مالیات دست‌دادن (The Handshake Tax)

یکپارچه‌سازی Magento شما ممکن است به دلیل یک هزینه پنهان شبکه کند باشد.

یک بار یک خروجی محصول (product export) را اجرا کردم که با یک API قیمت‌گذاری در ارتباط بود. یک محصول سریع کار کرد، اما کل کاتالوگ زمان بسیار زیادی برد. پایگاه داده من بیکار بود. پروفایلر نشان داد که مشکل از شبکه است.

کد، یک کلاینت HTTP جدید را داخل یک حلقه ایجاد می‌کرد.

قبل از اینکه داده‌ها را از طریق HTTPS ارسال کنید، ماشین شما کارهای سنگینی انجام می‌دهد. برای باز کردن یک سوکت، یک TCP handshake انجام می‌دهد. سپس برای تبادل گواهی‌ها (certificates) و مذاکره بر سر کلیدها، یک TLS handshake انجام می‌دهد. این کار چندین رفت و برگشت (round trips) نیاز دارد.

اگر این کار را یک بار انجام دهید، هزینه کم است. اما اگر این کار را داخل حلقه‌ای با ۴۰,۰۰۰ محصول انجام دهید، آن هزینه را ۴۰,۰۰۰ بار پرداخت می‌کنید. حجم داده‌های واقعی کم است، اما بخش تنظیمات (setup) بخش هزینه‌بر است.

در PHP اغلب این حس به شما دست می‌دهد که باید یک کلاینت بسازید و سپس آن را دور بیندازید. این روش برای یک درخواست وب واحد جواب می‌دهد، اما در فرآیندهای طولانی‌مدت شکست می‌خورد.

از این الگو در cron jobها، دستورات کنسول یا مصرف‌کنندگان صف پیام (message queue consumers) دوری کنید:

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

این کد برای هر محصول، یک اتصال جدید باز کرده و تمام مراحل handshake را اجرا می‌کند.

Guzzle اگر از یک نمونه (instance) کلاینت یکسان استفاده کنید، اتصالات را زنده نگه می‌دارد. کلاینت را به بیرون از حلقه منتقل کنید:

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

حالا سوکت و نشست (session) TLS باز می‌مانند. شما یک بار handshake انجام می‌دهید و بقیه را به صورت استریم (stream) ارسال می‌کنید. در Magento، به جای ساخت دستی کلاینت، یک کلاینت پیکربندی‌شده را از طریق سازنده (constructor) تزریق (inject) کنید.

عدم انجام این کار، چیزی فراتر از تأخیر (latency) ایجاد می‌کند. ممکن است پورت‌های خروجی شما تمام شوند. اتصالات بسته شده سریع‌تر از آنکه سیستم‌عامل آن‌ها را بازپس بگیرد، در وضعیت TIME_WAIT انباشته می‌شوند. سرویس شما در نهایت از باز کردن سوکت‌های جدید کاملاً باز می‌ماند.

کد خود را برای این اشتباه بررسی کنید. این دستور را در ترمینال خود اجرا کنید:

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