代码之家  ›  专栏  ›  技术社区  ›  Rdbhost

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

  •  0
  • Rdbhost  · 技术社区  · 16 年前

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

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

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

    现在,安装程序通过让serverb重试连接,直到成功,但这种方法似乎很脆弱。我希望对如何强制排序有更确定性的理解。

    3 回复  |  直到 16 年前
        1
  •  3
  •   sth    16 年前

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

    我发现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
  •  2
  •   Hassan Syed    16 年前

    我不认为它是脆弱的——至少我能想到它不会脆弱的场景。重试时间为5秒,一点也不差。这是一个吻的方法,没有任何角落的情况,你不明白。

    让一个分布式环境同步并不是为了让你的心脏不适,在你的例子中它的杀伤力太大了。

    为了让您对自己的方法有信心,我可以告诉您,我有几十个手工编写的复杂服务器进程分布在一个Web场上,它们从来没有给我任何悲伤,即使当数据库服务器消失,或当网络中继断开等。它们只是一直以降级模式运行,直到数据库恢复。

        3
  •  2
  •   Stéphan Kochen    16 年前

    如果服务器监听一个域套接字,您可以构建一个循环来轮询该套接字。在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”);_在第一台服务器中的正确时间点。其他有着更多新贵经验的人可能能够更好/更深入地阐述。

    推荐文章