You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 08:50:32