今天有小伙伴又在问 puma 在部署时候的重启方式,怎样做到 0 downtime,我这刚好整理了一篇笔记 分享给大家
puma/restart.md at master · puma/puma puma 关于 systemd 的 0down 方案
就是完全正常的重启
完全的生命周期,跟 stop 之后 start 一样,所有的东西都会重新加载
服务中断,会有 503 Service Unavailable 的情况
通过额外的 Server socket,确保 puma 在重启的过程中,可以持续的接受请求,并等待处理,puma 重启成功之后,将 socket 堆积的请求再发送出去
不会终止服务,请求连接也会得到保留。cluster 模式 和 simple 模式均可以使用,个人认为比较简单
使用 preload_app!可以加快启动速度
啥是 preload_app! 在 cluster 模式下 preload_app! 实现 将 master 进程的所有代码 在 fork 之前都 load 起来,这样就可以使用操作系统的 copy-on-write 技术,有效的降低内存使用。
在重启期间,进来的连接处于挂起状态 hanging, 如果时间过长,则上层如 nginx 会来个 502
满足任意条件即可启动
向 puma status/control server 请求 /restart
什么是 puma status/control server? 在 puma 启动的时候 可以带入参数来启动一个控制 url 类似 puma --control-url tcp://127.0.0.1:9293 --control-token foo
pumactl restart
Phased restart 名为 阶段重启,这种重启方式只适合跑在 cluster 模式下。工作机制是 : 先杀死一个老版本的 worker,再启动一个新的 worker,以此重复,直至所有的 worker 都是新版本,这种方式 master process 即 puma 的控制进程本身,是不会重启的,重启的只有 worker 进程。这种方式不适合配置有更新,以及添加新 Gem 的情况
在 puma 重启过程中,系统也是可以真正的处理请求,即 既接受了新的请求进来,请求进来后也会有 worker 来处理并返回结果(但是 是新是旧 worker 是随机的)
puma.rb 配置文件,是禁止使用 preload_app! 而需要使用 prune_bundler 的
为啥不能用 preload_app! ?因为主进程不重启,只是单启 worker
prune_bundler 代替了 preload, 来进行 gem 的装载