Назад | Перейти на главную страницу

Получение фрагментированного запроса через nginx

Сначала немного предыстории: у нас есть встроенное устройство, которое загружает множество мелких событий на веб-сервер. Для публикации этой информации используется фрагментированное кодирование. Каждое событие отправляется отдельным блоком, поэтому веб-сервер (node.js) может немедленно реагировать на события. Все это работает как шарм.

Отключение серверов и запуск netcat на сервере показывает, что отправляет устройство:

sudo nc -l 8080
POST /embedded_endpoint/ HTTP/1.1
Host: url.com
User-Agent: spot/33-dirty
Transfer-Encoding: chunked
Accept: text/x-events
Content-Type: text/x-events
Cache-Control: no-cache

120
{"some","json message"}
232
{"other","json event"}
232
{"and a lot more","up to 150 messages per second!"}
0

Теперь я установил nginx на свой веб-сервер (версия 1.6.0). В конце концов, я хочу, чтобы он обрабатывал SSL, и я хочу ускорить нормальный веб-трафик.

Если я теперь включу nginx с этой конфигурацией сервера:

server {
  listen 8080;

  location / {
    proxy_http_version 1.1;
    expires off;
    proxy_buffering off;
    chunked_transfer_encoding on;
    proxy_pass http://localhost:5000;
  }
}

Тогда я получаю это:

sudo nc -l 8080
POST /embedded_endpoint/ HTTP/1.1
Host: localhost:5000
Connection: close
Content-Length: 2415
User-Agent: spot/33-dirty
Accept: text/x-events
Content-Type: text/x-events
Cache-Control: no-cache

{"some","json message"}
{"other","json event"}
{"and a lot more","up to 150 messages per second!"}

Проблема в том, что это буферизуется, запросы теперь отправляются каждые 2 секунды. Все сообщения включены и могут быть обработаны. Но сейчас задержка ...

Могу ли я указать nginx напрямую пересылать мои фрагменты? Это должно произойти только для этой встроенной конечной точки. Я понимаю, что в nginx нет особого смысла, если вы отключите это для всех конечных точек.

Если вы можете перейти на Nginx 1.8.x или Nginx 1.9.x, теперь вы можете использовать эту директиву для отключения буферизации запросов:

proxy_request_buffering off

Думаю, это должно решить вашу проблему.

Для меня лекарством были эти две настройки:

В файле: /etc/nginx/nginx.conf

Добавить:

proxy_max_temp_file_size 0;
proxy_buffering off;

Между линиями client_max_body_size 128M; и server_names_hash_bucket_size 256;:

http {

client_max_body_size 128M;
proxy_max_temp_file_size 0;
proxy_buffering off;
server_names_hash_bucket_size 256;

С участием proxy_buffering off, nginx не должен буферизовать фрагментированные ответы от серверной части. Вам не нужно устанавливать chunked_transfer_encoding on явно это значение по умолчанию. Следующим шагом, который я бы предпринял для диагностики, является просмотр потока между nginx и серверной частью (небольшой tcpdump -i lo -n port 5000 должен сделать трюк), чтобы увидеть, действительно ли nginx выполняет буферизацию или поведение бэкэнда по какой-то причине изменилось.