第一次尝试

第一次尝试

我有一个安装和设置的脚本流量服务器

yum install -y trafficserver
systemctl start trafficserver

traffic_line -s proxy.config.url_remap.remap_required -v 0
traffic_line -s proxy.config.reverse_proxy.enabled -v 0

问题是,traffic_line失败:

[connect] 错误(main_socket_fd 3):没有这样的文件或目录错误:无法连接到管理端口,请确保traffic_manager 正在运行

这是因为systemctl start它立即返回,而无需等待流量服务器实际启动。

有没有办法告诉systemctl start仅在服务启动后返回?

如果这不可能,是否有一个命令可以让我运行systemctl start以真正等待服务启动?

答案1

这是因为systemctl start它立即返回,而无需等待流量服务器实际启动。

有没有办法告诉systemctl start仅在服务启动后返回?

systemctl start 等待服务准备就绪(除非使用 调用--no-block),服务只需正确指示这一点(即不使用Type=simple)。如果服务未在准备就绪时告知 systemd,则 、 等变体均systemctl is-active无济于事systemctl show

正如评论中提到的,最优雅的解决方案是套接字单元。systemd 启动套接字、traffic_line连接到它,systemd 启动服务并traffic_line阻塞,直到服务开始接受从 systemd 继承的文件描述符上的连接。

或者,您可以使用Type=forking(服务分叉,并且分叉的服务准备就绪后主 PID 退出)或Type=notify(服务sd_notify(0, "READY=1")准备就绪后调用)。

不幸的是,所有这些解决方案都需要一些支持trafficserver——使用 systemd 的套接字而不是分配自己的套接字,在主进程中适当地 fork 和等待,或者调用sd_notify。如果服务器不配合,systemd 就无法神奇地猜出服务器何时准备就绪:)


在查看了trafficserver的源代码之后,看起来它可能确实支持Type=forking- 服务器由专用命令生成traffic_cop,该命令似乎等到服务器启动并执行一些基本测试(至少代码看起来像这样)。因此,如果您更改服务类型,它可能会正常工作:

# /etc/systemd/system/trafficserver.service.d/type-forking.conf
[Service]
Type=forking

答案2

经过多次尝试,我终于让它工作了。

第一次尝试

在深入研究 systemctl help 之后,我发现了该is-active命令:

$ systemctl is-active trafficserver
active

因此我编写了一个 shell 脚本来等待该服务变为活动状态:

while true; do
    if [ $(systemctl is-active trafficserver) == "active" ]; then
        break
    fi

    sleep 1
done

不幸的是,尽管当我使用 start/stop 测试时该脚本按预期工作,我仍然遇到同样的错误在其后立即运行traffic_line命令时。我认为在实际进程完全启动之前(可能仅需几毫秒),服务就被报告为处于活动状态。

第二次尝试

所以我尝试了另一种方法。知道这是服务的第一次启动,我可以等到 TrafficServer Manager 的 PID 文件存在。以下是我尝试的方法:

while [ ! -f /run/trafficserver/manager.lock ]; do
  sleep 1
done

同样的问题:当流量服务器管理器的 PID 文件写入时,管理器实际上尚未准备好接收订单,因此我仍然收到错误

该死,我不想使用盲人sleep

第三次尝试

因此我最终检查了traffic_line命令本身是否失败:

while ! traffic_line --status &> /dev/null; do
    sleep 1
done

这有效!

不错,但是...

不幸的是,答案针对我正在使用的服务(trafficserver),并不直接适用于其他服务。

如果您知道这个问题的更通用的答案,请随时分享。

答案3

我不擅长编写 shell 脚本,但我认为你应该测试一下这两个,活动状态子状态财产如果返回积极的跑步分别。

$ systemctl show trafficserver -p SubState,ActiveState
ActiveState=active
SubState=running

此后您应该能够运行脚本的第二部分。

答案4

最简单的方法是向脚本添加睡眠功能:

sleep 30

或者你可以做一些工作控制这里

相关内容