当我第一次使用cap [env] deploy
部署我的应用程序时,一切都按预期工作。部署代码并使用puma:start
成功启动puma服务器。
彪马开始的capistrano输出
* 2015-01-09 12:19:37 executing `puma:start'
* executing "cd /path/to/app/current && bundle exec puma -q -d -e production -C ./config/puma/production.rb"
servers: ["example.com"]
[example.com] executing command
** [out :: example.com] Puma starting in single mode...
** [out :: example.com] * Version 2.9.2 (ruby 2.1.5-p273), codename: Team High Five
** [out :: example.com] * Min threads: 0, max threads: 16
** [out :: example.com] * Environment: production
** [out :: example.com] * Listening on unix:///path/to/app/shared/sockets/puma.sock
** [out :: example.com] * Daemonizing...
如果我进行代码更改并尝试重新部署,而不是调用puma:start
,则capistrano会调用puma:restart
,其行为就像成功一样,但是puma实际上并没有重新启动。
* 2015-01-09 12:27:56 executing `puma:restart'
* executing "cd /path/to/app/current && bundle exec pumactl -S /path/to/app/shared/sockets/puma.state restart"
servers: ["example.com"]
[example.com] executing command
** [out :: example.com] Command restart sent success
此时,如果我刷新网页,则会出现 504 Gateway Time-out 错误。它与this issue.非常相似。
正如此人建议的那样,如果我将workers 1
添加到我的puma配置文件中,重启将会起作用,但启动/停止不会。
在我目前的状态(没有工人),如果我做cap [env] puma:stop
,它不会停止美洲狮。它还 NOT 删除任何这些文件:
/path/to/app/shared/pids/puma.pid
/path/to/app/shared/sockets/puma.sock
/path/to/app/shared/sockets/puma.state
重要提示
在我的Rails服务器中,我使用的是ActionController::Live
和Rails 4.1。我使用Javascript / Redis连接到事件流。我在我的nginx错误日志中注意到了这一点:
nginx错误日志
2015/01/09 12:29:32 [error] 8992#0: *371 upstream timed out (110:
Connection timed out) while reading response header from upstream,
client: [ip], server: example.com, request: "GET /build_configurations/refresh_workers HTTP/1.1",
upstream: "http://unix:///path/to/app/shared/sockets/puma.sock/build_configurations
/refresh_workers", host: "example.com", referrer: "https://example.com/"
总而言之,如何在启动并重新启动时成功使用cap [env] deploy
部署代码更新?
更新
我发现this issue谈到重新启动与ActionController::Live
的美洲狮,但似乎没有解决方案。
答案 0 :(得分:1)
使用我在this other Stack Overflow answer中找到的信息,我能够实现一个可以解决这种情况的心跳。我自己并没有完全理解所有的机制,但我开始使用初始化程序来启动心跳:
<强>配置/初始化/ redis.rb 强>
REDIS = Redis.new(url: "redist://localhost:6379")
heartbeat_thread = Thread.new do
while true
REDIS.publish('heartbeat','thump')
sleep 2.seconds
end
end
at_exit do
# not sure this is needed, but just in case
heartbeat_thread.kill
REDIS.quit
end
我的控制器有:
def build_status_events
response.headers["Content-Type"] = "text/event-stream"
redis = Redis.new(url: "redist://localhost:6379")
# blocks the current thread
redis.psubscribe(['my_event', 'heartbeat']) do |on|
on.pmessage do |pattern, event, data|
response.stream.write("event: #{event}\n")
if event == 'heartbeat'
response.stream.write("data: heartbeat\n\n")
else
response.stream.write("data: #{data.to_json}\n\n")
end
end
end
rescue IOError
logger.info 'Events stream closed'
ensure
logger.info 'Stopping Events streaming thread'
redis.quit
response.stream.close
end
我相信会发生的是心跳被发布,如果出现错误,将调用ensure块并关闭订阅。然后puma按预期重新启动。如果有人有更好的解决方案或更多信息,请发表评论或添加其他答案。