Разбираемся в работе gzip_no_buffer в Nginx
В сентябре вышел пост SRE Dropbox об оптимизации веб-серверов в их геораспределённой сети доставки контента. Я заинтересовался опцией gzip_no_buffer
в NGINX для сокращения времени получения первого байта TCP-пакета с сервера (TTFB).
Этой опции нет в официальной документации, а единственное упоминание в книге NGINX HTTP Server Кле́мана Неде́льку вторит ответу Игоря Сысоева в почтовой рассылке 2006-го года:
By default Nginx waits until at least one buffer (defined by gzip_buffers) is filled with data before sending the response to the client. Enabling this directive disables buffering.
Из описания кажется, что опция отключает буферизацию, если ответ укладывается в один буфер, а если контент больше, то просто буферизирует вывод. Спешу огорчить: это не так.
if (conf->no_buffer && ctx->in == NULL) {
cl = ngx_alloc_chain_link(r->pool);
if (cl == NULL) {
return NGX_ERROR;
}
cl->buf = ctx->out_buf;
cl->next = NULL;
*ctx->last_out = cl;
ctx->last_out = &cl->next;
return NGX_OK;
}
Если включен gzip_no_buffer
, то заполняется один буфер, а затем возвращается клиенту без обработки следующей порции. В случае же превышения размера буфера, клиент получит ответ нулевой длины.
Иными словами, если размер буфера окажется недостаточным, веб-сервер не будет отдавать контент вовсе. Учитывайте эту особенность при конфигурировании NGINX. Выберите подходящее значение gzip_buffers
для вашего сервиса, если планируете использовать опцию в будущем.
Я рекомендую не отключать буферизацию. Возможно, эта оптимизация и играет роль на больших объёмах трафика, однако в небольших проектах влияние на производительность будет малозаметным.