هل تتواصل خدمات PHP المصغرة بالهمس؟ حان وقت رفع الصوت
\n\nتخيل: لديك 15 خدمة PHP مصغرة. واحدة مسؤولة عن المصادقة، وأخرى عن المدفوعات، وثالثة عن الإشعارات. تتواصل عبر HTTP، ولكن كل أسبوع يحدث عطل: مهلات زمنية، انهيارات، طلبات مفقودة. تضيف إعادة المحاولة، قواطع الدائرة، موازنة التحميل - ويتحول الكود إلى معكرونة من منطق التواصل الشبكي.
\n\nهنا يأتي دور Service Mesh - طبقة بنية تحتية تخرج كل السحر الشبكي من كود PHP الخاص بك. لا تخف: هذا ليس سحرًا، بل بنية مدروسة. ونعم، خدمات PHP المصغرة يمكنها (ويجب عليها) استخدام Service Mesh.
\n\nما هو Service Mesh ولماذا يحتاجه مطور PHP؟
\n\nService Mesh هو مستوى مخصص من البنية التحتية لإدارة التفاعل بين الخدمات. بدلاً من كتابة منطق موازنة التحميل والتشفير والتتبع والمهلات الزمنية في كل خدمة مصغرة، تقوم بتفويض ذلك إلى وكيل جانبي (sidecar proxy) (عادةً Envoy أو Linkerd).
\n\nبالنسبة لـ PHP، هذا مهم بشكل خاص لأن:
\n- \n
- تطبيقات PHP غالبًا ما تعمل عبر FastCGI أو FPM، وإضافة منطق شبكي لكل خدمة هو عبء إضافي \n
- Service Mesh يوفر mTLS (المصادقة المتبادلة) دون تغيير الكود \n
- تحصل على لوحة تحكم موحدة لمراقبة جميع الخدمات المصغرة \n
- يمكن تطبيق قواطع الدائرة (circuit breaker) و إعادة المحاولة (retry) مباشرة على مستوى الوكيل \n
المكدس الأكثر شيوعًا هو Istio + Envoy. لكننا سننظر إليه من وجهة نظر مطور PHP.
\n\nكيف يعمل: خدمة PHP + وكيل جانبي
\n\nلنفترض أن لديك خدمة مصغرة user-service بلغة PHP. تستمع على المنفذ 9000 (FPM). بدون Service Mesh، تصل إليها مباشرة:
GET http://user-service:9000/api/users/1\n\nمع Service Mesh، يتم إضافة وكيل Envoy إلى الحاوية الخاصة بك. الآن، كل حركة المرور الواردة والصادرة تمر عبره:
\n\n┌─────────────────┐ ┌──────────────┐\n│ تطبيق PHP │ ──► │ وكيل Envoy │\n│ (user-service) │ │ (جانبي) │\n└─────────────────┘ └──────┬───────┘\n │\n ▼\n ┌──────────────┐\n │ وكيل Envoy │\n │ (خدمة أخرى) │\n └──────────────┘\n\nكود PHP الخاص بك لا يعلم بوجود الوكيل. هو فقط يرسل الطلبات إلى localhost:80 أو localhost:9000 - يقوم Envoy باعتراضها وتوجيهها وفقًا لقواعد Istio.
مثال عملي: خدمة PHP مصغرة مع Service Mesh على Istio
\n\nالخطوة 1. إعداد خدمة PHP (بدون تغييرات في الكود)
\n\nلنفترض أن لديك سكريبت PHP بسيط يعيد بيانات المستخدم:
\n\n<?php\n// user-service/index.php\n$userId = $_GET['id'] ?? 0;\n$users = [\n 1 => ['name' => 'أحمد', 'email' => 'ahmed@example.com'],\n 2 => ['name' => 'سارة', 'email' => 'sara@example.com'],\n];\n\nheader('Content-Type: application/json');\necho json_encode($users[$userId] ?? ['error' => 'المستخدم غير موجود']);\n\nقم بتغليفه في Docker:
\n\n# Dockerfile\nFROM php:8.2-fpm\nCOPY index.php /var/www/html/index.php\nCMD ["php-fpm"]\n\nكل شيء قياسي. لا توجد تغييرات لـ Service Mesh.
\n\nالخطوة 2. النشر مع وكيل جانبي في Kubernetes
\n\nأضف التعليق التوضيحي sidecar.istio.io/inject: "true" - سيقوم Istio بإدراج Envoy تلقائيًا:
\n\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: user-service\nspec:\n replicas: 2\n selector:\n matchLabels:\n app: user-service\n template:\n metadata:\n labels:\n app: user-service\n annotations:\n sidecar.istio.io/inject: "true" # <-- السطر الرئيسي\n spec:\n containers:\n - name: php\n