מס ה-Handshake

האינטגרציה של Magento שלכם עשויה להיות איטית בגלל עלות רשת נסתרת.

פעם הרצתי ייצוא מוצרים שפנה ל-API של תמחור. מוצר אחד עבד מהר. הקטלוג המלא לקח נצח. מסד הנתונים שלי היה במצב idle. ה-profiler הראה שהבעיה היא הרשת.

הקוד יצר HTTP client חדש בתוך לולאה.

לפני שאתם שולחים נתונים דרך HTTPS, המכונה שלכם מבצעת עבודה כבדה. היא מבצעת TCP handshake כדי לפתוח socket. לאחר מכן היא מבצעת TLS handshake כדי להחליף תעודות ולנהל משא ומתן על מפתחות. זה דורש מספר סבבי תקשורת (round trips).

אם עושים זאת פעם אחת, העלות נמוכה. אם עושים זאת בתוך לולאה של 40,000 מוצרים, אתם משלמים את העלות הזו 40,000 פעמים. הנתונים עצמם קטנים. שלב ההקמה (setup) הוא החלק היקר.

ב-PHP לעיתים קרובות מרגישים שצריך לבנות client ולזרוק אותו. זה עובד עבור בקשת אינטרנט בודדת. זה נכשל בתהליכים ארוכי טווח (long-running processes).

הימנעו מהתבנית הזו ב-cron jobs, בפקודות קונסול (console commands) או בצרכני תור הודעות (message queue consumers):

הקוד הזה פותח חיבור חדש ומבצע handshake מלא עבור כל מוצר ומוצר.

Guzzle שומר על חיבורים פעילים אם משתמשים באותו מופע (instance) של ה-client. העבירו את ה-client אל מחוץ ללולאה:

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

כעת ה-socket וה-TLS session נשארים פתוחים. אתם מבצעים handshake פעם אחת ומזרמים (stream) את השאר. ב-Magento, הזרקו (inject) client מוגדר דרך ה-constructor שלכם במקום ליצור אותו ידנית.

אי-ביצוע פעולה זו גורם ליותר מסתם שיהוי (latency). אתם עלולים להיגמר בפורטים יוצאים (outbound ports). חיבורים סגורים מצטברים ב-TIME_WAIT מהר יותר ממה שה-OS שלכם מחזיר אותם. השירות שלכם יפסיק לפתוח sockets חדשים לחלוטין.

בדקו את הקוד שלכם כדי למצוא את הטעות הזו. הריצו את הפקודה הזו בטרמינל שלכם:

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

חפשו יצירה של client חדש שנמצאת בתוך לולאה. העבירו את ה-client אל מחוץ ללולאה. זהו שינוי של שורה אחת שמספק האצה עצומה לסנכרונים גדולים.

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