
PHP خلقت للموت. وكل شيء سيكون على ما يرام ، لكنه لم يُمنح فرصة للقيام بذلك مؤخرًا. قبل عام ، على المحور ، تم الإعلان عن أداة RoadRunner ، مما أجبر عملية PHP على ترك دائرة الموت والقيامة التي لا تنتهي.
مبدأ عمل RoadRunner هو الحفاظ على عملية التشغيل وإلقاء الطلبات الواردة فيها ، مما يسمح ، حسب المطورين ، بزيادة أداء التطبيق (حتى 40 مرة في بعض الأحيان).
منذ أن كنت أعمل مع Magento لفترة طويلة ، بدت فكرة رائعة أن تختبر الأداة ليس في إطار أسطوري ، ولكن في تطبيق حقيقي ، عملت Magento Open Source بشكل رائع.
تكلفة تهيئة تطبيق الماجنتو
تتضمن طريقة تسريع تطبيق RoadRunner تقليل وقت الاستجابة (بعد بدء عملية الاحماء) عن طريق تقليل الحمل العام لتهيئة التطبيق.

لقطة شاشة من عرض أنتون تسيتو "تصميم تطبيقات Go / PHP الهجينة باستخدام RoadRunner"
في حالة Magento ، يقع الوقت الرئيسي الذي يقضيه عند بدء التشغيل على:
- الملحن التحميل التلقائي
- إلباس الحذاء
التحميل التلقائي للملحن لا يجذب الانتباه ، لأنه معيار لتطبيق PHP.

نتائج التنميط المتعلقة بالملحن.
يتضمن Bootstraping تطبيق Magento تهيئة معالج الأخطاء والتحقق من حالة التطبيق ، إلخ.
الجزء الأصعب هو تهيئة حاوية IoC ("ObjectManager" من حيث Magento) وإنشاء تكراري لحالات التبعية من خلاله للحصول على كائن التطبيق.

نتائج التنميط المتعلقة ب bootstraping.
تطبيق RoadRunner
لبدء RoadRunner ، تحتاج إلى إنشاء عامل يحتوي على دورة لقبول الطلبات الواردة وإرسال الردود. علاوة على ذلك ، تعمل الأداة مع الطلبات والأجوبة التي تنفذ PSR-7. من الوثائق الرسمية ، يبدو مثل هذا:
while ($req = $psr7->acceptRequest()) { $resp = new \Zend\Diactoros\Response(); $resp->getBody()->write("hello world"); $psr7->respond($resp); }
ماجنتو و PSR-7
لم تقم Magento بعد بتنفيذ PSR-7 وتستخدم أداة الاستجابة والتطبيقات الخاصة بها من خارج الصندوق ، وهي الأساليب التي يتم استخلاصها أساسًا من الإصدار السابق.
لتطبيق RoadRunner ، تحتاج إلى العثور على نقطة إدخال تقبل الطلب في بعض النماذج وإرجاع استجابة ( مثال Symfony ).
هناك مثل هذه النقطة في Magento ، \ Magento \ Framework \ AppInterface ، هناك مشكلة واحدة فقط ، لم يتم تصميم هذه الواجهة لقبول الطلب. لكن انتظر ، من أين يدخل التطبيق؟ يجدر العودة إلى البداية ، ولا يُعد المانترا - PHP ليموت . وفقًا لذلك ، فإن الغالبية العظمى من المكتبات والحزم والأطر ، عند تصميمها وتقسيمها إلى طبقات ، لا تفترض ببساطة أن الطلب يتحول إلى أكثر من واحد.
طبقة النقل Magento مبنية على نفس المبدأ. على الرغم من أن الوثائق تصف الاختلافات بين الكائنات القابلة للحقن / الجديدة ، إلا أننا في الواقع نستخدم الطلب كخدمة عامة شاملة تقوم بتهيئة نفسها من المتغيرات العامة ($ _GET ، $ _POST). بالإضافة إلى كل هذا ، يمكن رؤية حقن هذه الخدمة على جميع مستويات التطبيق في النواة نفسها ، ناهيك عن جودة الوحدات الخارجية.
بناءً على ما تقدم ، تم إنفاق الأمل في تطبيق RoadRunner فقط من خلال تحويل الطلبات من نمط PSR-7 إلى نمط Magento.
تنفيذ محول PSR-7
نقوم بصياغة المشكلة ، مع مراعاة المعلومات الواردة.
أرغب في الحصول على واجهة تطبيق معينة تقبل طلب PSR-7 وترد استجابة PSR-7. من الضروري أيضًا إنشاء تطبيق للواجهة التي تم إنشاؤها لتكييف تنسيق التفاعل هذا مع تطبيق Magento.

