Буферизация вывода в Nginx

Последние два дня решали проблему высокой нагрузки на серверах 2ip.ru. Если в цифрах, то это порядка 130 тысяч хостов в сутки. В итоге откладывать было дальше некуда, я сел и переписал мод рерайт конфиг от apache, в локейшены nginx, на который мы решили перейти.

Попробовали конфигурацию, всё хорошо, но измерение скорости перестало работать. Причина ниже.

Если очень примерно, то замеры скорости у нас работает вот так:

<?php
   $start =  microtime();
   include('file.dat');
   $finish = microtime();
?>

1) Со стороны пользователя запрашиваем наш сценарий, замеряем время начала запроса.
2) Отдаём файл с мусором, известного нам размера. Пользователь тянет его на своей максимальной скорости.
3) Когда отдача завершена, делаем ещё один замер времени.
4) Считаем разницу между финишем и стартом, ну а дальше посчитать скорость зная время отдачи и размер файла — просто.

Дебаг показал, что каким бы большим ни был файл в инклюде, мы будем иметь практически идентичное время на выходе и входе.

Ноги растут из буферизации, которой во всю пользуется nginx. Он не ждёт сторону клиента, и автоматически выгружает всё из php-fpm себе в буфер, в итоге замеры скорости в принципе невозможны.

Но решение есть, в последней версии1, там как раз добавили простое отключение буферизации, причём сделать это можно выборочно. Например в определённый location можно добавить один параметр fastcgi_buffering off;, документация по теме.

После этого php ведёт себя адекватно. Как добавить передовые ветки в ваш линукс написано тут.

Слава роботам!


  1. на данный момент это 1.5.6. 


comments powered by Disqus