我有一个安装和设置的脚本流量服务器:
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
此后您应该能够运行脚本的第二部分。