Sidekiq перестает работать через некоторое время

Всем привет,

У меня есть установка с тремя развертываниями OpenShift: одно для Redis (7.0.10), одно для PostgreSQL (13.10) и ещё одно для Discourse (stable 3.0.3). Всё работает нормально сразу после развёртывания, однако через несколько часов или дней процессы Sidekiq (UNICORN_SIDEKIQS=3) останавливаются. Я заметил следующее: в директории /shared/log/rails не создаётся файл sidekiq.log. Я считаю, что именно это является причиной, по которой Sidekiq не перезапускается автоматически:

root@discourse-b9f766dcf-52zjq:/var/www/discourse# ls -laF /shared/log/rails/
total 32
drwxr-xr-x. 2 nobody www-data  4096 Jun  9 08:57 ./
drwxr-xr-x. 3 root   root      4096 May 30 06:16 ../
-rw-r--r--. 1 nobody www-data 16082 Jun  9 09:28 production.log
-rw-r--r--. 1 nobody www-data  1345 Jun  9 09:02 unicorn.stderr.log
-rw-r--r--. 1 nobody www-data   204 Jun  9 09:02 unicorn.stdout.log

Когда sidekiq останавливается, в логах хоста (host/logs) я вижу следующее сообщение:

Info:
Sidekiq is consuming too much memory (using: 530.35M) for 'discourse.internal.odencluster.com', restarting

