Sidekiq服务平滑重载与代码更新相关技术问询
Sidekiq服务平滑重载与代码更新相关技术问询
我目前为Sidekiq低优先级服务使用了以下Linux systemd单元文件:
[Unit] Description=sidekiq low After=syslog.target network.target [Service] Type=simple WorkingDirectory=/var/www/backend/current Environment="RAILS_ENV=production" ExecStart=/home/deploy/.rvm/gems/ruby-2.6.9/wrappers/bundle exec sidekiq -C /var/www/backend/shared/config/sidekiq_low.yml ExecReload=/bin/kill -USR1 $MAINPID ExecStop=/bin/kill -USR1 $MAINPID KillMode=mixed TimeoutStopSec=86400 User=deploy Group=deploy UMask=0002 Environment=MALLOC_ARENA_MAX=2 # if we crash, restart RestartSec=1 Restart=always SyslogIdentifier=sidekiq_low [Install] WantedBy=multi-user.target
这个配置运行得还不错,但我们的代码更新很频繁,每次发版都需要重启Sidekiq服务,让新进程加载更新后的代码。不过有些Worker的任务要跑好几个小时才能完成,所以我特意在配置里用了USR1信号来处理重载和停止操作。我想确认这样的配置是否合理,有没有可以优化的地方?
作为长期使用Sidekiq和systemd部署服务的开发者,我来分享下我的经验:
首先,你用USR1信号来实现平滑重启的思路完全正确!Sidekiq对USR1信号的处理逻辑就是启动新进程接管新任务,旧进程继续处理当前正在运行的任务,直到所有任务完成后自动退出,完美适配你这种有长耗时任务的场景,不会因为发版中断正在执行的业务。
给你几个补充建议,让这套配置更完善:
- 区分Reload和Stop的行为:你现在把ExecReload和ExecStop都设成了USR1,虽然Stop时也会让旧进程完成任务,但执行
systemctl stop sidekiq_low后,systemd不会自动启动新进程。建议发版时优先用systemctl reload sidekiq_low,这个操作会触发新进程启动,自动衔接新代码;只有在需要彻底停止服务时再用stop。 - 验证日志确认流程:你已经配置了
SyslogIdentifier=sidekiq_low,可以通过查看系统日志(比如journalctl -u sidekiq_low)来确认重载时的进程切换是否正常,正常情况下会看到类似“Starting new Sidekiq process”“Old process exiting after finishing current jobs”的日志信息,确保长任务确实在被正确处理。 - 确认Sidekiq版本兼容性:USR1信号的平滑重启特性是从Sidekiq 3.0版本开始支持的,你用的Ruby 2.6.9搭配的Sidekiq版本应该是符合要求的,但如果遇到异常可以先核对版本。
- 自动化部署集成:既然你们发版频繁,可以把
systemctl reload sidekiq_low集成到部署脚本里,比如用Capistrano的话,在deploy的after hooks里加上这个命令,发版完成后自动触发平滑重载,省得手动操作。
另外你设置的TimeoutStopSec=86400(24小时)非常合理,给足了长任务的执行时间,不用担心systemd强制杀掉还在处理任务的旧进程。
备注:内容来源于stack exchange,提问作者simo
相关产品推荐
相关产品推荐

