Rails - Как я могу предотвратить Sidekiq от замедления сервера? - PullRequest
1 голос
/ 20 марта 2020

У меня есть информационный бюллетень, который я рассылаю своим клиентам (~ 10 тыс. Электронных писем) каждое утро, и иногда случается, что это задание Sidekiq требует некоторой производительности ЦП / памяти, что веб-сайт (приложение Rails) не работает и сталкивается с отключениями.

Когда я смотрю на панель управления Sidekiq, я вижу, что есть какая-то проблема (возможно, неверный адрес электронной почты и Sidekiq неоднократно пытается отправить его снова?) С информационным бюллетенем, и он застрял.

Как сделать Я предотвращаю такое поведение и не позволяю повторять задачу Sidekiq (которая, как мне кажется, является проблемой прорыва)?

Вот мой код:

задача рейка:

namespace :mailer do  desc "Carrier blast - morning"
  task :newsletter_morning => [:environment] do                                            
    NewslettertJob.perform_later
  end
end

определение задания:

class NewslettertJob < ApplicationJob
  def perform
    ...
    NewsletterMailer.morning_blast(data).deliver_now
  end
end

и NewsletterMailer:

class NewsletterMailer < ApplicationMailer
  def morning_blast(data)
    ...
    customers.each do |customer|
      yield customer, nil; next if customer.email.blank?

      begin
        Retryable.retryable( tries: 1, sleep: 30, on: [Net::OpenTimeout, Net::SMTPAuthenticationError, Net::SMTPServerBusy]) do
          send_email(customer.email).deliver
        end
        send_email(customer.email).deliver
      rescue Net::SMTPSyntaxError => e
        error_msg = "Newsletter sending failed on #{Time.now} with: #{e.message}. e.inspect: #{e.inspect}"
        logger.warn error_msg
        yield customer, nil
        next
      end
    end
  end
end

Чего я хочу добиться, так это того, что бюллетень будет рассылаться каждое утро, и если Rails / Sidekiq столкнется с проблемой, он просто отключится, поэтому информационный бюллетень не повлияет на «жизнь» на главном веб-сайте (его сервере).

Заранее благодарим вас за каждый совет. Я застрял в этом вопросе на некоторое время.

Ответы [ 2 ]

3 голосов
/ 20 марта 2020

Я думаю, что в идеале вам следует отделить серверы фоновых задач от веб-серверов, чтобы фоновый процесс не влиял на производительность веб-сервера. Я работаю в компании с очень высоким трафиком / высокой нагрузкой, и у нас здесь есть своего рода архитектура.

В этом ответе есть объяснения о том, как остановить повторные попытки: Отключить автоматизацию c повтор с ActiveJob, используется с Sidekiq

Еще одна вещь, ваша электронная почта отправляется синхронно (.deliver). Это подразумевает, что ваша задача - это огромный монолитный процесс со многими клиентами с огромным влиянием на память. Вместо этого вы можете использовать delivery_later, чтобы у каждого клиента был свой маленький работник. Это также поможет уменьшить использование процессора и памяти. Вы могли бы даже создать работника для отправки электронных писем по каждому клиенту и использовать свою монолитную работу, чтобы просто отправить их.

class NewslettertJob < ApplicationJob
  def perform
    ...
    customers.each |customer| do
      NewsletterMailer.morning_blast(customer, data).deliver_later if customer.email.present?
    end 
  end
end

Однако я думаю, что серебряная пуля отделяет ваш сервер sidekiq от вашего веб-сервера - один сервер выделен для фоновых задач. На вашем веб-сервере вы даже не запускаете инстансы sidekiq.

1 голос
/ 20 марта 2020
  1. Если ваша машина имеет только одно ядро, Sidekiq и puma будут бороться за процессор. Понизьте параллелизм Sidekiq, чтобы он потреблял меньше ресурсов ЦП, или получайте машину с несколькими ядрами, или перемещайте Sidekiq на другую машину.

  2. Если процесс Sidekiq использует 100% ядра, то ниже настройка параллелизма. По умолчанию в Sidekiq 6.0 установлено значение 10, что является хорошим значением по умолчанию, но если вы просто отправляете электронные письма, вы можете увеличить его до 20. Вы можете запустить несколько процессов Sidekiq, если вы используете sh, чтобы использовать несколько ядер для более быстрой обработки заданий.

...