PSR-7 محول
كما ذكر أعلاه ، تطبيق magento يعرض بالفعل استجابة ، لذلك نحن بحاجة فقط لتحويله إلى تنسيق PSR-7.
بالنسبة للطلب ، فأنت بحاجة إلى فصل يقوم بالاتصال بجميع المكالمات إلى كائن الطلب الحالي ، والذي نضعه في سجل خاص (نعم ، سوف يغفر آلهة الهندسة المعمارية هذا الانحراف). بالإضافة إلى ذلك ، تبين أن فئة الطلب لا تستخدم فئة واحدة ، ولكن 3 ، لذلك يتطلب إعادة تسجيلها من خلال تكوين IoC للحاوية.

مجموعة من الفصول المستخدمة للعمل مع الاستفسارات في Magento
مشاكل تطبيق PHY undying
يواجه أحد التطبيقات التي يتم تشغيلها من خلال RoadRunner نفس المشكلات التي تواجه أي عملية php طويلة الأجل ، ويتم شرحها في الوثائق ( https://roadrunner.dev/docs/usage-production )
المشاكل الرئيسية لمستوى التطبيق التي يجب على المطور مراقبتها هي:
يجب إيلاء اهتمام خاص في سياق Magento لإدارة الحالة ، حيث إن التخزين المؤقت للمستخدم / المنتج / الفئة الحالية داخل الخدمة يعد نهجًا شائعًا للغاية في كل من النواة وفي وحدات الطرف الثالث.
protected function getCustomer(): ?CustomerInterface { if (!$this->customer) { if ($this->customerSession->isLoggedIn()) { $this->customer = $this->customerRepository->getById($this->customerSession->getCustomerId()); } else { return null; } } return $this->customer; }
مثال على طريقة من النواة تستخدم حالة الكائن.
تشغيل Magento Rest API Server عبر RoadRunner
نظرًا للمشاكل المحتملة مع الحالة العالمية ، استنادًا إلى تجربة تطوير الجزء الأمامي من Magento ، تم اختيار الجزء الأنسب والألم من WebApi لإطلاقه.
أول شيء فعله هو إنشاء عاملنا ، الذي سيخوض رحلة عبر RoadRunner ويعيش إلى ما لا نهاية (تقريبًا). للقيام بذلك ، خذ جزءًا من الكود من أدلة RoadRunner وأضف تطبيقنا هناك ، ملفوفًا بمحول PSR-7.
$relay = new StreamRelay(STDIN, STDOUT); $psr7 = new PSR7Client(new Worker($relay)); $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, []); $app = $bootstrap->createApplication(\Magento\Framework\App\Http::class); $psr7Application = $bootstrap->getObjectManager()->create( \Isxam\M2RoadRunner\Application\MagentoAppWrapper::class, [ 'magentoApp' => $app ] ); while ($request = $psr7->acceptRequest()) { try { $response = $psr7Application->handle($request); $psr7->respond($response); } catch (\Throwable $e) { $psr7->getWorker()->error((string)$e); } }
سيتم تنفيذ الكود قبل حلقة الوقت في بداية العامل ، كل ما هو داخل الحلقة - مع كل طلب جديد.
عندما يكون موظفنا جاهزًا ، ننتقل إلى تهيئة خادم RoadRunner المكتوب في Go. كل شيء جميل وسريع هنا ، فقط حزمة الملحن التي تقوم بتنزيل الملف القابل للتنفيذ لا تحتاج إلى تثبيت ، والتي لا يمكن أن تكون ممتعة. نحن ننشئ تكوين خادمنا - فالأبسط الذي يبدو عليه شيء من هذا القبيل.
http: address: 0.0.0.0:8086 workers: command: "php worker.php" pool: numWorkers: 1
التكوين RoadRunner.
تحتوي الوثائق على وفرة من الإعدادات التي تسمح لك بتكوين الخادم بمرونة حتى لا تتحقق الرغبة في ترجمة بياناتك الثنائية بالضبط.
./rr serve -v -d
بداية الخادم
اختبار الحل
الأدوات
للاختبار المريح ، نأخذ شيئًا بسيطًا ، على سبيل المثال artillery.io.
سنختبر الأداء بمساعدة مستخدم واحد ينفذ الاستعلامات بالتتابع (يدعم RoadRunner أيضًا تنفيذ الاستعلام في عدة سلاسل رسائل ، وسنترك هذا السؤال للباحثين الآخرين)
عند الإدخال ، لدينا ملف تهيئة المدفعية مع بيئتين - Apache و RoadRunner. كلاهما يعمل مع مثيل Magento نفسه ، لذلك هنا على قدم المساواة.
سيناريوهات الاختبار
تم استخدام السيناريوهات التالية لقياس أداء الحلين.
السيناريو 1. إنشاء فئة - name: "S1. Create category" flow: - loop: - post: url: "/rest/V1/categories" json: category: name: "name-{{prefix}}-{{ $loopCount }}" parent_id: 2 is_active: true count: 100
السيناريو 2. الحصول على قائمة البلدان - name: "S2. Countries list" flow: - loop: - get: url: "/rest/V1/directory/countries" count: 100
السيناريو 3: سرد أنواع المنتجات - name: "S3. Product types list" flow: - loop: - get: url: "/rest/V1/products/types" count: 100
السيناريو 4. الحصول على قائمة مجموعات السمات - name: "S4. Product attribute sets list" flow: - loop: - get: url: "/rest/V1/products/attribute-sets/sets/list?searchCriteria" count: 100
السيناريو 5. الحصول على فئة - name: "S5. Category get" flow: - loop: - get: url: "/rest/V1/categories/2" count: 100
السيناريو 6. إنشاء المنتج - name: "S6. Create product" flow: - loop: - post: url: '/rest/V1/products' json: product: sku: "sku-{{prefix}}-{{ $loopCount }}" name: "name-{{prefix}}-{{ $loopCount }}" attribute_set_id: 4 price: 100 type_id: "simple" count: 100
السيناريو 7. استرداد قائمة المنتجات - name: "S7. Get product list" flow: - loop: - get: url: "/rest/V1/products?searchCriteria[pageSize]=20" count: 100
يؤدي
بعد تشغيل جميع البرامج النصية بالتناوب من خلال RoadRunner و Apache ، تم الحصول على متوسطات مدة الاستعلام. وفقًا للمتوسطات ، تختلف سرعة جميع السيناريوهات تقريبًا بنفس القيمة التي تبلغ تقريبًا 50 مللي ثانية.

