Почему SSE в рельсах висят на связи? - PullRequest
1 голос
/ 22 апреля 2019

Я читаю это сообщение , в котором говорится о соединениях SSE без блокировки потоков сервера Автор описывает, как решить проблему блокировки.

Моя путаница заключается в том, что если я закрываю поток на стороне сервера (с sse.close) и на стороне клиента (с source.close()), почему у вас возникла проблема? Почему сервер висит на соединении?

1 Ответ

1 голос
/ 22 апреля 2019

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

Например, скажем (очень упрощенно и приблизительно):

  1. у вас есть 10 потоков / рабочих, без SSE
  2. вы открываете каждую html-страницу менее чем за 0,1 секунды
  3. пользователь будет ждать до 1 секунды, пока страница загрузится, прежде чем разрыдаться и уйти с вашего сайта
  4. пользователь затемпрочитайте страницу в течение 9 секунд, прежде чем запросить следующую

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

Теперь добавляем обновления SSE на эти страницы, шаг за шагом:

  1. первый пользователь подключается, получает htmlчерез 0,1 с, затем один поток будет занят запросом SSE за 9 секунд до перезагрузки страницы, и после этой перезагрузки он снова будет заблокирован запросом того же пользователя
  2. у вас есть только 9 свободных потоков
  3. второй пользователь подключается, то же самое повторяется

Таким образом, в одной системе может обрабатываться только максимум 10 пользователей , что в 100 раз меньше.И вы не можете просто увеличить потоки до 1000, потому что они не свободны (память, накладные расходы планировщика и т. Д.).

Подвох в том, что в большинстве случаев большинство таких соединений ничего не делают, просто ожидают события,поэтому им на самом деле не нужна зарезервированная для них тема.Так что логично освобождать поток для других запросов, не закрывая соединение, вот что делает hijack.

PS.Этот подход может пойти еще дальше: клиентские обновления в режиме реального времени могут оставаться открытыми с помощью процесса, отличного от rails server (не ruby ​​и более эффективный), при этом все еще выполняя всю логику событий в rails.Например, с помощью anycable backend для ActionCable вы можете легко поддерживать тысячи одновременных подключений

...