alheio/blizzard
Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
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кб, если наступил
таймаут итд.