كيفية استخدام PHP لتنفيذ الخدمات المصغرة؟

Swoft


لماذا يجب أن نتحدث عن إدارة الخدمات؟


مع ازدياد شعبية الإنترنت ، أصبحت بنية MVC التقليدية أكثر انتفاخًا وصعبة للغاية مع استمرار توسيع نطاق التطبيقات.


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


على الرغم من أن التطبيقات المتعددة تحل مشكلة التطبيق المتضخم ، إلا أن التطبيقات مستقلة عن بعضها البعض ولا يمكن إعادة استخدام الخدمات أو الرموز الشائعة.




بالنسبة لنظام الإنترنت الكبير ، فإنه يحتوي عادةً على تطبيقات متعددة مع خدمات مشتركة ، ولكل تطبيق علاقة اتصال فيما بينها. بالإضافة إلى ذلك ، هناك تحديات أخرى لنظام الإنترنت واسع النطاق ، مثل كيفية التعامل مع المستخدمين الذين يتزايد عددهم بسرعة ، وكيفية إدارة فرق البحث والتطوير للتكرار السريع لتطوير النظام ، وكيفية الحفاظ على ترقية النظام بطريقة مستقرة ، وما إلى ذلك.


لذلك ، من أجل إعادة استخدام الخدمات بشكل جيد والحفاظ على وحدات للتوسع بسهولة. نريد فصل الخدمات عن التطبيق. لم تعد الخدمة موجودة في أحد التطبيقات ، ولكن يتم الاحتفاظ بها كخدمة منفصلة. لم يعد التطبيق نفسه مكدس وحدة منتفخة ، ولكن مكون خدمة وحدات.


Servitization


ملامح


فما هي ميزة استخدام "Servitization"؟


  • تطبيق ينقسم إلى خدمات من قبل الشركات
  • يمكن نشر الخدمة الفردية بشكل مستقل
  • يمكن مشاركة الخدمة بواسطة تطبيقات متعددة
  • الخدمات يمكن أن يكون لها اتصال بين بعضها البعض
  • بنية النظام أكثر وضوحا
  • الوحدات الأساسية مستقرة ، ويمكن أن تؤدي ترقية مكونات الخدمة في الوحدات إلى تجنب خطر حدوث إصدارات جديدة متكررة
  • سهل التطوير والإدارة
  • يمكن إجراء الصيانة من قبل فريق فردي مع تدفق عمل واضح والمسؤوليات
  • إعادة استخدام الخدمات ، إعادة استخدام الرموز
  • من السهل جدا للتوسع

التحدي المتمثل في servitization


بعد خدمة النظام ، تكون تبعية النظام معقدة ، ويزيد عدد التفاعلات بين الخدمات. في وضع تطوير fpm ، لأنه لا يمكن توفير الذاكرة المقيمة ، يجب أن يبدأ كل طلب من الصفر عن طريق البدء في تحميل عملية لإنهاء العملية ، مع إضافة الكثير من النفقات العامة غير المجدية. أيضًا ، لا يمكن إعادة استخدام اتصال قاعدة البيانات ولا يمكن حمايته لأن fpm تعتمد على العملية كما يحدد عدد عملية fpm أيضًا عدد المتزامنة. هذه هي المشاكل التي نواجهها من خلال تطوير fpm البسيط. لذلك ، هذه هي الأسباب التي تجعل Java أكثر شعبية الآن في منصة الإنترنت مقارنةً بـ .NET و PHP . بصرف النظر عن PHP non-memory resident ، وهناك العديد من القضايا الأخرى التي تحتاج إلى معالجة.


  • المزيد من الخدمات ، وأكثر تعقيدًا من إدارة التكوين
  • تبعيات الخدمة المعقدة
  • تحميل موازنة بين الخدمات
  • توسيع الخدمة
  • مراقبة الخدمة
  • تخفيض الخدمة
  • مصادقة الخدمة
  • الخدمة عبر الإنترنت وغير متصل
  • وثائق الخدمة
    ......

يمكنك تخيل الفوائد التي تجلبها لنا الذاكرة المقيمة.


  • ابدأ فقط في تهيئة إطار العمل بمجرد التركيز على معالجة الطلبات حيث يمكن تهيئة إطار العمل فقط في الذاكرة عند بدء التشغيل مرة واحدة للذاكرة المقيمة


  • تعدد إرسال الاتصال ، لا يستطيع بعض المهندسين فهم إذا لم يستخدموا تجمع الاتصالات ، فما هي نتيجة إجراء اتصالات لكل طلب؟ يؤدي الكثير من مورد الواجهة الخلفية في الاتصالات. بالنسبة لبعض الخدمات الأساسية ، مثل Redis ، وقواعد البيانات ، فإن الاتصالات تعتبر باهظة الثمن.



لذلك ، هل هناك حل جيد؟ الجواب هو نعم ، ويستخدم الكثير من الناس إطار عمل يسمى Swoft . Swoft هو إطار عمل RPC مع ميزة Service Governance . Swoft هو أول إطار للذاكرة الكاملة لـ PHP للذاكرة المقيمة في PHP ، استنادًا إلى المفهوم الأساسي لـ Spring Boot ، الاصطلاح أكبر من التكوين.


