ضريبة المصافحة

قد يكون تكامل Magento الخاص بك بطيئاً بسبب تكلفة شبكة خفية.

قمت ذات مرة بتشغيل عملية تصدير للمنتجات تتواصل مع واجهة برمجة تطبيقات (API) للتسعير. عمل منتج واحد بسرعة، لكن الكتالوج الكامل استغرق وقتاً طويلاً جداً. كانت قاعدة البيانات الخاصة بي في حالة خمول، وأظهرت أداة تحليل الأداء (profiler) أن المشكلة تكمن في الشبكة.

كان الكود يقوم بإنشاء عميل HTTP جديد داخل حلقة تكرارية (loop).

قبل إرسال البيانات عبر HTTPS، يقوم جهازك بعمل شاق؛ حيث يقوم بإجراء مصافحة TCP لفتح مقبس (socket)، ثم يقوم بإجراء مصافحة TLS لتبادل الشهادات والتفاوض على المفاتيح. يتطلب هذا عدة رحلات ذهاب وإياب (round trips).

إذا قمت بذلك مرة واحدة، فستكون التكلفة منخفضة. أما إذا قمت بذلك داخل حلقة تكرارية لـ 40,000 منتج، فستدفع تلك التكلفة 40,000 مرة. البيانات الفعلية صغيرة، لكن عملية الإعداد هي الجزء المكلف.

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

تجنب هذا النمط في مهام cron، أو أوامر وحدة التحكم (console commands)، أو مستهلكي طوابير الرسائل (message queue consumers):

  • foreach ($products as $product) {
  • $client = new \GuzzleHttp\Client();
  • $client->post('https://api.example.com/sync', [...]);
  • }

هذا الكود يفتح اتصالاً جديداً ويجري عملية المصافحة الكاملة لكل منتج على حدة.

يحافظ Guzzle على الاتصالات حية إذا استخدمت نفس نسخة العميل (client instance). انقل العميل خارج الحلقة التكرارية:

  • $client = new \GuzzleHttp\Client(['base_uri' => 'https://api.example.com']);
  • foreach ($products as $product) {
  • $client->post('/sync', [...]);
  • }

الآن يظل المقبس وجلسة TLS مفتوحين. تقوم بإجراء المصافحة مرة واحدة ثم تقوم ببث الباقي. في Magento، قم بحقن (inject) عميل مهيأ عبر المنشئ (constructor) بدلاً من إنشائه يدوياً.

الفشل في القيام بذلك يسبب ما هو أكثر من مجرد زمن انتقال (latency). قد تنفد منك المنافذ الصادرة (outbound ports). تتراكم الاتصالات المغلقة في حالة TIME_WAIT بسرعة أكبر مما يمكن لنظام التشغيل استعادتها، مما سيؤدي إلى توقف خدمتك عن فتح مقابس جديدة تماماً.

تحقق من الكود الخاص بك بحثاً عن هذا الخطأ. قم بتشغيل هذا الأمر في الطرفية (terminal):

grep -rn "new .*Client(" app/code | grep -i http

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

Source: https://dev.to/iamrobindhiman/the-handshake-tax-reuse-your-http-client-in-magento-integrations-3kk7