#FailOverConf «Не забивайте гвозди микроскопом!» Делаем скоростной frontend на nginx+Lua Александр Демидов «1С-Битрикс» #FailOverConf #FailOverConf Классика #FailOverConf #FailOverConf Волшебный proxy_pass Например: proxy_pass http://sqs.eu-west-1.amazonaws.com/...; #FailOverConf #FailOverConf Проверка доступности #FailOverConf #FailOverConf На «чистом» nginx – не получилось… • Нельзя использовать вместе proxy_pass и return • Не получалось переписать ответ на проксируемый запрос • Добавили PHP-FPM как бэкенд • И написали простой скрипт в несколько строк на PHP Итог: • Расход памяти • Блокирующие запросы #FailOverConf #FailOverConf #FailOverConf Скорость сайтов • Какой сайт считается быстрым? • Быстро генерируется, минимальное число запросов к базе, быстро скачивается страница… • Есть только один критерий с точки зрения клиента - насколько быстро отображается сайт. #FailOverConf Что считать? Navigation Timing API #FailOverConf #FailOverConf Сколько? • Собираем метрики в Javascript • Потенциально – десятки тысяч сайтов • 500-1500-… запросов на вставку в секунду • Десятки миллионов хитов в день • Последние N-хитов • Гистограмма распределения, онлайн #FailOverConf #FailOverConf Сколько? • Собираем метрики в Javascript • Потенциально – десятки тысяч сайтов • 500-1500-… запросов на вставку в секунду • Десятки миллионов хитов в день • Последние N-хитов • Гистограмма распределения, онлайн #FailOverConf #FailOverConf Куда писать? #FailOverConf #FailOverConf Требования • Напоминаем - 500-1500-… запросов на вставку в секунду, должны быть неблокирующими • Сложная логика проверки и выставления кук • Принимать и POST, и GET – передавать только POST • Авторизация в Amazon Web Services, v. 4 • В ответ клиенту – валидный Javascript #FailOverConf #FailOverConf Nginx? Nginx! #FailOverConf Варианты: • «Чистый» nginx – невозможно реализовать всю логику • Nginx + бэкенд (PHP) – низкая производительность, расход ресурсов • Nginx + свой модуль (С/C++) – сложно, долго разрабатывать и тестировать • Nginx + ngx_http_perl_module – блокирующий, «модуль экспериментальный, поэтому возможно всё» • Nginx + ngx_lua - … #FailOverConf Почему Lua? • Что-то новое и простое #FailOverConf #FailOverConf Почему Lua? • Очень легкий • Очень быстрый (LuaJIT) • Очень гибкий: • доступ к HTTP запросу и ответу • синхронные неблокирующие подзапросы (ngx.location.capture, connect) • дополнительные модули • разные фазы (rewrite, content, log и т.д.) #FailOverConf #FailOverConf Прокси в Kinesis #FailOverConf http { lua_package_cpath "/usr/lib64/crypto.so;;"; server { location /bx_stat { lua_need_request_body on; rewrite_by_lua ‘ local data = "" if ngx.var.request_method == "POST" then data = ngx.req.get_body_data() else data = ngx.var.query_string; ngx.req.set_uri_args(""); end ... local crypto = require "crypto" local kDate = crypto.hmac.digest("sha256", date_short, "AWS4" .. secret_key, true) ... ngx.req.set_header("x-amz-date", date_long) ngx.req.set_header("Authorization", "AWS4-HMAC-SHA256 Credential= ... ‘; proxy_set_header Host kinesis.eu-west-1.amazonaws.com; proxy_pass https://kinesis.eu-west-1.amazonaws.com/; #FailOverConf Нюансы настройки nginx worker_processes 4; events { worker_connections } 10240; worker_rlimit_nofile 100000; proxy_hide_header proxy_hide_header proxy_hide_header proxy_hide_header Access-Control-Expose-Headers; x-amz-id-2; x-amzn-RequestId; Content-Type; proxy_method POST; #FailOverConf #FailOverConf Сеть /etc/sysctl.conf (man sysctl) # диапазон портов исходящих коннектов net.ipv4.ip_local_port_range=1024 65535 # повторное использование TIME_WAIT сокетов net.ipv4.tcp_tw_reuse=1 # быстрая утилизация TIME_WAIT сокетов net.ipv4.tcp_tw_recycle=1 # время пребывания сокета в FIN_WAIT_2 net.ipv4.tcp_fin_timeout=15 # размер таблиц файрволла net.netfilter.nf_conntrack_max=1048576 # длина очереди входящих пакетов на интерфейсе net.core.netdev_max_backlog=50000 # количество возможных подключений к сокету net.core.somaxconn=81920 # не посылать syncookies на SYN запросы net.ipv4.tcp_syncookies=0 #FailOverConf #FailOverConf Что получилось? #FailOverConf #FailOverConf Характеристики системы #FailOverConf #FailOverConf Летим и… спотыкаемся • Ошибки "connect() to [...] failed (99: Cannot assign requested address) while connecting to upstream« • Огромное количество TIME_WAIT #FailOverConf #FailOverConf «Волшебная пилюля» #FailOverConf upstream kinesis { server kinesis.eu-west-1.amazonaws.com:443 max_fails=0 fail_timeout=10s; keepalive 1024; } proxy_pass https://kinesis/; proxy_http_version 1.1; proxy_set_header Connection ""; #FailOverConf Новая задача – ускорение «Битрикс24» #FailOverConf #FailOverConf «Веб-акселератор» #FailOverConf • Поддержка SPDY для клиентов • SSL keep alive на бэкенды • Раздельный кэш для общей статики /bitrix/.*.(css|js|png|…), пользовательской статики, композитных хитов • Вся логика исключений для композита • Через header_filter_by_lua – удаление кэша (высчитываем путь к файлам, удаляем через Lua os.remove) #FailOverConf «Веб-акселератор» #FailOverConf • Через header_filter_by_lua – удаление кэша (высчитываем путь к файлам, удаляем через Lua os.remove) #FailOverConf Новая задача – ускорение «Битрикс24» #FailOverConf #FailOverConf А еще? Библиотека lua-resty - интерфейсы к: • memcached • MySQL • Redis • WebSocket • И т.д. #FailOverConf #FailOverConf Где применить? • Альтернатива map’ам • Много виртуальных хостов (shared хостинги?) • CMS на Lua #FailOverConf #FailOverConf Резюме #FailOverConf «Скорость сайтов» - 1 виртуальный сервер (2 ядра, 4 Гб RAM) • 55+ млн. хитов в сутки «Веб-акселератор» «Битрикс24» - физический сервер (быстрые SSD диски для большого объема кэша) • 55+ млн. хитов в сутки Сложная логика бэкенда (обработка запросов, коннекты к внешним сервисам, работа с кэшем) – прямо на фронтенде http://nginx.org/ru/docs/ http://wiki.nginx.org/HttpLuaModule http://www.lua.ru/doc/ #FailOverConf Спасибо за внимание! Вопросы? Александр Демидов demidov@1c-bitrix.ru +7-926-521-3700 @demidov http://www.1c-bitrix.ru