يوفر Swoft طريقة أكثر أناقة لاستخدام خدمات RPC مثل Dubbo و Swoft له أداء رائع مماثل لأداء Golang . هذه هي نتيجة اختبار الإجهاد لأداء Swoft في PC .

Swoft


سرعة المعالجة مذهلة للغاية في اختبار الضغط ab . مع وحدة المعالجة المركزية i7 generation 8 وذاكرة 16GB ، 100000 طلب فقط استخدام 5s . الوقت مستحيل بشكل أساسي لتحقيقه في وضع تطوير fpm . يعد الاختبار أيضًا كافيًا لإظهار الأداء العالي والاستقرار في Swoft .


حوكمة خدمة أنيقة


تسجيل الخدمة واكتشافها


في عملية حوكمة الخدمات المصغرة ، غالبًا ما يكون تسجيل الخدمات التي يتم تشغيلها إلى مجموعات الجهات الخارجية ، مثل القنصل / etcd ، مشتركًا. يستخدم هذا الفصل مكون قنصل swoft في إطار Swoft لتنفيذ تسجيل الخدمة واكتشافها.
Swoft
منطق التنفيذ


 <?php declare(strict_types=1); namespace App\Common; use ReflectionException; use Swoft\Bean\Annotation\Mapping\Bean; use Swoft\Bean\Annotation\Mapping\Inject; use Swoft\Bean\Exception\ContainerException; use Swoft\Consul\Agent; use Swoft\Consul\Exception\ClientException; use Swoft\Consul\Exception\ServerException; use Swoft\Rpc\Client\Client; use Swoft\Rpc\Client\Contract\ProviderInterface; /** * Class RpcProvider * * @since 2.0 * * @Bean() */ class RpcProvider implements ProviderInterface { /** * @Inject() * * @var Agent */ private $agent; /** * @param Client $client * * @return array * @throws ReflectionException * @throws ContainerException * @throws ClientException * @throws ServerException * @example * [ * 'host:port', * 'host:port', * 'host:port', * ] */ public function getList(Client $client): array { // Get health service from consul $services = $this->agent->services(); $services = [ ]; return $services; } } 

قواطع دوائر الخدمة


في البيئة الموزعة ، وخاصةً النظام الموزع لبنية microservice ، من الشائع جدًا أن يقوم أحد برامج النظام باستدعاء نظام بعيد آخر. قد تكون هذه المكالمة عن بعد عملية أخرى أو مضيفًا آخر عبر الشبكة. الفرق الأكبر بين هذه المكالمة عن بعد والمكالمة الداخلية للعملية هو أن المكالمة عن بعد قد تفشل أو تتوقف. لا استجابة حتى المهلة. والأسوأ من ذلك ، إذا كان هناك العديد من المتصلين الذين يتصلون بالخدمة الموقوفة نفسها ، فمن المحتمل جدًا أن تنتظر مهلة الخدمة بسرعة تنتشر إلى النظام الموزع بأكمله ، مما تسبب في سلسلة من ردود الفعل التي تستهلك كامل كمية كبيرة من الموارد في الأنظمة الموزعة. في النهاية ، يمكن أن يؤدي إلى شلل النظام.


تم تصميم وضع قاطع الدائرة لمنع الكوارث الناجمة عن ردود الفعل المتسلسلة التي تشبه الشلال في الأنظمة الموزعة.



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


استخدام الصمامات بسيط وقوي. يمكن @Breaker مع @Breaker . يمكن استخدام فتيل Swoft في أي سيناريو ، مثل تسمى الخدمة. يمكن تخفيضه أو عدم الاتصال به عند طلب خدمة طرف ثالث.


 <?php declare(strict_types=1); namespace App\Model\Logic; use Exception; use Swoft\Bean\Annotation\Mapping\Bean; use Swoft\Breaker\Annotation\Mapping\Breaker; /** * Class BreakerLogic * * @since 2.0 * * @Bean() */ class BreakerLogic { /** * @Breaker(fallback="loopFallback") * * @return string * @throws Exception */ public function loop(): string { // Do something throw new Exception('Breaker exception'); } /** * @return string * @throws Exception */ public function loopFallback(): string { // Do something } } 

تقييد الخدمة


تقييد التدفق ، قواطع الدارات ، خفض مستوى الخدمة يمكن التأكيد عليها مرارًا وتكرارًا لأنها مهمة حقًا. عندما لا تعمل الخدمة ، يجب كسرها. تقييد التدفق هو أداة لحماية نفسه. إذا لم تكن هناك آلية للحماية الذاتية وتلقى الاتصالات بغض النظر عن عددها ، فستتوقف الواجهة الأمامية بالتأكيد عندما تكون حركة المرور كبيرة جدًا بينما لا يمكن للجهة الخلفية التعامل مع جميع الاتصالات.


يتمثل تقييد التدفق في الحد من عدد الطلبات المتزامنة وعدد الطلبات عند الوصول إلى الموارد النادرة ، مثل السلع التي يتم بيعها بطريقة الفلاش ، وذلك لخفض الذروة بشكل فعال وتخفيف منحنى التدفق. الغرض من تقييد التدفق هو الحد من معدل الوصول المتزامن والطلبات المتزامنة ، أو الحد من سرعة الطلب خلال نافذة زمنية لحماية النظام. بمجرد الوصول إلى الحد الأقصى للسعر أو تجاوزه ، يمكن رفض الطلبات أو وضعها في قائمة الانتظار.


تستخدم الطبقة السفلية من تقييد التدفق في Swoft خوارزمية الجرافة الرمزية ، وتعتمد الطبقة الأساسية على Redis لتنفيذ قيود التدفق الموزعة.


تقييد تدفق Swoft لا يقتصر فقط على التحكم في وحدات التحكم ، ولكنه يحد أيضًا من الأساليب في أي حبة ضوئية ويتحكم في معدل الوصول للطرق. المثال التالي هو التفسير بالتفصيل.


 <?php declare(strict_types=1); namespace App\Model\Logic; use Swoft\Bean\Annotation\Mapping\Bean; use Swoft\Limiter\Annotation\Mapping\RateLimiter; /** * Class LimiterLogic * * @since 2.0 * * @Bean() */ class LimiterLogic { /** * @RequestMapping() * @RateLimiter(rate=20, fallback="limiterFallback") * * @param Request $request * * @return array */ public function requestLimiter2(Request $request): array { $uri = $request->getUriPath(); return ['requestLimiter2', $uri]; } /** * @param Request $request * * @return array */ public function limiterFallback(Request $request): array { $uri = $request->getUriPath(); return ['limiterFallback', $uri]; } } 

هذا يدعم symfony/expression-language . إذا كانت السرعة محدودة ، limiterFallback أسلوب المحدد المحدد limiterFallback .


مركز التكوين


قبل أن نتحدث عن مركز التكوين ، دعونا نتحدث عن ملف التكوين. نحن لسنا غريبين عليه. يوفر لنا القدرة على تعديل البرنامج ديناميكيًا. الاقتباس من شخص ما هو:


تعديل ديناميكي لموقف رحلة وقت تشغيل النظام!

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


بالنسبة للإصدار المستقل ، نسميه التكوين (ملف) ؛ لنظام الكتلة الموزعة ، نسميها مركز التكوين (النظام) ؛


ما هو بالضبط مركز التكوين الموزعة؟


مع تطور الأعمال وتحديث بنية الخدمة الصغيرة ، يتزايد عدد الخدمات وتكوين البرامج (مختلف الخدمات الصغيرة وعناوين الخوادم المختلفة والمعلمات المختلفة) وطريقة ملف التكوين التقليدي وطريقة قاعدة البيانات لا يمكن تلبية احتياجات المطورين في إدارة التكوين:


  • الأمان: يتبع التكوين الكود المصدري المخزن في قاعدة الشفرة ، والذي يسهل حدوث تسرب للتكوين ؛
  • في الوقت المناسب: تعديل التكوين وإعادة تشغيل الخدمة لتصبح نافذة المفعول.
  • القيود: لا يمكن دعم التعديلات الديناميكية: على سبيل المثال ، مفاتيح التبديل ، مفاتيح الوظائف ؛

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


حول مراكز التكوين الموزعة ، هناك العديد من حلول المصادر المفتوحة على الويب ، مثل:


Apollo هو مركز تكوين موزع تم تطويره بواسطة قسم إطار عمل كتريب. يمكن أن تدير مركزيا تكوين بيئات مختلفة ومجموعات مختلفة من التطبيقات. يمكن دفعها إلى نهاية التطبيق في الوقت الحقيقي بعد تعديل التكوين. إنه يحتوي على ميزات السلطة المعيارية وإدارة العمليات ، وهو مناسب لسيناريوهات تكوين وإدارة الخدمات المجهرية.


يستخدم هذا الفصل Apollo كمثال لسحب التكوين وتأمين خدمات إعادة التشغيل من مركز التكوين عن بعد. إذا لم تكن معتادًا على Apollo ، يمكنك أولاً إلقاء نظرة على Swoft extension Apollo وقراءة وثائق Apollo Official.


يستخدم هذا الفصل Apollo في Swoft كمثال. عندما يتغير تكوين Apollo ، أعد تشغيل الخدمة (http-server / rpc-server / ws-server). فيما يلي مثال على وكيل:


 <?php declare(strict_types=1); namespace App\Model\Logic; use Swoft\Apollo\Config; use Swoft\Apollo\Exception\ApolloException; use Swoft\Bean\Annotation\Mapping\Bean; use Swoft\Bean\Annotation\Mapping\Inject; /** * Class ApolloLogic * * @since 2.0 * * @Bean() */ class ApolloLogic { /** * @Inject() * * @var Config */ private $config; /** * @throws ApolloException */ public function pull(): void { $data = $this->config->pull('application'); // Print data var_dump($data); } } 

ما سبق عبارة عن سحب تكوين Apollo بسيط ، بالإضافة إلى هذه الطريقة ، يوفر Swoft-Apollo طرقًا أكثر للاستخدام.



Source: https://habr.com/ru/post/ar460855/


All Articles