2009-12-05 59 views
0

我有几个服务器和其他守护进程需要以正确的顺序启动。如何在Ubuntu下对init.d脚本进行排序

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

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

现在,安装程序的工作原理是让serverB重新尝试连接,直到成功为止,但该方法似乎很脆弱。我希望更强烈地了解如何强制排序。

回答

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'语句的非常脆弱的方法来说,这是一个很大的改进。

2

我不认为它是脆弱的 - 至少我可以想象它不会脆弱的场景。重试时间为5秒,并且一点都不差。它是一种KISS方法,并且没有任何你不明白的角落案例。

获得一个分布式环境同步并不是因为心脏不好,在你的例子中它的矫枉过正。

为了让你对自己的方法有一定的信心,我可以告诉你,我已经有数十个手工编写的复杂服务器进程分布在Web场中,即使数据库服务器已经消失,他们也从来没有给我任何伤心,网络中继线已经断开等等,他们只是继续运行在降级模式下,直到数据库回来。

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风格的初始化。 Ubuntu实际上使用Upstart,这是一个基于事件的系统,而不是一系列脚本。你可以选择使用暴发户作业而不是System-V初始化脚本,并从你的服务器发起一个自定义的Upstart事件,这会触发第二台服务器的启动。

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

+0

我相信套接字'文件'总是存在,所以它的存在不是一个好的指标。延迟守护进程方法很有前途。我现在使用shell'&'方法(快速简单),但是在内部进行守护进程非常实用。 – Rdbhost 2009-12-05 19:20:15

+0

您可以在启动服务器之前删除套接字,因此它将不得不重新创建它。 (我也忘了,循环可能也需要短暂的睡眠。) – 2009-12-05 19:56:20

+0

您可能需要在该轮询循环中进行睡眠。 – mc0e 2015-02-17 13:09:08