首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使ExecStartPost命令在后台运行

使ExecStartPost命令在后台运行
EN

Stack Overflow用户
提问于 2016-11-25 07:05:34
回答 2查看 3.5K关注 0票数 0

我为我的春季引导应用程序提供了一个systemd服务,连接到consul服务器的haproxy后面。consul提供consul-template,通过consul-template命令自动更新haproxy配置文件中的服务位置。

consul-template接受一个模板文件并写入最终的haproxy配置文件,然后重新加载haproxy

现在,consul-template进程需要始终与我的应用程序一起在后台运行,以便当应用程序出现时,它可以检测新的应用程序启动并更新其在配置文件中的位置。

这是我的systemd服务文件。

代码语言:javascript
复制
[Unit]
Description=myservice
Requires=network-online.target
After=network-online.target

[Service]
Type=forking
PIDFile=/home/dragon/myservice/run/myservice.pid
ExecStart=/home/dragon/myservice/bin/myservice-script start
ExecReload=/home/dragon/myservice/bin/myservice-script reload
ExecStop=/home/dragon/myservice/bin/myservice-script stop
ExecStartPost=consul-template -template '/etc/haproxy/haproxy.cfg.template:/etc/haproxy/haproxy.cfg:sudo systemctl reload haproxy'
User=dragon

[Install]
WantedBy=multi-user.target

现在,当我启动systemctl start myservice时,我的应用程序就会启动,对consul-template的调用也会正常工作,但是consul-template进程不会出现在后台。我必须按Ctl+C,然后systemctl返回,我的应用程序和领事模板进程都在运行。

consul-template ExecStartPost**?**中指定的背景中运行进程的方法是。

我试图在&命令的末尾添加ExecStartPost,但是consul-template抱怨说它是一个附加的无效参数,但失败了。

我还试图将命令设置为/bin/sh -c "consul-template command here...",但这也不起作用。即使是这个命令中的nohup也不能工作。

任何帮助都是非常感谢的。

EN

回答 2

Stack Overflow用户

发布于 2016-12-10 20:13:26

解决方法是将bash文件作为您的入口点,在其中添加所需的所有内容,然后所有这些都将神奇地工作起来。

票数 2
EN

Stack Overflow用户

发布于 2022-07-07 18:41:37

我正试图完成同样的任务。我想在服务启动后向Tomcat发送一些HTTP请求,以便在第一个用户请求之前对服务器进行热身。

在尝试使用ExecStartPost触发异步进程时,我经历了很多尝试和错误,但实际上起了作用。通过调用shell脚本,我可以触发后台进程,但是从我的测试系统看来,当ExecStartPost完成时,进程线程就会被杀死,所以任何子进程也会被杀死。我尝试了各种组合,使用&setsidnohup等,甚至一些Perl试图在它自己的线程中触发可执行文件,但一旦shell脚本从ExecStartPost中退出,任何运行的进程都会被杀死。有可能有一些使用ExecStartPost的解决方案,但我找不到。

然而,所做的工作是创建一个新服务(比如@divinedragon所提到的),它支持我想要监视的服务(在本例中是Tomcat)。

因为我花了一些研究才得到了我想要的工作方式,所以我想分享我的解决方案,以防它帮助到别人。

第一步是创建一个新服务(例如/usr/lib/systemd/system/tomcat-service-listener.service):

代码语言:javascript
复制
[Unit]
Description=Tomcat start/stop event listener
# make sure to stop the service when Tomcat stops
BindsTo=tomcat.service
# waits for both Nginx & Tomcat to be started before this service is started
After=nginx.service tomcat.service

[Service]
Type=oneshot
ExecStart=/path/to/your/script.sh start
ExecStop=/path/to/your/script.sh stop
RemainAfterExit=yes
TimeoutStartSec=300

[Install]
# When the service is enabled, forces this service to start when Tomcat is started
WantedBy=tomcat.service

关于这里正在发生的事情的一些注释:

  • BindsTo确保在Tomcat停止时停止服务。这将触发ExecStop命令。
  • After确保在服务器重新启动时,该服务在Nginx和Tomcat启动之前不会启动。
  • WantedBy将为Tomcat创建wants符号链接(当服务启用时),这将迫使Tomcat在其重新启动时启动该服务。
  • RemainAfterExit=yesExecStop工作所必需的。如果您只关心在服务启动时触发什么,而不关心服务何时停止,则可以将其设置为no并删除ExecStop行。
  • 使TimeoutStartSec足够长,以满足您计划运行的任何任务。

要使此服务正常工作,您需要执行以下操作:

代码语言:javascript
复制
# make the service executable
chmod 664 /usr/lib/systemd/system/tomcat-service-listener.service
# make Systemd aware of the new service
systemctl daemon-reload
# register the service so it's started/stopped with Tomcat
systemctl enable tomcat-service-listener.service

现在,您需要脚本触发所需的逻辑。在我的例子中,我想在Tomcat启动后对一些服务器进行热身,这样我的/path/to/your/script.sh看起来就像:

代码语言:javascript
复制
#!/bin/sh

SCRIPT_MODE="$1"
LOGFILE=/var/logs/myscript.log

log_message() {
    local MESSAGE="$1"

    echo "$(date '+%Y-%m-%d %H:%M:%S')  $MESSAGE" >> "$LOGFILE"

    return 0
}

warmup_server() {
    local SERVER_ADDRESS="$1"
    local SERVER_DESCRIPTION="$2"

    log_message "Warming up $SERVER_DESCRIPTION..."
    # we want to track the time it took to warm up the server
    local START_TIME=$(date +%s)
    # server restarts can take a while for all services to start, so we must retry long enough for all relevant services to start
    HTTP_STATUS=$(curl --insecure --location --silent --show-error --fail --retry 60 --retry-delay 2 --retry-max-time 240 --output /dev/null --write-out "%{http_code}" '$SERVER_ADDRESS')
    # we want to track the time it took to warm up the server
    local TOTAL_STARTUP_TIME=$(($(date +%s)-$START_TIME))
    log_message "$SERVER_DESCRIPTION started in $TOTAL_STARTUP_TIME seconds... (Status: $HTTP_STATUS)"

    return 0
}


# monitor when Tomcat has stopped
if [ "$SCRIPT_MODE" == "stop" ]; then
    log_message "Tomcat listener shutting down..."
    exit 0
elif [ "$SCRIPT_MODE" == "start" ]; then
    log_message "Tomcat listener started..."
fi

# servers to warm up
warmup_server 'https://127.0.0.1' 'Localhost #1'
warmup_server 'https://127.0.0.2' 'Localhost #2'

这似乎完全符合我的要求。服务在服务器重新启动时启动,启动/停止/重新启动Tomcat将触发预期的事件。由于它独立于Tomcat服务,如果需要的话,我可以重新启动这个预热脚本。它也不会延迟Tomcat的启动时间,因为它是自己的服务,因此按我的要求异步运行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40799429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档