كل طلب HTTP يقدمه واجهة برمجة التطبيقات (API) الخاصة بك يعتمد على طبقة نقل لا يفكر فيها معظم المطورين أبدًا. لمدة 25 عامًا، كانت الإجابة هي TCP. ثم ملّت Google من انتظار تحسين TCP، وقامت ببناء بروتوكول QUIC فوق UDP، وحوّلته IETF إلى معيار. HTTP/3 هو إصدار HTTP الذي صمم للعمل عليه.
يبدو هذا وكأنه مجرد "سباكة". وهو كذلك في معظمه. لكن هذه "السباكة" تغير مدى سرعة اتصال واجهة برمجة التطبيقات الخاصة بك، وكيف تتصرف على الشبكات الخلوية المتقطعة، وكيف تتشارك الطلبات المتوازية في الاتصال. إذا كنت تقوم بتصميم أو تشغيل واجهات برمجة التطبيقات، فيجب أن تعرف ما الذي تغير وما لم يتغير، وكيف تتحقق مما تتحدث به نقاط النهاية الخاصة بك اليوم.
شيء واحد يظل ثابتًا في كل هذا: طلباتك، استجاباتك، أكواد الحالة، وحمولات JSON تبدو متطابقة على HTTP/1.1، HTTP/2، و HTTP/3. أدوات مثل Apidog تقوم بالاختبار وتصحيح الأخطاء على مستوى API، لذلك كل ما تتحقق منه بشأن سلوك نقطة النهاية يظل صحيحًا بغض النظر عن إصدار النقل الذي تتفاوض عليه بنيتك التحتية. إذا كنت قد قرأت بالفعل تفصيلنا حول ما هو HTTP/2 وكيفية اختبار واجهات برمجة تطبيقات HTTP/2، فإن هذه المقالة تستكمل من حيث انتهت تلك.
ما هو بروتوكول QUIC؟
QUIC هو بروتوكول نقل تم توحيده في RFC 9000. يعمل فوق UDP بدلاً من TCP، ويعيد بناء الميزات التي يوفرها TCP (الموثوقية، الترتيب، التحكم في الازدحام) في مساحة المستخدم، لكل دفق (stream)، مع تشفير مدمج من الحزمة الأولى.
أربعة قرارات تصميمية تحدده:
يعمل على UDP. يتم تنفيذ TCP في نواة أنظمة التشغيل والصناديق الوسيطة (middleboxes) في جميع أنحاء الإنترنت، مما يجعل تطويره شبه مستحيل. UDP هو غلاف رقيق لا يقدم ضمانات تسليم، لذلك يقوم QUIC ببناء طبقة الموثوقية الخاصة به فوقه ويمكنه شحن التحسينات كتحديثات للمكتبات بدلاً من ترقيات نظام التشغيل.
TLS 1.3 مدمج، وليس مضافًا لاحقًا. مع TCP، تكمل مصافحة TCP، ثم مصافحة TLS منفصلة فوقها. QUIC يدمجها. يتم إعداد التشفير داخل مصافحة النقل نفسها، لذلك يكون الاتصال الآمن الجديد جاهزًا بعد رحلة ذهاب وعودة واحدة. لا يوجد شيء اسمه QUIC غير مشفر.
التدفقات مستقلة. يحمل اتصال QUIC العديد من التدفقات (streams)، ويتم تسليم كل منها بشكل مستقل. الحزمة المفقودة تؤدي فقط إلى توقف التدفق الذي تنتمي إليه. هذا هو الحل لمشكلة حظر الرأس الأمامي (head-of-line blocking) في TCP، والتي سنتناولها بعد قليل.
تستمر الاتصالات رغم تغيرات الشبكة. يحدد TCP الاتصال بواسطة عنوان IP والمنفذ. إذا تغير أحدهما (الخروج من نطاق Wi-Fi، التبديل إلى 5G)، يموت الاتصال. يحدد QUIC الاتصالات بواسطة معرف اتصال بدلاً من ذلك، بحيث يمكن للعميل الانتقال إلى شبكة جديدة والحفاظ على نفس الاتصال المنطقي حيًا. لا إعادة اتصال، ولا مصافحة جديدة.
HTTP/3، المحدد في RFC 9114، هو ربط دلالات HTTP بتدفقات QUIC. نفس الأساليب، نفس الرؤوس، نفس أكواد الحالة. تنسيق سلكي مختلف، نقل مختلف.
HTTP/3 مقابل HTTP/2: ما الذي تغير عملياً
كان HTTP/2 خطوة كبيرة نحو الأمام مقارنة بـ HTTP/1.1. لقد قدم تعدد الإرسال (multiplexing)، بحيث يمكن للعديد من الطلبات مشاركة اتصال TCP واحد بدلاً من الوقوف في قائمة الانتظار أو فتح ستة مقابس متوازية. لكنه أبقى TCP تحت الغطاء، وقد خلق ذلك مشكلة لم يتمكن HTTP/2 من حلها بمفرده.
يضمن TCP التسليم المرتب لدفق بايت واحد. عندما تفقد حزمة واحدة، يحتفظ TCP بكل بايت يأتي بعدها حتى تصل إعادة الإرسال، حتى البايتات التي تنتمي إلى تدفقات HTTP/2 غير ذات صلة تمامًا. حزمة مفقودة واحدة تجمد جميع الطلبات العشرين المتعددة الإرسال على الاتصال. هذا هو حظر الرأس الأمامي (head-of-line blocking) على مستوى النقل، وعلى شبكة بها فقدان حزم، يمكن أن يجعل HTTP/2 أبطأ من HTTP/1.1 مع اتصالاته المتعددة.
يزيل HTTP/3 دفق البايت المشترك. يتم تعيين كل طلب لتدفق QUIC الخاص به مع ترتيب التسليم الخاص به. إذا فقدت حزمة تحمل التدفق 5، فإن التدفقات من 6 إلى 24 تستمر في التدفق. أخيرًا، يعمل تعدد الإرسال بالطريقة التي كانت مخططات HTTP/2 تدعيها دائمًا.
تغيرت حسابات المصافحة أيضًا:
| HTTP/2 عبر TCP+TLS 1.3 | HTTP/3 عبر QUIC | |
|---|---|---|
| إعداد اتصال جديد | 2 رحلة ذهاب وعودة (TCP + TLS) | 1 رحلة ذهاب وعودة |
| استئناف اتصال | 1 رحلة ذهاب وعودة | 0 رحلات ذهاب وعودة (0-RTT) |
| تأثير الحزمة المفقودة | يحظر جميع التدفقات | يحظر تدفقًا واحدًا |
| تبديل الشبكة (Wi-Fi إلى 5G) | يموت الاتصال، إعادة اتصال كاملة | يتم ترحيل الاتصال، ويستمر |
| التشفير | اختياري نظريًا، طبقة منفصلة | إلزامي، TLS 1.3 مدمج |
يتطلب صف 0-RTT تحذيرًا. عندما يعيد العميل الاتصال بخادم شاهده من قبل، يسمح له QUIC بإرسال بيانات التطبيق في الحزمة الأولى، قبل اكتمال المصافحة. ممتاز للتأخير. لكن بيانات 0-RTT يمكن التقاطها وإعادة تشغيلها من قبل مهاجم، لذلك يجب على الخوادم أن تقبل فقط الطلبات الثابتة (idempotent) في 0-RTT. طلب GET معاد تشغيله غير ضار. لكن طلب POST معاد تشغيله يقوم بخصم بطاقة ائتمان ليس كذلك. إذا قمت بتمكين 0-RTT على حافتك، فتأكد من استبعاد مكالمات API غير الثابتة، أو تأكد من أن شبكة CDN الخاصة بك تقوم بذلك نيابة عنك.
ماذا يعني HTTP/3 لواجهات برمجة التطبيقات الخاصة بك
لا تكون ترقيات البروتوكول مهمة إلا إذا غيرت شيئًا يمكن قياسه. إليك حيث يحدث HTTP/3 فرقًا في حركة مرور API، وحيث لا يحدث.
يصبح إعداد الاتصال أقل تكلفة
يقضي العميل المتنقل النموذجي على اتصال بزمن انتقال دائري (RTT) يبلغ 60 مللي ثانية حوالي 120 مللي ثانية على إعداد TCP+TLS قبل أن يغادر أول طلب API الجهاز حتى. يقلل HTTP/3 ذلك إلى حوالي 60 مللي ثانية، وما يقرب من الصفر عند الاستئناف. بالنسبة لواجهة برمجة تطبيقات تُستدعى من تطبيق جوال يفتح اتصالات جديدة بشكل متكرر (تشغيل بارد، استيقاظ الخلفية، جلسات قصيرة الأمد)، فإن التوفير يتحقق في كل طلب من هذه الطلبات الأولى. بالنسبة لتكامل من خادم إلى خادم يحافظ على مجموعة اتصالات دافئة، يتم استهلاك وقت المصافحة إلى درجة اللاأهمية ولن تلاحظ شيئًا.
يتوقف العملاء المتنقلون عن قطع الاتصالات
تعد هجرة الاتصال هي الميزة الخفية لفرق API. يبدأ المستخدم طلبًا على شبكة Wi-Fi في المكتب، ثم يسير إلى المصعد، وينتقل الهاتف إلى الشبكة الخلوية. عبر TCP، يفشل هذا الطلب الجاري وتدخل منطق إعادة المحاولة من جانب العميل (لديك منطق إعادة المحاولة، أليس كذلك؟) مع إعادة اتصال كاملة. عبر QUIC، يتبع الاتصال الجهاز إلى الشبكة الجديدة. عدد أقل من أخطاء المهلة في سجلات عميلك، وعدد أقل من عمليات الكتابة غير المكتملة التي يجب التفكير فيها.
تعدد الإرسال بدون نمط الفشل
بالنسبة لواجهات برمجة تطبيقات REST، فإن إصلاح حظر الرأس الأمامي (HOL) مهم بشكل خاص عندما يطلق العميل العديد من الطلبات بالتوازي: لوحة تحكم تقوم بتحديث 15 ويدجت، أو محرك مزامنة يدفع مجموعة من التحديثات. على شبكة نظيفة، يعمل HTTP/2 و HTTP/3 بنفس الكفاءة تقريبًا. أضف فقدان حزم بنسبة 1-2٪ (شبكة Wi-Fi مزدحمة في مؤتمر، شبكة خلوية في مترو الأنفاق)، وسيحافظ HTTP/3 على استقلالية الطلبات المتوازية بينما يوقفها HTTP/2 بالتزامن.
gRPC يبقى في الغالب على HTTP/2 في الوقت الحالي
gRPC مرتبط بـ HTTP/2 حسب التصميم؛ يعتمد عقده السلكي على تأطير (framing) HTTP/2 ومذيلاته (trailers). لم يقم نظام gRPC البيئي بتوحيد خرائط HTTP/3، ولا تقدمه تطبيقاته الرئيسية (Go، Java، Python، Node). يمكن لخادم Kestrel في .NET أن يقدم gRPC عبر HTTP/3 كقدرة تجريبية، ولكن اعتبر ذلك استثناءً. إذا كانت بنيتك تعتمد على gRPC و HTTP/2 لأداء واجهات برمجة التطبيقات الداخلية، فإن ترحيل HTTP/3 ليس شيئًا تحتاج إلى التخطيط له هذا العام.
التدفق وحركة المرور في الوقت الفعلي
تعمل أحداث المرسل من الخادم (Server-Sent Events) عبر HTTP/3 دون تغيير، نظرًا لأن SSE هي استجابة HTTP عادية طويلة الأمد. تُعد WebSockets أكثر تعقيدًا: تم تصميم ترقية WebSocket لـ TCP، ويفتقر نظيرها في HTTP/3 (RFC 9220، بالإضافة إلى واجهة برمجة تطبيقات WebTransport الناشئة) إلى دعم شامل. إذا كنت توازن بين WebSockets مقابل HTTP العادي لميزة في الوقت الفعلي، فلا ينبغي أن تكون توفر HTTP/3 هو الدافع للقرار بعد.
الجزء الصادق: متى لن يساعد HTTP/3
معظم مشكلات تأخير API لا علاقة لها ببروتوكول النقل. إذا استغرقت نقطة النهاية الخاصة بك 400 مللي ثانية بسبب استعلام قاعدة بيانات غير مفهرس، سيقوم HTTP/3 بتسليم تلك الاستجابة البطيئة قبل 60 مللي ثانية. يهيمن التخزين المؤقت، وتصميم الحمولة، واستعلامات N+1، وإعادة استخدام الاتصال على أداء API في العالم الحقيقي، ويجب عليك استنفاذ هذه الأمور قبل التفكير في النقل. سيؤدي اختبار أداء API المنظم عادةً إلى تحقيق مكاسب أكبر بعشرة أضعاف من ترقية البروتوكول.
يتألق HTTP/3 في ظروف محددة:
- روابط ذات زمن انتقال عالٍ، حيث يؤدي توفير رحلات ذهاب وعودة إلى مكسب ثابت في النسبة المئوية.
- شبكات بها فقدان حزم، حيث يزداد تأثير التخلص من حظر الرأس الأمامي.
- العملاء المتنقلون الذين يغيرون الشبكات في منتصف الجلسة.
- العديد من الاتصالات القصيرة بدلاً من عدد قليل من الاتصالات الطويلة.
بالنسبة لواجهة برمجة تطبيقات JSON نموذجية تستخدمها الخوادم في نفس المنطقة عبر شبكات موثوقة، يكون الفرق قابلاً للقياس في المعايير وغير مرئي للمستخدمين. ملاحظتان عمليتان أخريان: يتم حظر منفذ UDP 443 في بعض شبكات الشركات (يتراجع العملاء تلقائيًا إلى HTTP/2، لذلك لا يتعطل شيء)، ويكلف تشفير QUIC في مساحة المستخدم حاليًا المزيد من وحدة المعالجة المركزية للخادم لكل اتصال مقارنة بـ TCP Kernel المُعدل.
الدعم الحالي: من يتحدث HTTP/3 اليوم
التبني أوسع مما يعتقده معظم مطوري الواجهة الخلفية:
- المتصفحات: Chrome، Edge، Firefox، و Safari جميعها تدعم HTTP/3 وتم تمكينه افتراضيًا.
- شبكات CDN والحواف: Cloudflare، Fastly، Akamai، و CloudFront تدعمه؛ على Cloudflare هو مجرد خيار تفعيل. بالنسبة لمعظم الفرق، هذا هو المسار العملي: إنهاء HTTP/3 عند الحافة، والحفاظ على HTTP/1.1 أو HTTP/2 من الحافة إلى المصدر.
- الخوادم: أضاف Nginx دعمًا تجريبيًا لـ HTTP/3 في الإصدار 1.25 باستخدام
listen 443 quic;. يقوم Caddy بتمكينه افتراضيًا. يدعمه LiteSpeed و HAProxy. لا يدعمه Apache httpd. - بيئات التشغيل (Runtimes): لا يدعم Node.js خادم HTTP/3 مدمجًا مستقرًا، وهذا سبب آخر يجعل الإنهاء عند الحافة هو النشر الشائع.
- curl: يدعمه مع العلامة
--http3عند بنائه مقابل مكدس TLS يدعم HTTP/3؛ راجع وثائق curl HTTP/3 لمعرفة الإصدارات التي تتضمنه.
كيف تتحقق مما إذا كانت واجهة برمجة التطبيقات الخاصة بك تقدم HTTP/3
يتم الاكتشاف من خلال رأس الاستجابة Alt-Svc. يقوم الخادم الذي يعلن عن HTTP/3 بالرد على طلبك الأول (HTTP/2) بشيء مثل:
alt-svc: h3=":443"; ma=86400
يخبر هذا العميل: هذه الخدمة نفسها متاحة عبر HTTP/3 على منفذ UDP 443 لمدة الـ 24 ساعة القادمة. تحقق من ذلك باستخدام curl:
curl -sI https://www.cloudflare.com | grep -i alt-svc
# alt-svc: h3=":443"; ma=86400
لإجراء الطلب عبر HTTP/3 مباشرة (يتطلب إصدار curl يدعم HTTP/3):
curl --http3 -I https://cloudflare-quic.com
# HTTP/3 200
يبلغ سطر الحالة عن HTTP/3 بدلاً من HTTP/2. في أدوات مطوري Chrome (Chrome DevTools)، افتح علامة تبويب الشبكة (Network)، انقر بزر الفأرة الأيمن على رأس العمود، وقم بتمكين عمود البروتوكول (Protocol)، وابحث عن h3 بجوار استدعاءات واجهة برمجة التطبيقات الخاصة بك. في الإنتاج، أضف البروتوكول المتفاوض عليه إلى سجلات الوصول الخاصة بك؛ يخبرك الفرق بين حركة مرور h2 و h3 بعدد عملائك الذين يستفيدون من الميزة.
بينما تتحقق من النقل، تحقق من السلوك أيضًا. وجه Apidog إلى نفس نقاط النهاية وتأكد من أكواد الحالة ومخططات الاستجابة وميزانيات التأخير. مكاسب مستوى النقل لا قيمة لها إذا كان عقد API الأساسي معطلًا، وفحوصات العقد هي بالضبط الطبقة التي لا يمكن لتغيير البروتوكول أن ينقذك فيها. قم بتنزيل Apidog مجانًا وقم بتشغيل نفس مجموعة الاختبار قبل وبعد تفعيل HTTP/3 على حافتك؛ الفرق في أوقات الاستجابة على شبكات الجوال هو إجابتك الواقعية، وليس عناوين المعايير.
الأسئلة الشائعة
هل HTTP/3 أسرع من HTTP/2؟
على الشبكات النظيفة ذات زمن الانتقال المنخفض: بالكاد. على الشبكات ذات فقدان الحزم أو زمن الانتقال العالي: نعم، غالبًا بشكل ملحوظ، لأن HTTP/3 يوفر رحلة ذهاب وعودة للمصافحة، ولم تعد الحزمة المفقودة الواحدة تعيق كل طلب متعدد الإرسال. قم بالقياس باستخدام ملف تعريف حركة المرور الخاص بك قبل إعلان الفوز. وتذكر أن HTTP/2 يظل ممتازًا؛ إذا واجهت أخطاء اتصال هناك، فعادةً ما تكون مشكلات على مستوى TLS مثل مشكلة SSLV3_ALERT_HANDSHAKE_FAILURE بدلاً من قيود البروتوكول.
هل يستخدم HTTP/3 بروتوكول TCP؟
لا. يعمل HTTP/3 على QUIC، والذي يعمل على UDP، عادةً عبر المنفذ 443. يعيد QUIC تنفيذ الموثوقية والترتيب والتحكم في الازدحام التي كان TCP يوفرها، ولكن لكل تدفق وفي مساحة المستخدم. إذا تم حظر UDP 443 على شبكة ما، فإن العملاء يتراجعون تلقائيًا إلى HTTP/2 عبر TCP.
هل أحتاج إلى تغيير كود API الخاص بي من أجل HTTP/3؟
تقريبًا لا. دلالات HTTP لم تتغير: نفس الأساليب، الرؤوس، أكواد الحالة، والهيئات. العمل يكمن في البنية التحتية (تمكينه في شبكة توصيل المحتوى CDN، موازن التحميل، أو الخادم) بالإضافة إلى فحص تصميم واحد: تأكد من تقييد البيانات المبكرة لـ 0-RTT على الطلبات المستقرة (idempotent requests).
هل يمكنني استخدام gRPC عبر HTTP/3؟
غالبًا لا، في الوقت الحالي. تنسيق gRPC السلكي مرتبط بـ HTTP/2، ومكتبات gRPC السائدة لا تقدم نقل HTTP/3. يدعم .NET ذلك بشكل تجريبي. حافظ على خدمات gRPC على HTTP/2 واعتمد HTTP/3 حيث يؤتي ثماره أولاً: نقاط نهاية REST العامة الموجهة للمتصفح والجوال.
