فتحُ اتّصالٍ ليس مجّانًا. فبروتوكول TCP يكلّف رحلة، وTLS يكلّف أخرى، ثم بعد ذلك فقط يخرج الطلب. وعلى وصلةٍ زمنُها ٦٠ مِلّي ثانية يعني ذلك ١٢٠ مِلّي ثانية أُنفقت قبل أن يُسأل خادمُك شيئًا — لكل اتّصال.
وإبقاءُ الاتّصال حيًّا يعني: افعل ذلك مرّةً واحدة
بإبقاء الاتّصال حيًّا يعيد المتصفّح استعمال الاتّصال نفسه للملفّات العشرين التالية. وهو مفعَّل افتراضيًّا في كل خادمٍ حديث، ولهذا يدور هذا المقال في معظمه حول ألّا تكسره.
# nginx defaults, and they are sensible
keepalive_timeout 65;
keepalive_requests 1000;
تحقّق أنه عندك
curl -sSI https://yourdomain.com/ | grep -i -E 'connection|http/'
ووجودُ HTTP/2 أو HTTP/3 في سطر الحالة يعني أن إعادة الاستعمال تحدث بالفعل وليست شيئًا تضبطه — انظر HTTP/2 وHTTP/3. وأمّا Connection: close على استجابة HTTP/1.1 فهو ما يستحقّ التحقيق.
والثلاثةُ التي تكسره
- موازنُ حملٍ أو وسيطٌ قديم في المقدّمة يغلق الاتّصالات بنفسه.
- أو كتلةُ upstream مضبوطة خطأً — إذ يخاطب Nginx تطبيقك بلا مجمّع إبقاءٍ حيّ.
- أو تقديمُ الأصول من أسماء مضيفين كثيرة مختلفة، فلا يُعاد استعمال اتّصالٍ للملفّ التالي.
upstream app {
server 127.0.0.1:9000;
keepalive 32; # the pool Nginx keeps open to your app
}
location / {
proxy_http_version 1.1;
proxy_set_header Connection ""; # required, or the pool is not used
}
وتقديمُ الخطوط والصور والسكربتات من نطاقك أنت صار اليوم أسرع من مضيفٍ خارجي: الاتّصالُ نفسه، ولا نظامَ أسماءٍ إضافي، ولا تشفيرَ إضافي. وتوزيعُ الأصول على أسماء مضيفين كان نصيحةً لـHTTP/1.1 وهو اليوم كلفة.