قاعدة المعرفة

إعدادات kernel لعدد كبير من الاتصالات المفتوحة

قيم sysctl وحدود systemd المهمة عندما يحمل صندوق عشرات الآلاف من المقابس، وتلك المنسوخة من مشاركات المدونات القديمة التي لا تفعل شيئًا.

قِس أولاً

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

انحدار ListenOverflows يعني أن قائمة الانتظار ممتلئة وأن النواة تتجاهل المصافحات المكتملة. هذه مشكلة محددة ولها حل محدد. معظم الأعراض الأخرى لا تُحل بضبط sysctl على الإطلاق، وضبط جهاز غير مُحمَّل لا يؤدي إلا إلى نقل الفشل النهائي إلى مكان يصعب اكتشافه.

الإعدادات التي تستحق مكانها

# /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

ما يفعله كل منها:

  • somaxconn يحدد الحد الأقصى لقائمة انتظار الاستماع، وما زال لتطبيقك أن يطلبه. في nginx هذا هو listen ... backlog=65535؛ وفي معظم اللغات هو الوسيط الثاني في listen().
  • ip_local_port_range يهم في جانب العميل. الوكيل الذي يفتح اتصالات صادرة إلى وجهة واحدة يستنفد المنافذ المؤقتة عند حوالي ثمانية وعشرين ألفًا مع النطاق الافتراضي.
  • tcp_tw_reuse يتيح للنواة إعادة استخدام مآخذ TIMEWAIT لاتصالات صادرة جديدة. آمن. تمت إزالة قريبه `tcptw_recycle` من Linux في 4.12، وأي دليل لا يزال يوصي به كُتب قبل 2017.
  • fq مع bbr تحسين حقيقي على المسارات الطويلة أو المفقودة، وتأثيره محايد على المسارات القصيرة النظيفة. كلاهما في النوى القياسية.

تتبع الاتصالات

جدار الحماية المتتبع للحالة يمنح كل اتصال إدخال conntrack، وللجدول سقف. بلوغه يُسقط الحزم ويكتب nf_conntrack: table full إلى سجل النواة.

sysctl net.netfilter.nf_conntrack_max net.netfilter.nf_conntrack_count

ارفعه إذا كانت لديك الذاكرة — كل إدخال يكلف بضع مئات من البايتات:

net.netfilter.nf_conntrack_max = 1048576

حيث يكون الحمل خدمة عامة بدون حالة، الحل الأفضل هو عدم تتبعه:

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

الحدود التي يتجاهلها systemd

/etc/security/limits.conf ينطبق على تسجيلات الدخول عبر PAM. ليس له أي تأثير إطلاقًا على خدمة يبدأها systemd، ولهذا فإن رفع nofile هناك وإعادة تشغيل nginx لا يغير شيئًا. اضبطه على الوحدة:

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

تحقق من الخدمة قيد التشغيل وليس من الملف الذي كتبته للتو:

systemctl show nginx -p LimitNOFILE

ثلاثة أمور لا تفعلها

  • لا تلصق ملف sysctl بخمسين سطرًا من منتدى. نصفه يستهدف نواة لم تُصدَر منذ عقد، وسطر واحد سيكسر اكتشاف MTU للمسار بصمت.
  • لا ترفع tcp_rmem وtcp_wmem دون مسار طويل سمين يبرر ذلك. على مسار بزمن استجابة ميلي ثانية واحدة، المخازن المؤقتة الأكبر تشتري الكمون وضغط الذاكرة.
  • لا تعطّل tcp_timestamps. تخسر تقدير زمن الرحلة وPAWS، وتكسب إشاعة عن الأداء.

قِس مرة أخرى بعد كل تغيير، تغييرًا واحدًا في كل مرة، واحفظ الملف في نظام تحكم بالإصدارات حتى يرى من يأتي بعدك ما فعلت ولماذا.

جاهز عندما تكون

اختر مدينة. اختر الحجم. ادفع بالعملة الرقمية.

لا نماذج عن هويتك، ولا انتظار لموافقة بشرية، ولا مكالمة للتحقق من أي شيء. بمجرد تصفية الفاتورة، تصل بيانات الدخول إلى بريدك الإلكتروني.