Сасл: Перегрузка. Или – «Не Кладите На Тарелку Больше, Чем Она Может Вместить»

Эrlang — отличная платформа для создания серверов, а ее стандартная библиотека предоставляет множество инструментов, значительно облегчающих жизнь разработчика.

Одной из типичных задач разработчика промышленного сервера является контроль нагрузки.

То есть наш сервер должен вести себя адекватно, даже если запросов больше, чем сервер (на нашем оборудовании) может обработать.

В этом, собственно, и состоит одно из ключевых отличий решений «по колено» от «Enterprise».

Настоящий, хорошо спроектированный сервер «знает», что он не может тратить ресурсы бесконечно, отслеживает ресурсы и контролирует нагрузку.

Как это сделано? Одним из средств контроля загрузки в программах Erlang является модуль перегрузка в приложении сасл .

Ее идея очень проста — при поступлении нового запроса от клиента мы проверяем текущую нагрузку, если она больше N в секунду, отправляем клиенту вежливый отказ.

Если нагрузка меньше этого порога, то передаем этот запрос в основную обработку.

Идея проста — но реализация довольно неприятная, нужно запоминать время прихода последних нескольких запросов, учитывать, что могут быть локальные «пики» интенсивности запросов и т.д. К счастью для нас, все это делает модуль перегрузки.

В настройках программы можно указать необходимый порог (грубо говоря в sys.config ), а затем, когда приходит запрос от клиента, мы просто выполняем перегрузка: запрос() и смотрим на результат - принимаем - продолжаем работать, отклоняем - отказываемся от обслуживания.

То есть что-то вроде

 
 handle_call(SomeRequest,State) ->
   case overload:request() of
      reject -> {reply, overloaded, State}
      accept -> {Result,NewState}= do_something(SomeRequest,State),
                     {reply,Result,NewState}
    end.
 
Негласно sasl подсчитывает, когда и сколько раз была вызвана перегрузка:request(), и на основании этого по сложной формуле (можно посмотреть в документации) рассчитывает нагрузку и по результатам решает, стоит ли текущий запрос достоин обработки Как это выглядит на практике: Настраиваем sasl, примерно такой sys.config:
 
 [
 {sasl,[{overload_max_intensity, 300.0},{sasl_error_logger,{file,"/var/log/rcvr.log"}},{utc_log,false}]}
 ].

Здесь мы устанавливаем максимальную интенсивность 300 запросов в секунду.

Давайте побежим, например erl +K true -sname rcvr -setcookie 123 -config sys.config И мы следим за загрузкой.

Через неделю Мунин показывает нам это:

сасл: перегрузка.
</p><p>
 Или – «не кладите на тарелку больше, чем она может вместить»

Здесь вы можете видеть, что сервер принимает и обрабатывает всего 300 запросов в секунду, это то, что нам нужно.



Минусы перегрузки
  • Поскольку sasl подсчитывает интенсивность вызовов перегрузки:request() для определения текущей нагрузки, перегрузку:request() можно использовать только в одном месте программы.

    У вас не работает для сервера, который принимает (например) http и rpc запросы, настройте перегрузку отдельно для rpc и отдельно для http.

  • Настройки указаны в sys.config (или в файле .

    app) и не могут быть изменены во время работы программы.

    то есть для перенастройки sasl:overload вам придется перезагрузить сервер.



Мораль
Модуль перегрузки удобен, но применим не везде из-за своих ограничений.

но в любом случае об этом надо знать и помнить.

Теги: #erlang #OTP #Erlang/OTP

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.