sendfile, tcp_nopush, tcp_nodelay în Nginx

Performanță și PHP Toate versiunile Nginx (sendfile_max_chunk implicit 2m din 1.21.4)

sendfile trimite fișierele statice direct din nucleul sistemului, fără copieri prin memoria lui Nginx; tcp_nopush și tcp_nodelay reglează pachetele TCP.

Sintaxă
sendfile on | off;
tcp_nopush on | off;
tcp_nodelay on | off;

Ce face sendfile, tcp_nopush, tcp_nodelay

Fără sendfile, Nginx citește fișierul în memorie și apoi îl scrie în conexiune. Cu sendfile on; folosește apelul de sistem sendfile(): nucleul copiază datele direct din cache-ul de fișiere în socket. Pentru fișiere statice (imagini, CSS, descărcări) consumul de procesor scade.

tcp_nopush on (doar împreună cu sendfile) trimite antetele răspunsului și începutul fișierului în același pachet și umple pachetele complet. tcp_nodelay on (implicit) trimite imediat datele mici pe conexiunile keep-alive, fără întârzierea algoritmului Nagle.

Cele trei se folosesc de obicei împreună. Pe unele sisteme de fișiere de rețea sau în mașini virtuale cu directoare partajate (de exemplu VirtualBox) sendfile poate trimite fișiere vechi sau corupte; acolo se oprește.

Parametri

Parametru Descriere
Context http, server, location (sendfile și în if din location).
Implicit sendfile off;, tcp_nopush off;, tcp_nodelay on;
sendfile_max_chunk Cât trimite un apel sendfile() o dată (implicit 2m), ca o descărcare mare să nu blocheze workerul.

Ce returnează

Nimic; schimbă modul în care Nginx trimite fișierele.

Exemple

Exemplul 1: Configurația obișnuită din nginx.conf

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    # ...
}

Exemplul 2: Mediu de dezvoltare cu director partajat

Într-o mașină virtuală Vagrant/VirtualBox cu director partajat, sendfile off previne servirea unor versiuni vechi ale fișierelor modificate.

server {
    listen 80;
    server_name dev.local;
    root /vagrant/public;

    sendfile off;
}

Greșeli frecvente

  • Activezi tcp_nopush fără sendfile: nu are niciun efect.
  • Modifici CSS-ul în mașina virtuală și browserul primește fișierul vechi sau trunchiat, deși cache-ul e golit: oprește sendfile pe directoarele partajate.

Comenzi înrudite

  • open_file_cache: Păstrează în memorie fișierele deschise des (descriptori, dimensiuni, date de modificare), ca Nginx să nu le caute pe disc la fiecare cerere.