
لماذا يجب أن نتحدث عن إدارة الخدمات؟
مع ازدياد شعبية الإنترنت ، أصبحت بنية 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
.

سرعة المعالجة مذهلة للغاية في اختبار الضغط ab
. مع وحدة المعالجة المركزية i7 generation 8
وذاكرة 16GB
، 100000
طلب فقط استخدام 5s
. الوقت مستحيل بشكل أساسي لتحقيقه في وضع تطوير fpm
. يعد الاختبار أيضًا كافيًا لإظهار الأداء العالي والاستقرار في Swoft
.
حوكمة خدمة أنيقة
في عملية حوكمة الخدمات المصغرة ، غالبًا ما يكون تسجيل الخدمات التي يتم تشغيلها إلى مجموعات الجهات الخارجية ، مثل القنصل / etcd ، مشتركًا. يستخدم هذا الفصل مكون قنصل 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 implements ProviderInterface { private $agent; public function getList(Client $client): array {
في البيئة الموزعة ، وخاصةً النظام الموزع لبنية 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 { public function loop(): string {
تقييد التدفق ، قواطع الدارات ، خفض مستوى الخدمة يمكن التأكيد عليها مرارًا وتكرارًا لأنها مهمة حقًا. عندما لا تعمل الخدمة ، يجب كسرها. تقييد التدفق هو أداة لحماية نفسه. إذا لم تكن هناك آلية للحماية الذاتية وتلقى الاتصالات بغض النظر عن عددها ، فستتوقف الواجهة الأمامية بالتأكيد عندما تكون حركة المرور كبيرة جدًا بينما لا يمكن للجهة الخلفية التعامل مع جميع الاتصالات.
يتمثل تقييد التدفق في الحد من عدد الطلبات المتزامنة وعدد الطلبات عند الوصول إلى الموارد النادرة ، مثل السلع التي يتم بيعها بطريقة الفلاش ، وذلك لخفض الذروة بشكل فعال وتخفيف منحنى التدفق. الغرض من تقييد التدفق هو الحد من معدل الوصول المتزامن والطلبات المتزامنة ، أو الحد من سرعة الطلب خلال نافذة زمنية لحماية النظام. بمجرد الوصول إلى الحد الأقصى للسعر أو تجاوزه ، يمكن رفض الطلبات أو وضعها في قائمة الانتظار.
تستخدم الطبقة السفلية من تقييد التدفق في 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 { public function requestLimiter2(Request $request): array { $uri = $request->getUriPath(); return ['requestLimiter2', $uri]; } 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 { private $config; public function pull(): void { $data = $this->config->pull('application');
ما سبق عبارة عن سحب تكوين Apollo بسيط ، بالإضافة إلى هذه الطريقة ، يوفر Swoft-Apollo
طرقًا أكثر للاستخدام.
الرابط الرسمي