【转载】Docker 配置 Mastodon Sidekiq 多线程

今早在群里收到报错,nofan 的 timeline 延迟近半小时不动,跑 Sidekiq 看了一下,队列里超过 4000 条待处理任务,简单看了一下日志,大部分是 bgme.me 的未响应报错。当笔记本自己记录。

Sidekiq 的机制是这样,如果队列中的任务发生错误,会隔一段时间重新处理一次,由于 bgme 站点挂掉太久,导致投递至 bgme 的消息持续报错,然后不断重复投递导致待处理任务越积越多。

针对这个问题,首先在管理员面板手动停止向 bgme 进行投递,并且强行结束错误任务,防止再次进入任务队列。

操作完之后,任务数量没有非常明显的下降,一方面是队列中已经积累了大量待处理任务,另一方面是 Mastodon 默认的 Sidekiq 线程数过小,同时处理的任务有限。

其实在 Mastodon v3.5+ 处理过类似的问题,上次的解决方案在升级到 4.0+ 时,不知道什么原因导致 Sidekiq 无法正常工作,于是将 Docker compose 配置改成了 Mastodon 默认配置。

这次重新找了下解决方案,发现秘站站长这篇博文让 sidekiq 更快处理 mastodon 任务非常有帮助,通过 Chat GPT 将文中针对服务器部署的方案改成 Docker compose 可用的方案,然后做如下修改:

  1. 在 .env.production 环境变量中设置 DB_POOL=40
  2. 在 Docker compose 做如下配置
  sidekiq:
    build: .
    image: twoheart/mastodon:edge
    restart: always
    env_file: .env.production
    command: bundle exec sidekiq -c 20
    depends_on:
      - db
      - redis
    networks:
      - external_network
      - internal_network
    volumes:
      - ./public/system:/mastodon/public/system
    healthcheck:
      test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]

  sidekiq2:
    build: .
    image: twoheart/mastodon:edge
    restart: always
    env_file: .env.production
    command: bundle exec sidekiq -c 20 -q default -q pull -q ingress
    depends_on:
      - db
      - redis
    networks:
      - external_network
      - internal_network
    volumes:
      - ./public/system:/mastodon/public/system
    healthcheck:
      test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]

其中 -c 参数代表所使用的线程数,需要保证总线程数 <= 数据库最大连接数。-q 参数代表指定处理的队列名称。。

以上配置将保证同时有两个 Sidekiq 进程,分别使用 20 个线程。同时,Sidekiq2 进程还指定了处理三个队列:default、pull、ingress。

搞完以上操作,使用 docker-compose down 和 docker-compose up -d 重启服务,检查 Sidekiq 面板。

搞定。

总结

  1. 其实早在刚刚升级 4.0 版本时就可以修复调优这件事,觉得没问题就没动,太懒了,差评
  2. 应该早点把解决方案总结成文章,下次遇到就能少花很多时间找解决方案
  3. Chat GPT 虽然持续降智,但在解决非开放性的技术问题时还是蛮有用的

作者:nofan

链接:https://blog.nofan.xyz/posts/20231207/

许可:CC BY-NC-SA 4.0

参考链接