يتجمّد موجّه أوامر تفاعلي فوق النفق لعدة ثوانٍ أثناء تنفيذ نسخ ملف، ثم يستأنف كأن شيئًا لم يحدث. التنزيل هو الشيء الوحيد الذي به مشكلة، ومع ذلك ينتظر موجّه الأوامر أيضًا، ويتعافى الاثنان في اللحظة نفسها. هذا النمط هو بصمة تدفّق موثوق واحد يحمل محادثات كثيرة، وهو يصمد أمام كل تعديل ضبط تقريبًا يجرّبه الناس أولًا.

يستحق العَرَض أن يُقرأ بعناية لأنه يشير إلى آلية لا إلى إعداد: التوقف مشترك، لذا السبب مشترك، والكائن المشترك هو الاتصال الخارجي. كل شيء آخر في السجل يبدو طبيعيًا أثناء حدوث ذلك.

العَرَض: كل شيء يتوقف في اللحظة نفسها

توقّف اتصالين داخليين معًا هو الدليل. التنزيل البطيء وموجّه الأوامر البطيء محادثتان منفصلتان في TCP بأرقام تسلسل منفصلة وحالة ازدحام منفصلة، لذا لا ينبغي أن يمسّ عطل في إحداهما الأخرى. عندما يتوقفان بالخطوة نفسها، فهناك شيء فوقهما يرتّب بايتاتهما.

ذلك الشيء هو طبقة النقل في النفق. في وضع TCP، يكتب OpenVPN الحزم المغلفة في اتصال TCP واحد إلى النظير، وعقد TCP هو تسليم تدفّق بايت واحد بالترتيب. لا تُسلَّم البايتات اللاحقة إلى التطبيق قبل المفقودة، أيًّا كانت المحادثة الداخلية التي تنتمي إليها.

لاحظ ما لا يخبرك به العَرَض. إنه لا يقول إن المسار معطوب، أو أن الخادم مثقل، أو أن التشفير بطيء. تلك تنتج أشكالًا مختلفة: إنتاجية منخفضة بانتظام، أو مهل انتهاء، أو أعطال تصيب اتجاهًا واحدًا. التوقف المشترك الذي ينتهي عند إعادة إرسال مقطع مفقود واحد هو تأثير ترتيب تحديدًا.

تدفّق بايت خارجي واحد، محادثات داخلية كثيرة

تصوّر النفق يحمل تنزيلًا وموجّه أوامر في الوقت نفسه. يُفقد مقطع من الاتصال الخارجي. قد تصل المقاطع التالية إلى المضيف المستقبِل، وستقرّها حزمة TCP المستقبِلة، لكنها لا تستطيع تسليمها إلى الأعلى حتى تُملأ الفجوة. لذلك لا يجد OpenVPN شيئًا يقرأه لموجّه الأوامر، رغم أن بايتاته وصلت منذ وقت طويل.

هذا هو حجب رأس الطابور داخل اتصال واحد، وهو لا يتطلب أن يشترك التطبيقان في اتصال داخلي. إنهما يشتركان في الخارجي، وهذا يكفي.

التأثير من الدرجة الثانية يزيد الأمر سوءًا. المرسل الداخلي الذي لا يرى إقرارًا قد يعيد إرسال بيانات تحاول الطبقة الخارجية تسليمها بالفعل. تصبح إعادة الإرسال تلك حركة نفق إضافية على مسار أثبت للتو أنه يستطيع فقدان المقاطع، فيتنافس عمل التعافي مع التعافي المهم.

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

لماذا لا يستطيع مؤقت داخلي أطول أن يساعد

رفع الحد الأدنى لمهلة إعادة الإرسال على مسار ما، بواسطة rto_min، يؤجل إعادة الإرسال المعتمدة على المؤقت لحركة TCP المولّدة محليًا التي تستخدم ذلك المسار. إنه مِقبض حقيقي بتأثير حقيقي، وهو يعالج مشكلة الدرجة الثانية لا الأولى.

ip route show
ip route show cache 2>/dev/null | head
ss -tin dst 10.70.0.1

ما لا يستطيعه هو إطلاق البايتات الخارجية خارج الترتيب، أو استعادة المقطع المفقود أسرع، أو جعل خادم التطبيق البعيد يتبنّى المؤقت نفسه. لا تزال الحزمة المستقبِلة تسلّم بالترتيب، ولا يزال المرسل في الطرف البعيد يستخدم قياسات زمن الذهاب والإياب الخاصة به.

كما أنه لا يعطّل كل آلية تعافٍ أخرى من الفقد. حيث يتطلب الفقد الحقيقي تعافيًا معتمدًا على المؤقت، يجعل الحد الأدنى الأكبر التطبيق ينتظر أطول قبل أن يتصرف، وهو عكس ما تحتاجه جلسة حساسة للكمون.

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

ما يفعله tcp-nodelay وما لا يفعله

خيار النفق الذي يعطّل التخزين المؤقت على نمط Nagle في مقبس النقل له غرض ضيق: يمنع الكتابات الصغيرة من انتظار مزيد من البيانات قبل الإرسال. وهذا يساعد الحركة التفاعلية على تجنّب تأخير إضافي على مسار سليم في ما عدا ذلك.

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

من السهل الخلط بين الاثنين لأن كليهما يوصف كإصلاح للكمون. أحدهما يزيل انتظارًا مصطنعًا أدخله التخزين المؤقت؛ والآخر يتطلب تغيير ما يضمنه النقل، وهو ما لا يفعله أي خيار مقبس.

كيف تقارن وسائل النقل بإنصاف

إذا سمح المشغّل بذلك وكانت الخدمتان موجودتين، قارن خدمة UDP وخدمة TCP تحملان الحمل نفسه عبر مسار الوصول نفسه إلى الخادم نفسه. تغيير البلد أو المزوّد أو جيل الخادم بين الاختبارين يُدخل متغيرًا سيهيمن على النتيجة.

راقب التوقف المشترك لا رقم الإنتاجية. توقف عدة تطبيقات داخلية معًا أثناء الفقد الخارجي هو الملاحظة التي تحدد حجب رأس الطابور؛ أما رقم اختبار سرعة واحد أقل فلا يحدده.

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

التحول إلى UDP يزيل التدفق الموثوق الإضافي ويترك TCP الداخلي يقوم بتعافيه بنفسه. إنه لا يعد بفقد صفري أو كمون منخفض، وستظل هناك حاجة لإصلاح وصلة رفع مشبعة أو طوابير مفرطة الحجم أو مشكلة MTU. لا تُحجز الحركة خارج النفق أبدًا خلف فجوة تسلسل النفق، رغم أنها قد تعاني عندما يشترك المساران في وصلة مزدحمة واحدة، وذلك الاختناق المشترك يستحق تحقيقًا خاصًا به بدلًا من طيّه في هذا التحقيق.

مقالات ذات صلة