نتيجة اختبار الأداء.
يؤدي
أكدت التجربة العملية الافتراضات حول ثبات المكسب في أداء RoadRunner في تطبيق معين. يتيح لك استخدام هذه الأداة تسريع معالجة طلبات التطبيق للحصول على ثابت يساوي وقت التهيئة للبيئة والتبعيات.
في المعالجات الخفيفة ، يتيح لك ذلك تسريع التطبيق في بعض الأحيان ، وبصورة ثقيلة لا يكاد يكون له تأثير ملموس. إذا كان رمزك بطيئًا ، فعلى الأرجح لن يساعده الموز.
إذا كان التطبيق الخاص بك مكتوبًا جيدًا ، فلن يكون هناك على الأرجح أي مشكلة في تشغيله من خلال RoadRunner ، ولكن إذا كان التطبيق يتطلب التكيف للاستخدام مع RoadRunner ، فمن المرجح أنه كان سيتطلب الأمر نفسه دون RoadRunner لمراقبة طبقات الهندسة المعمارية بشكل أوضح واتباع معايير التنمية في هذا المجال.
Magento Open Source مناسب بشكل عام للتشغيل في بيئة معينة ، ومع ذلك ، فإنه يتطلب تحسينات على طبقة النقل وتصحيح منطق الأعمال لمنع السلوك غير الصحيح أثناء الطلبات المتكررة داخل نفس العملية. أيضًا ، يفرض استخدام RoadRunner قيودًا معينة على مناهج التطوير ، ومع ذلك ، فإنها لا تتعارض مع الممارسات الراسخة.
وأخيرا لقطة لطيفة. متى ستظل ترى طلبات Magento مع وقت الاستجابة هذا؟ مراجع
- مثال من المقال
- RoadRunner الموقع الرسمي