Использование Puma и Sidekiq в бэкэнд-приложении Rails

У меня есть внутренний сервер Rails с Sidekiq, который служит сервером API. Приложение работает следующим образом:

  1. Мой сервер Rails получает множество запросов от входящих клиентов API одновременно.

  2. Для каждого из этих запросов сервер Rails будет выделять задания серверу Sidekiq. Сервер Sidekiq отправляет запросы к внешним API (таким как Facebook) для получения данных, их анализа и возврата результата на сервер Rails.

Например, если я получаю 10 входящих запросов от своих API-клиентов, на каждый запрос мне нужно сделать 10 запросов к внешним API-серверам, получить данные и обработать их.

Моя задача состоит в том, чтобы заставить мое приложение одновременно отвечать на входящие запросы. То есть каждый входящий запрос мое приложение должно обрабатывать параллельно: совершать вызовы к внешним API, получать данные и возвращать результат.

Теперь я знаю, что Puma может добавить параллелизм в приложение Rails, в то время как Sidekiq является многопоточным.

Мой вопрос: действительно ли мне нужен Sidekiq, если у меня уже есть Puma? Какая польза от использования Puma и Sidekiq?

В частности, с Puma я просто вызываю свои внешние вызовы API, обработку данных и т. д. из моего приложения Rails, и они будут автоматически параллельны.


person AdamNYC    schedule 28.09.2013    source источник


Ответы (2)


Да, вы, вероятно, хотите использовать Puma и Sidekiq. Здесь на самом деле есть две проблемы.

Параллелизм (как, кажется, вы уже знаете) — это количество веб-запросов, которые могут быть обработаны одновременно. Использование сервера приложений, такого как Puma или Unicorn, определенно поможет вам добиться лучшего параллелизма, чем сервер веб-кирпича по умолчанию.

Другая проблема заключается в том, сколько времени требуется вашему серверу для обработки веб-запроса.

Причина, по которой эти две вещи связаны, заключается в том, что количество запросов в секунду, которые может обработать ваше приложение, зависит как от среднего времени обработки каждого запроса, так и от количества рабочих процессов, принимающих запросы. Скажем, ваше среднее время отклика составляет 100 мс. Тогда один веб-воркер может обрабатывать 10 запросов в секунду. Если у вас 5 воркеров, то вы можете обрабатывать 50 запросов в секунду. Если ваше среднее время отклика составляет 500 мс, то вы можете обрабатывать 2 запроса в секунду с одним работником и 10 запросов в секунду с 5 работниками.

Время от времени взаимодействие с внешними API может быть медленным, а в худших случаях оно может быть очень ненадежным из-за неотвечающих серверов на удаленном конце, сбоев или замедлений сети. Sidekiq — отличный способ оградить ваше приложение (и ваших конечных пользователей) от возможности медленного отклика удаленного API. Представьте, что удаленный API по какой-то причине работает медленно и среднее время ответа от него замедлилось до 2 секунд на запрос. В этом случае вы сможете обрабатывать только 2,5 запроса в секунду с 5 работниками. При большем трафике ваши конечные пользователи могут начать долго ждать, прежде чем любая страница в вашем приложении сможет ответить, даже те, которые не делают удаленные вызовы API, потому что все ваши веб-работники могут ожидать медленного удаленного API. ответить. Поскольку трафик продолжает расти, ваши пользователи начнут получать тайм-ауты соединения.

Идея использования Sidekiq заключается в том, что вы отделяете время, затрачиваемое на ожидание внешнего API, от ваших веб-воркеров. В основном вы берете запрос данных от своего пользователя, передаете его Sidekiq, а затем немедленно возвращаете ответ пользователю, который в основном говорит: «мы обрабатываем ваш запрос». Затем Sidekiq может взять задание и сделать внешний запрос. После того, как у него есть данные, он может сохранить эти данные обратно в ваше приложение. Затем вы можете использовать веб-сокеты, чтобы отправить пользователю уведомление о том, что данные готовы. Или даже отправить им данные напрямую и соответствующим образом обновить страницу. (Вы также можете использовать опрос, чтобы страница постоянно спрашивала «она уже готова?», но это очень быстро становится очень неэффективным.)

Я надеюсь это имеет смысл. Дайте знать, если у вас появятся вопросы.

person Jeremy Green    schedule 29.09.2013
comment
Большое спасибо, Джереми. Это имеет большой смысл. Мой процесс занимает одну-две минуты, чтобы извлечь данные из внешних API. Меня беспокоит то, что ресурсы моих воркеров заблокированы в ожидании данных от API. Помогает ли Sidekiq решить эту проблему? - person AdamNYC; 29.09.2013
comment
Да, Sidekiq поможет с этим. Последний длинный абзац моего ответа - это описание того, как это будет работать. - person Jeremy Green; 29.09.2013
comment
Спасибо, Джереми. Я получил эту часть. Мой вопрос: даже если мой Sidekiq создает несколько потоков и ждет ответов от внешних API, будут ли эти потоки по-прежнему удерживать ресурсы (ЦП, ОЗУ) в течение нескольких минут во время ожидания? Я предполагаю, что если мое приложение может работать асинхронно, то в ожидании ответа ресурсы моего сервера могут использоваться для выполнения других запросов или для обработки данных, возвращенных из более ранних запросов. - person AdamNYC; 30.09.2013
comment
Ответ на этот вопрос во многом зависит от того, как работают внешние вызовы API. Если вы можете просто отправить им запрос, а затем они сразу же вернут сообщение о том, что мы обрабатываем ваш запрос, затем они POST отправят результаты в веб-перехватчик на вашей стороне, тогда да, вы сможете делать другие вещи во время ожидания. Если вы отправляете запрос и их сервисные блоки до тех пор, пока у него не будут данные, готовые вернуться непосредственно к тому же запросу, ваш рабочий процесс все равно будет потреблять ресурсы во время ожидания. - person Jeremy Green; 30.09.2013

Sidekiq, как Resque и Delayed Job, предназначен для обеспечения асинхронной обработки заданий из очереди.

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

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

person colinm    schedule 29.09.2013
comment
Спасибо @colinm. Мои клиенты ждут данных. Как правило, моим работникам требуется несколько минут, чтобы вернуть результат клиентам. Однако клиенты могут отправлять несколько запросов одновременно. Я хотел бы начать обработку данных для каждого из запросов параллельно и вернуть клиентам все, что было возвращено с моего сервера Sidekiq. Что было бы хорошим выходом из моей ситуации? Спасибо за ваше понимание. - person AdamNYC; 29.09.2013
comment
Более 750 мс? Асинхронный - person ; 17.03.2014