Skip to content

alheio/blizzard

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ОПИСАНИЕ

blizzard - многопоточный HTTP-сервер

Используется приложениями, нуждающимися в HTTP-общении с окружающим миром -
такое приложение реализуются как .so-плагин к blizzard-у. От плагина
требуется реализация интерфейса blizzard-плагина - конструктор/деструктор,
load(), easy() хендлер, hard() хендлер. Опционально - idle() и другие, не
полностью виртуальные функции класса blz_plugin.

blizzard поддерживает следующие ключи командной строки:

  -c, --config-file=   - конфиг-файл
  -p, --pid-file=      - pid-файл
  -d, --daemon         - демонизироваться при запуске
  -D, --no-daemon      - не демонизироваться при запуске

Общая работа сервера проста:

Cервер стартует, парсит свой конфиг, создаёт объект плагина, вызывает его
метод load(), передавая ему необходимые параметры, инициализирует сетевые
соединения

* сетевой поток - следит за сокетом, привешенным к "входящему" порту; когда
  получает соединение, добавляет сокет в список готовых сокетов; обрабатывает
  сетевые события; парсит HTTP-запросы; готовые запросы кладёт в easy-очередь;
  проверяет done-очередь на предмет ответов; отдаёт сформированные ответы.
  Если установлен лимит на количество элементов в easy/hard-очереди, на все
  излишки сервер отвечает 503 ошибкой.

* easy-потоки (число задаётся конфигом). Спят, ожидая данные в easy-очереди.
  Если в очереди появляются запросы, easy-потоки оживают, конкурентно вызывая
  easy-хендлер плагина на каждый элемент очереди. После этого варианта три:

  1 хендлер обработал конект - blizzard кладёт запрос в done-очередь.
  2 хендлер не осилил запрос - blizzard кладёт запрос в hard-очередь.
  3 хендлер обнаружил ошибку - blizzard пишет в соединение код 503, кладя запрос в done-очередь.

* hard-потоки (число задаётся конфигом). Спят, ожидая данные в hard-очереди.
  Если в очереди появляются запросы, hard-потоки оживают, радостно разгребая 
  очередь и вызывая hard-хендлер на каждый элемент. Тут у хэндлера уже два
  варианта:

  1 хендлер обработал конект - blizzard кладёт запрос в done-очередь.
  2 хендлер обнаружил ошибку - blizzard пишет в соединение код 503, кладя запрос в done-очередь.

* idle-поток. Если в конфиге есть ключ <idle_timeout>, этот поток вызывает
  idle-функцию у плагина с заданной ключом периодичностью. Иначе он вызывает
  idle ровно один раз.

КОНФИГУРАЦИОННЫЙ ФАЙЛ

Параметры:

  <pid_file_name>        - имя pid-файла
  <log_file_name>        - имя log-файла
  <log_level>            - уровень логгирования, варианты: alert crit error warn notice info debug - в порядке убывания важности

  <stats>
    <uri>                - по этому URI можно получить статистику
  </stats>

  <plugin>
    <ip>                 - айпи входного сокета
    <port>               - порт входного сокета
    <connection_timeout> - таймаут на каждый коннекшн
    <idle_timeout>       - период между вызовами idle у плагина в мс
    <library>            - путь к .so-плагину
    <params>             - строка, передаваемая в set_param для инициализации плагина
    <easy_threads>       - число easy-потоков
    <hard_threads>       - число hard-потоков
    <easy_queue_limit>   - если указан, ограничивает число запросов в easy-очереди
    <hard_queue_limit>   - если указан, ограничивает число запросов в hard-очереди.
  </plugin>

СТАТИСТИКА

Статистика отдаётся при запросе к uri, указанному в директиве uri секции stats
в следующем формате:

  <blizzard_stats>                                           
      <blizzard_version>0.3.2</blizzard_version>
      <uptime>287</uptime>                     # в секундах
      <rps>1105.250</rps>                      # запросов в секунду
      <queues>                                 # размеры очередей
          <easy>2</easy>                       # мгновенный размер
          <max_easy>1</max_easy>               # максимальный размер за предыдущие 4 секунды
          <hard>0</hard>
          <max_hard>0</max_hard>
          <done>0</done>
          <max_done>1</max_done>
      </queues>
      <response_time>                          # времена обработки запросов (в секундах)
          <min>0.127500</min>                  # минимальное за предыдущие 4 секунды
          <avg>1.342132</avg>                  # среднее за предыдущие 4 секунды
          <max>8.674405</max>                  # максимальное за предыдущие 4 секунды
      </response_time>
      <mem_allocator>                          # данные аллокатора памяти
          <pages>1</pages>                     # кол-во выделенных страниц в http-пуле
          <objects>8</objects>                 # кол-во выделенных объектов в http-пуле
      </mem_allocator>
      <rusage>                                 # данные rusage для blizzard-а
          <utime>2</utime>                     # время в userspace
          <stime>4</stime>                     # время в system
      </rusage>
  </blizzard_stats>

ИЗВЕСТНЫЕ ПРОБЛЕМЫ

* если максимальное число файловых дескрипторов не очень велико (ulimit -n
  выдаёт например 1024), при большой интенсивности запросов этот запас может
  исчерпаться, вызывая таймауты по соответствующим коннектам. Потому при
  таймаутах как минимум нужно выставить ulimit -n достаточно большим, например,
  16384

* сервер отличается агрессивным поведением в отношении коннектов, с которыми у
  него есть проблемы - он просто закрывает соединение, если ошибка в
  http-запросе, если суммарный размер HTTP-хэдеров больше 8кб, если наступил
  таймаут итд.

About

http-server with two pools of threads (one for easy to handle requests, and one for hard to handle), forked from Begun's lizard

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 84.3%
  • CMake 15.7%