如何在Ubuntu下对init.d脚本进行排序

时间:2009-12-05 16:40:14

标签: ubuntu init.d

我需要以正确的顺序启动一些服务器和其他守护进程。

我已经从骨架脚本创建了init.d脚本,并且可以使用编号的命名系统安装它们以正确的顺序启动,但仍然存在一些问题:

一个服务器('serverA')需要初始化数据库连接,然后侦听套接字。 然后,另一台服务器('serverB')需要连接到该套接字,如果先前的进程尚未侦听,则连接将失败。有没有办法阻止serverA的init.d脚本终止,直到serverA开始监听?在serverA init终止之前,serverB init不会启动。

现在,设置通过让serverB重试连接直到成功为止,但这种方法似乎很脆弱。我想对如何强制测序有一个更确定的理解。

3 个答案:

答案 0 :(得分:3)

是的,这是我正在回答的问题,但我发现这种技术很有用,并且正在为其他遇到类似问题的人分享。

我发现socat在等待套接字或端口时非常有用。一个init.d脚本,如:

case “$1″ in
  start)
  echo '--benign phrase' | socat - UNIX-CONNECT:/path/to/socket,retry=10,intervall=1
;;

将等待套接字变为可写,然后返回。没有涉及守护进程,因此它阻止执行更高编号的init.d脚本,直到它完成。

使用这样的服务器脚本会降低启动顺序,因此不是最佳的,但是与脚本中“sleep n”语句的非常脆弱的方法相比有了很大的改进。

答案 1 :(得分:2)

我不认为它是脆弱的 - 至少我能想到它不会脆弱的情景。重试时间为5秒,一点也不差。它是一种KISS方法,没有任何你不理解的角落案例。

让分布式环境同步并不适合胆小的人,并且在你的例子中有点过分。

为了让您对自己的方法充满信心,我可以告诉您,我已经在网络服务器上分发了数十个手写的复杂服务器进程,即使数据库服务器已经消失,或者网络也没有给我带来任何悲伤他们只是继续以降级模式运行,直到数据库恢复。

答案 2 :(得分:2)

如果服务器侦听域套接字,则可以构建一个轮询轮询的套接字。在bash中可能有一种更简单的方法,但它看起来像:

for i in 1 2 3 4 5; do
  if [ -e '/var/run/myserver.sock' ]; then
    break
  fi
done

另一个解决方案是让服务器不要守护进程,直到它打开侦听套接字。这样,init脚本将暂停,直到进程守护进程,这保证了套接字可用。

当然,这取决于你的应用程序本身是守护进程,而不是通过其他方式。 (“/ usr / bin / myserver&”等。)

更新:

另请注意,您现在正在做的是所有System-V样式的init。 Ubuntu实际上使用的是Upstart,它是一个基于事件的系统,而不是一系列脚本。您可以选择使用upstart作业而不是System-V init脚本,并从服务器触发自定义Upstart事件,这将触发第二台服务器的启动。

Getting Started guide在最底部有一个例子。我不知道是否有API方式,但它可能只是一个“系统(”/ bin / initctl emit myevent“);”在你的第一台服务器的正确时间点。其他具有更多Upstart经验的人可能能够更好地进一步阐述。