Глеб Гончаров

Системный администратор в ФанБоксе. Автоматизирую и сопровождаю инфраструктуру для проектов мобильных операторов.

О работе 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 для вашего сервиса, если планируете использовать опцию в будущем.

Я рекомендую не отключать буферизацию. Возможно, эта оптимизация и играет роль на больших объёмах трафика, однако в небольших проектах влияние на производительность будет малозаметным.