Chef infra 厨师长:我确保有服务正在网络上监听

Chef infra 厨师长:我确保有服务正在网络上监听,chef-infra,Chef Infra,我使用来安装mongodb实例 我正在尝试在服务启动时执行脚本: execute "Add Mongo Users" do command "mongo #{host}:#{port} /tmp/mongo.setup.users.js" subscribes :run, 'service[mongod]', :delayed end 我得到了这个错误: ==> Expected process to exit with [0], but received '1' ==>

我使用来安装mongodb实例

我正在尝试在服务启动时执行脚本:

execute "Add Mongo Users" do
  command "mongo #{host}:#{port} /tmp/mongo.setup.users.js"
  subscribes :run, 'service[mongod]', :delayed
end
我得到了这个错误:

==> Expected process to exit with [0], but received '1'
==> ---- Begin output of mongo localhost:30158 /tmp/mongo.setup.users.js ----
==> STDOUT: MongoDB shell version v3.4.2
==> connecting to: localhost:30158
==> 2017-06-05T07:39:48.136+0000 W NETWORK  [thread1] Failed to connect to 127.0.0.1:30158, in(checking soc
ket for error after poll), reason: Connection refused
==> 2017-06-05T07:39:48.136+0000 E QUERY    [thread1] Error: couldn't connect to server localhost:30158, co
nnection attempt failed :
所以,正如您所看到的,当执行命令时,服务还没有运行(我得到一个网络错误)

我已经查看了cookbook存储库代码。根据,服务已启动


有什么想法吗?

因为触发服务启动并不意味着它马上就可以接受连接,所以您需要等待一段时间

  • 一种常见的方法是添加额外的硬编码延迟,例如

    命令“sleep 3;mongo..”
    
    缺点:在机器A上3秒钟可能就足够了,但在机器B上就不够了(所以把20秒放进去,你已经解决了99.9%的问题,但并没有成为一个更好的程序员;-)

  • 一个更好的方法可以在以下方面看到:

    def等待,直到准备就绪!
    Timeout.Timeout(超时,超时)do
    开始
    打开(端点)
    救援袜匠,
    Errno::ECONNREFUSED,
    Errno::Econreset,
    Errno::ENETUNREACH,
    超时::错误,
    OpenURI::HTTPError=>e
    #如果已启用身份验证,服务器将返回HTTP
    # 403. 这是“OK”,因为这意味着服务器实际上是
    #准备接受请求。
    如果e.message=~/^403,则返回/
    Chef::Log.debug(“Jenkins不接受请求-#{e.message}”)
    睡眠(0.5)
    重试
    结束
    结束
    营救詹金斯超时
    新建(端点,超时)
    结束
    
    这段代码反复尝试连接到Jenkins,直到它工作或达到超时。您应该能够将其适应mongo(您可以调用该命令并检查它是否成功,或者像Jenkins代码那样直接连接到TCP端口)

  • 介于两者之间的一种方法是使用Chef的
    retry
    参数:

    执行“添加Mongo用户”操作
    命令“mongo{host}:{port}/tmp/mongo.setup.users.js”
    重试10次
    订阅:运行“服务[mongod]”,延迟
    结束
    
    我不完全确定它是否能工作,因为
    mongo
    命令可能会很快返回故障,几乎没有时间启动服务(因此结合全能的
    sleep
    ?)。此外,根据您执行的命令,确保不会造成负面副作用(当它可以连接到该服务,但在以后的步骤中失败时——结果是它再次运行。想想这里的数据损坏和朋友)


可能是命令有点太快。触发服务启动并不意味着它已准备好接受连接。请注意主题中的拼写。可能会更新
命令
参数的值,并预先设置
ss-ntl;
以首先输出侦听端口列表(检查我是否正确).你说得对。执行命令时,服务并没有监听网络。有什么想法吗?