Как и зачем создавать NginX-модуль
- теория, практика, профит
Часть вторая
Сошников Василий, Mail.Ru Group
Agenda
• Введение
• Upstream (Proxy handler)
• Преобразование контента на лету
• Коротко о Shared memory
• CDN Video, аналитика и кэширование
Введение
Архитектура NginX
core
http upstream script
NginX
modules
Configuration
ngx_http_NAME_{main, srv, loc}_conf_t
Code
ngx_http_NAME_t
ngx_http_NAME_function(…)
Code style
Chain of responsibility
http
NginX
Module 1 Module N
Request
Reply
Next Next
Аналогия
Phases, всему свое время и место
NginX
Module 1 Module N
Next
Phase 1
Module 1 Module N
Next
Phase N
Доступные фазы
Файл: nginx/src/http/
ngx_http_core_module.h
[ Flags
]
[ Ptrs
]
Chain buffer
Файл: nginx/src/core/ngx_buf.h
Upstream (Proxy handler)
Анатомия
+ upstream Keepalive module
Application serverHTTP
Application server
Application server
Application server
Application server
Application server
Native protocol
Proxy & balancing
Инсталляция
- Регистрируем новую директиву и
handler [1]
- Инициализируем новый upstream [2]
- Добавляем новый handler [3]
[1]
[2]
[3]
Обработка контента
- Инициализируется при запросе [1]
- Upstream & Downstream инициализируется при запросе, либо
берется из модуля Upstream KeepAlive [2]
- Handlers (ngx_upstream_t::*) [3]:

create_request - создание запроса к backend.


reinit_request - reset запроса к backend (вызывается до
create_request).


process_header - обработка headers от backend.
abort_request - клиент отменил запрос.
finalize_request - nginx закончил читать из backend.
input_filter_ctx - контекст input handlers(void *).
input_filter_init[4] - инициализация фильтра.
input_filter[5] - преобразование ответа от backend.
- Вычитываем тело, которое отправил клиент [6].
- В ngx_upstream_t::buffer хранится ответ от backend.
[1]
[2]
[3]
[5]
[4]
[6]
Преобразование контента на лету
Анатомия
top_body_filter
Next
Body filters chain
ВАШ_body_filter
Инсталляция
- Регистрация модуля и
postconfiguration handler [1]
- Добавление в handler chain [2]
Внимание



Порядок модулей в chain не
гарантируется (!)
[1]
[2]
Обработка контента
Say hello to a stream parsing… (C)

О чем стоит помнить



- Все chain, все кусочками.
- ngx_buf_s::sync = 1, если у вас пустой
chain buffer.
- Иногда лучше использовать malloc,
realloc, free вместо chain buffer.
- Добавляйте кучу debug’а.
- Результатом работы предыдущего
модуля может быть поломка вашего.
Коротко о shared memory
Анатомия
HTTP
nginx-based service (!)
Shared Memory
CDN Video, аналитика и кэширование
Задача
• Ускорить Wowza Media Stream Server путем эффективного
кэширования контента на edge-серверах, но без потери
функциональности.
Решение в лоб
Edge / Front Edge / Cache OriginClient
Wowza
- Проверка токенов

- Роутинг

- Failover
- Кэширование (.ts-файлов)

- Инвалидация кэша
- Apple HLS
- RTMP
- DASH
Проблемы, или то, что мы теряем
• Wowza Media Stream
• Аналитика
• Биллинг
• Трекинг
Правильное решение
Edge / Front Edge / Cache OriginClient
Wowza
Плюс

————————————

- трекинг пользователей (!)

- специальное логирование в формате wowza(!)
Трекинг
- Генерация уникального session id
- Должно быть отключаемо
(контролируем через nginx.conf)
- m3u8-файлы не кэшируются (!)
M3u8-файлы
Wowza
GET /playlist.m3u8&token=STR&…
GET /playlist.m3u8?session_id=NUM&token=STR…
Wowza
GET /playlist.m3u8?session_id=NUM&…

— Контент файла —

#EXTM3U

chunklist_w1447934753_b0001.m3u8?session_id=NUM?…n

…
Запрос Ответ
Логирование
- В формате Wowza (!)
- analytics.log
- access.log
- примеры на картинке слева
- Трекинг событий (start, play, stop …)
- Локальный Nginx-based сервис для
логирования
Сбор и агрегация логов
Edge / FrontClient
- Контроль TTL сессий

- Запись в логи

- Ротация логово
Shared memory queue
statagetnd Файлы Сборщик / Аргрегатор
СУБД / GUI / Отчеты / Биллинг
- Дедубликация (destroy, stop)

- Много разных агрегаций

- Сборка логов с edge-фронтов
…
Решено! Но вскрылись недостатки
• Wowza Media Stream Server все еще чувствует себя
плохо из-за запросов m3u8-файлов.
Фикс — перезаписываем контент кэша при
запросе
Edge / Front Edge / Cache OriginClient
Wowza
Плюс

————————————

- преобразование m3u8-файлов на лету

- кэшируем m3u8-файлы с очень маленьким TTL
Перезаписываем
контент
- Парсим m3u8-файл из кэша (!)
- Обновляем URI-аргументы в файле
- Отдаем клиенту измененный контент
Cache
GET /playlist.m3u8&token=STR&…
GET /playlist.m3u8?session_id=NUM&token=STR…
Cache
GET /playlist.m3u8?session_id=NUM&…

— Контент файла —

#EXTM3U

chunklist_w1447934753_b0001.m3u8?{REWRITE ARGS}n

…
Запрос Ответ
Схема
Ссылки
https://github.com/dedok/nginx-tutorials — примеры с прошлого выступления.


https://github.com/tarantool/nginx_upstream_module — пример upstream-модуля.
https://www.nginx.com/resources/wiki/modules/ — библиотека знаний и модулей.
https://github.com/nginx/nginx — исходники nginx.



https://en.wikipedia.org/wiki/HTTP_Live_Streaming — о HLS.

Вопросы & Контакты
• GitHub
• https://github.com/dedok
• Twitter
• https://twitter.com/vasayso
• @vasayso
• Telegram
• vasily_soshnikov

Как и зачем создавать NginX-модуль — теория, практика, профит. Часть 2 / Василий Сошников (Mail.Ru)