Baza wiedzy

Ustawienia jądra dla dużej liczby połączeń

Wartości sysctl i limity systemd, które mają znaczenie, gdy maszyna utrzymuje dziesiątki tysięcy gniazd, oraz te skopiowane ze starych wpisów na blogu, które nie robią nic.

Najpierw zmierz

ss -s
cat /proc/sys/fs/file-nr
nstat -az TcpExtListenOverflows TcpExtListenDrops

ListenOverflows rosnące oznacza, że kolejka akceptacji jest pełna i jądro odrzuca ukończone uzgadnianie. To konkretny problem z konkretnym rozwiązaniem. Większości innych objawów nie rozwiązuje się przez sysctl w ogóle, a strojenie maszyny, która nie jest pod obciążeniem, tylko przenosi ostateczną awarię w miejsce trudniejsze do znalezienia.

Ustawienia, które się opłacają

# /etc/sysctl.d/90-connections.conf
fs.file-max = 2097152
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 32768
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 10240 65535
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_mtu_probing = 1
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
sysctl --system
sysctl net.ipv4.tcp_congestion_control

Co robi każde z nich:

  • somaxconn ogranicza kolejkę nasłuchu, a aplikacja i tak musi o nią poprosić. W nginx to listen ... backlog=65535; w większości języków to drugi argument listen().
  • ip_local_port_range ma znaczenie po stronie klienta. Proxy otwierające połączenia wychodzące do jednego celu wyczerpuje porty efemeryczne przy około dwudziestu ośmiu tysiącach przy domyślnym zakresie.
  • tcp_tw_reuse pozwala jądru ponownie wykorzystać gniazda TIMEWAIT dla nowych połączeń wychodzących. Bezpieczne. Jego kuzyn `tcptw_recycle` został usunięty z Linuksa w 4.12, a każdy poradnik, który nadal go zaleca, został napisany przed 2017 rokiem.
  • fq z bbr to realna poprawa na długich lub stratnych ścieżkach i bez różnicy na krótkich i czystych. Oba są w standardowych jądrach.

Śledzenie połączeń

Stanowy firewall daje każdemu połączeniu wpis conntrack, a tabela ma sufit. Jego osiągnięcie upuszcza pakiety i zapisuje nf_conntrack: table full do dziennika jądra.

sysctl net.netfilter.nf_conntrack_max net.netfilter.nf_conntrack_count

Podnieś go, jeśli masz pamięć — każdy wpis kosztuje kilkaset bajtów:

net.netfilter.nf_conntrack_max = 1048576

Tam, gdzie obciążenie to bezstanowa usługa publiczna, lepszą odpowiedzią jest nieśledzenie go:

table inet raw {
  chain prerouting {
    type filter hook prerouting priority raw;
    tcp dport 443 notrack
  }
}

Limity, które systemd ignoruje

/etc/security/limits.conf dotyczy logowań przez PAM. Nie ma żadnego wpływu na usługę uruchamianą przez systemd, dlatego podniesienie nofile tam i ponowne uruchomienie nginx niczego nie zmienia. Ustaw to w jednostce:

mkdir -p /etc/systemd/system/nginx.service.d
cat > /etc/systemd/system/nginx.service.d/limits.conf <<EOF
[Service]
LimitNOFILE=1048576
EOF
systemctl daemon-reload
systemctl restart nginx

Zweryfikuj względem działającej usługi, a nie pliku, który właśnie zapisałeś:

systemctl show nginx -p LimitNOFILE

Trzy rzeczy, których nie robić

  • Nie wklejaj pięćdziesięciowierszowego pliku sysctl z forum. Połowa dotyczy jądra, które nie było wydawane od dekady, a jedna linia po cichu zepsuje wykrywanie MTU ścieżki.
  • Nie podnoś tcp_rmem i tcp_wmem bez długiej i grubej ścieżki, która to uzasadnia. Na ścieżce o opóźnieniu jednej milisekundy większe bufory kupują opóźnienie i presję na pamięć.
  • Nie wyłączaj tcp_timestamps. Tracisz szacowanie czasu rundy i PAWS, a zyskujesz plotkę o wydajności.

Mierz ponownie po każdej zmianie, jedną zmianę na raz, i trzymaj plik w kontroli wersji, aby następna osoba mogła zobaczyć, co i dlaczego zrobiłeś.

Gotowi, gdy jesteś

Wybierz miasto. Wybierz rozmiar. Płać kryptowalutą.

Bez formularzy o tym, kim jesteś, bez czekania na akceptację człowieka, bez telefonu w celu weryfikacji. Faktura zostaje uregulowana, a dane logowania trafiają do Twojej skrzynki.