backtrace:
config/unicorn.conf.rb:163:in `check_sidekiq_heartbeat'
config/unicorn.conf.rb:243:in `master_sleep'
unicorn-6.1.0/lib/unicorn/http_server.rb:295:in `join'
unicorn-6.1.0/bin/unicorn:128:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/3.2.0/bin/unicorn:25:in `load'
/var/www/discourse/vendor/bundle/ruby/3.2.0/bin/unicorn:25:in `<main>'

Затем в логах пода Discourse я вижу сообщение:

(48) Reopening logs
(48) Reopening logs
(48) Reopening logs

Однако, поскольку в /shared/log/rails/ отсутствует файл sidekiq.log, перезапуск не происходит.

Мои знания о Rails близки к нулю, поэтому мне трудно проводить диагностику, но я вижу, что Sidekiq не приостановлен:

[1] pry(main)> Sidekiq.paused?
=> false

А при ручном запуске он работает:

2023-06-09T09:47:15.556Z pid=195386 tid=449q INFO: Booting Sidekiq 6.5.8 with Sidekiq::RedisConnection::RedisAdapter options {:host=>"redis", :port=>6379, :namespace=>"sidekiq"}
2023-06-09T09:47:20.528Z pid=195386 tid=449q INFO: Booted Rails 7.0.4.3 application in production environment
2023-06-09T09:47:20.528Z pid=195386 tid=449q INFO: Running in ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
2023-06-09T09:47:20.528Z pid=195386 tid=449q INFO: See LICENSE and the LGPL-3.0 for licensing details.
2023-06-09T09:47:20.528Z pid=195386 tid=449q INFO: Upgrade to Sidekiq Pro for more features and support: https://sidekiq.org

Есть несколько вещей, которые, как я полагаю, помогут мне решить эту проблему:

  1. Как заставить систему создавать файл /shared/log/rails/sidekiq.log?
  2. Как разрешить Sidekiq использовать более 530 МБ памяти?

Если у кого-то есть предложения, пожалуйста, дайте знать. Заранее благодарю за уделённое время и поддержку!

Хорошего дня! :slight_smile:

Привет, Денис,

Я сосредоточусь на предоставлении информации о том, как увеличить использование RSS для Sidekiq.

Для этого обратите внимание на переменную окружения UNICORN_SIDEKIQ_MAX_RSS (источник: discourse/config/unicorn.conf.rb at 89d7b1861d1625352e82e82c19f93e7272c965ef · discourse/discourse · GitHub) (например, UNICORN_SIDEKIQ_MAX_RSS: 1000), что позволит вам выделить больше памяти. В любом случае, я рекомендую немного уменьшить значение UNICORN_SIDEKIQS до 1 или 2, если только у вас не накопилось множество задач в очереди на длительное время.

Я не знаю, в чём может быть причина перезапусков вашего Sidekiq, обычно он перезапускается в фоновом режиме после OOM (согласно discourse/config/unicorn.conf.rb at 89d7b1861d1625352e82e82c19f93e7272c965ef · discourse/discourse · GitHub), но проверьте your-forum.com/logs для получения дополнительной информации. Надеюсь, это поможет.

С наилучшими пожеланиями,
Исмаэль

Привет, @trobiyo, огромное спасибо за быструю и понятную поддержку!

Да, мой Sidekiq перезапускается из-за нехватки памяти (OOM), но я последовал вашему совету: уменьшил значение UNICORN_SIDEKIQS=1 и выделил больше памяти для RSS, установив переменную окружения UNICORN_SIDEKIQ_MAX_RSS.

Надеюсь, это поможет и предотвратит перезапуски Sidekiq.

У вас есть какие-то идеи, почему Sidekiq не пишет логи в файл /shared/log/rails/sidekiq.log?

Ещё раз спасибо и отличного дня! :slight_smile:

С уважением,
Денис

Привет,

Если я не ошибаюсь, вам нужно установить переменную окружения DISCOURSE_LOG_SIDEKIQ в значение 1, как указано в discourse/app/jobs/base.rb at 7c768a2ff99f45ab5008c16cf6982652d576a0e2 · discourse/discourse · GitHub. В противном случае функция write_to_log завершится без вывода лога (см. discourse/app/jobs/base.rb at 7c768a2ff99f45ab5008c16cf6982652d576a0e2 · discourse/discourse · GitHub).

Надеюсь, это поможет.

Привет,

Да, DISCOURSE_LOG_SIDEKIQ=1 помогло, и я вижу файл /shared/log/rails/sidekiq.log. Это отлично!

Я также заметил, что Sidekiq работает уже какое-то время и не перезапускался из-за нехватки памяти (OOM) с тех пор, как я увеличил лимит памяти и сократил количество процессов до одного.

Похоже, это решение моей проблемы с Sidekiq. Я продолжу следить за ситуацией и обновлю информацию здесь, если возникнут какие-либо проблемы, связанные с Sidekiq.

Тем временем, я очень благодарен за вашу помощь, @trobiyo! У вас прекрасная поддержка!

Удачного дня!

:slight_smile:

Это отличная новость :clap:, рад, что это помогло решить проблему!

С уважением,
Исмаил

Снова здравствуйте, @trobiyo,

К сожалению, Sidekiq по-прежнему останавливается, похоже, что внесённые изменения были недостаточными. =/

В логах я вижу следующую ошибку:

info:
Job exception: FinalDestination: all resolved IPs were disallowed

backtrace:
/var/www/discourse/lib/final_destination/ssrf_detector.rb:104:in `lookup_and_filter_ips'
/var/www/discourse/lib/final_destination/http.rb:13:in `connect'
/usr/local/lib/ruby/3.2.0/net/http.rb:1248:in `do_start'
/usr/local/lib/ruby/3.2.0/net/http.rb:1237:in `start'
/usr/local/lib/ruby/3.2.0/net/http.rb:687:in `start'
/var/www/discourse/lib/final_destination.rb:511:in `safe_session'
/var/www/discourse/lib/final_destination.rb:450:in `safe_get'
/var/www/discourse/lib/final_destination.rb:161:in `get'
/var/www/discourse/lib/retrieve_title.rb:81:in `fetch_title'
/var/www/discourse/lib/retrieve_title.rb:7:in `crawl'
/var/www/discourse/lib/inline_oneboxer.rb:76:in `lookup'
/var/www/discourse/lib/cooked_processor_mixin.rb:310:in `process_inline_onebox'
/var/www/discourse/lib/cooked_processor_mixin.rb:39:in `block in post_process_oneboxes'
/var/www/discourse/lib/oneboxer.rb:213:in `block in apply'
/var/www/discourse/lib/oneboxer.rb:161:in `block in each_onebox_link'
nokogiri-1.14.2-x86_64-linux/lib/nokogiri/xml/node_set.rb:235:in `block in each'
nokogiri-1.14.2-x86_64-linux/lib/nokogiri/xml/node_set.rb:234:in `upto'
nokogiri-1.14.2-x86_64-linux/lib/nokogiri/xml/node_set.rb:234:in `each'
/var/www/discourse/lib/oneboxer.rb:161:in `each_onebox_link'
/var/www/discourse/lib/oneboxer.rb:212:in `apply'
/var/www/discourse/lib/cooked_processor_mixin.rb:9:in `post_process_oneboxes'
/var/www/discourse/lib/cooked_post_processor.rb:41:in `block in post_process'
/var/www/discourse/lib/distributed_mutex.rb:53:in `block in synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:34:in `synchronize'
/var/www/discourse/lib/cooked_post_processor.rb:38:in `post_process'
/var/www/discourse/app/jobs/regular/process_post.rb:28:in `block in execute'
/var/www/discourse/lib/distributed_mutex.rb:53:in `block in synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:34:in `synchronize'
/var/www/discourse/app/jobs/regular/process_post.rb:8:in `execute'
/var/www/discourse/app/jobs/base.rb:249:in `block (2 levels) in perform'
rails_multisite-4.0.1/lib/rails_multisite/connection_management.rb:80:in `with_connection'
/var/www/discourse/app/jobs/base.rb:236:in `block in perform'
/var/www/discourse/app/jobs/base.rb:232:in `each'
/var/www/discourse/app/jobs/base.rb:232:in `perform'
sidekiq-6.5.8/lib/sidekiq/processor.rb:202:in `execute_job'
sidekiq-6.5.8/lib/sidekiq/processor.rb:170:in `block (2 levels) in process'
sidekiq-6.5.8/lib/sidekiq/middleware/chain.rb:177:in `block in invoke'
/var/www/discourse/lib/sidekiq/pausable.rb:134:in `call'
sidekiq-6.5.8/lib/sidekiq/middleware/chain.rb:179:in `block in invoke'
sidekiq-6.5.8/lib/sidekiq/middleware/chain.rb:182:in `invoke'
sidekiq-6.5.8/lib/sidekiq/processor.rb:169:in `block in process'
sidekiq-6.5.8/lib/sidekiq/processor.rb:136:in `block (6 levels) in dispatch'
sidekiq-6.5.8/lib/sidekiq/job_retry.rb:113:in `local'
sidekiq-6.5.8/lib/sidekiq/processor.rb:135:in `block (5 levels) in dispatch'
sidekiq-6.5.8/lib/sidekiq.rb:44:in `block in <module:Sidekiq>'
sidekiq-6.5.8/lib/sidekiq/processor.rb:131:in `block (4 levels) in dispatch'
sidekiq-6.5.8/lib/sidekiq/processor.rb:263:in `stats'
sidekiq-6.5.8/lib/sidekiq/processor.rb:126:in `block (3 levels) in dispatch'
sidekiq-6.5.8/lib/sidekiq/job_logger.rb:13:in `call'
sidekiq-6.5.8/lib/sidekiq/processor.rb:125:in `block (2 levels) in dispatch'
sidekiq-6.5.8/lib/sidekiq/job_retry.rb:80:in `global'
sidekiq-6.5.8/lib/sidekiq/processor.rb:124:in `block in dispatch'
sidekiq-6.5.8/lib/sidekiq/job_logger.rb:39:in `prepare'
sidekiq-6.5.8/lib/sidekiq/processor.rb:123:in `dispatch'
sidekiq-6.5.8/lib/sidekiq/processor.rb:168:in `process'
sidekiq-6.5.8/lib/sidekiq/processor.rb:78:in `process_one'
sidekiq-6.5.8/lib/sidekiq/processor.rb:68:in `run'
sidekiq-6.5.8/lib/sidekiq/component.rb:8:in `watchdog'
sidekiq-6.5.8/lib/sidekiq/component.rb:17:in `block in safe_thread'

Есть ли у вас какие-либо идеи, что может быть не так, исходя из этого?

Ещё раз спасибо за вашу поддержку.

:slight_smile:

Привет, Денис,

Похоже, это проблема с сокетами/DNS, вызывающая тайм-аут? У вас что-то настроено в параметре «Разрешенные внутренние хосты»?

Судя по трассировке стека, при поиске IP-адресов этот список оказывается пустым (см. discourse/lib/final_destination/ssrf_detector.rb на ветке main · discourse/discourse · GitHub), что срабатывает в discourse/lib/final_destination/http.rb на ветке tests-passed · discourse/discourse · GitHub. Поэтому я склонен полагать, что это может быть связано с вашей установкой (возможно, она не может достичь IP-адреса подов Sidekiq?)

Или проверьте, не используется ли в вашем кластере какой-либо NetworkPolicy — это может быть ещё одной причиной.

С уважением