Страницы

Поиск по вопросам

суббота, 27 октября 2018 г.

NGINX: раздача дописываемого файла

В моем приложении есть файл, который по сути напоминает лог т.е. постоянно дописывается. Хочу использовать хедер Range для как альтернативу long polling и вебсокетам для чтения дополняющегося файла, так как на реализацию этих технологий нужно время, тем более с учетом использования С++. Насколько эффективно NGINX справится с такой задачей, возможно будут проблемы при работе с дополняющимися файлами? И какие параметры будут оптимальными для реализации этого подхода? Может быть нужно использовать directio в приложении и NGINX для оптимизации? Или стоит вообще отказаться от этой идеи?... Сервер на базе linux, файловая система ext4. Размер файла не превышает 100МБ(одновременно запись идет в один файл, потом создается новый).
PS: В файл придется писать в любом случае и разбивка на мелкие файлы не связана с реализацией этого подхода.


Ответ

Не имеет смысла изобретать велосипед так как для nginx уже есть модуль для работы с вебсокетами, который берет всю сложную работу на себя. Вам остается только передавать сообщения для доставки в nginx. Устанавливается на раз:
sudo apt install libnginx-mod-nchan
Настройка тоже ничего сложного не представляет. Может работать через Redis в конфигурации с множеством серверов.
Если вы по какой-то причине не можете использовать этот модуль, то опять же стоит изобретать очередную БД на коленке. На серьёзных нагрузках файлы на диске никогда не заменят настоящую БД, будь это MySQL или что. Хотя бы потому что типичная БД может гарантировать что горячие данные будут в оперативке, тогда как дисковый кеш вообще ничего не гарантирует. Это очень легко проверить простым бенчмарком.

Из альтернатив можно рассмотреть, например, websocketd. Эта программа, очень близкая по сути inetd, существует отдельно от nginx. Вам нужно лишь перенаправить WS соединения на неё, что очень просто.
location /mywsapp { proxy_pass http://mywsbackend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
В простейшем виде, без nginx, программа, которая будет читать из файла новый строки и передавать их по WebSocket будет выглядеть так: (tail.sh)
#!/bin/bash tail -q -n0 -F /tmp/websocketdata.txt
Страница, которая читает данные, выглядит так: (index.html)


Если оба файла в одном каталоге, то запускаем:
python -m SimpleHTTPServer 8000 & ./websocketd --port=8080 ./tail.sh &
Открываем в браузере http://127.0.0.1:8000/ и в соседней консоли пишем в файл:
tee -a /tmp/websocketdata.txt
Печатаем текст и смотрим как он появляется в окне браузера в тот же миг.
Это читающей программе будут доступны всевозможные переменные как если бы она работала CGI в окружении, например QUERY_STRING и другие. Без необходимости их проверять можно сделать даже так, убрав прослойку из bash:
./websocketd --port=8080 tail -q -n0 -F /tmp/websocketdata.txt
Чтобы не усложнять программу для чтения файлов можно проверять доступ к подключению через WebSocket на стороне nginx используя директиву auth_request

Комментариев нет:

Отправить комментарий