مضادات عكا: الكثير من الممثلين

الصورة

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

حدث لي أنني لم أكتب عن هذا النمط المضاد المتكرر للغاية حتى الآن. غالبًا ما يمكن العثور عليه في كود المطورين الذين بدأوا للتو في العمل مع نموذج الممثل.

هناك طريقتان للحصول على عدد كبير جدًا من الممثلين:

- تطوير نظام به أنواع مختلفة من الفاعلين ، وكثير منها غير مطلوب
- إنشاء عدد كبير جدًا من الجهات الفاعلة في وقت التشغيل عندما لا يكون ضروريًا وغير فعال

دعونا نلقي نظرة على هذه الخيارات بالتفصيل.

أنواع كثيرة جدًا من الممثلين


الفكرة العامة هي شيء من هذا القبيل: "لدينا ممثلين ، لذلك يجب أن يكون كل شيء فاعلًا."

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

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

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

هذا النهج له عيبان:

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

لذلك ، عند تصميم أنظمة فاعلة ، تحتاج إلى التفكير في ما يجب أن يكون غير متزامن في الواقع ، وهذا في الأساس:

- مكالمات إلى أنظمة خارجية (خارج jvm الخاص بك)
- مكالمات لحظر العمليات (واجهات برمجة التطبيقات القديمة والحوسبة الثقيلة ، ...)

الكثير من الجهات الفاعلة في وقت التشغيل


الفكرة العامة هي شيء من هذا القبيل: "كلما زاد عدد الفاعلين لدينا ، كلما كان كل شيء أسرع."

في الواقع ، الممثلون خفيفون ، ويمكنك تشغيل الملايين منهم في جهاز افتراضي واحد . نعم يمكنك ذلك. لكن هل هو ضروري؟

الصورة

إذا استطعت ، فهذا لا يعني أنه يجب عليك ذلك

إجابة مختصرة: ليس دائمًا - يعتمد ذلك على ما تفعله مع الممثلين.

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

ومع ذلك ، إذا كان لديك عدة أنواع من الممثلين الذين شاركوا في حساب شيء ما - على سبيل المثال ، تحليل مستند XML - فمن المشكوك فيه إنشاء الملايين من هؤلاء الممثلين (لا يهم بشكل مباشر أو من خلال جهاز توجيه).

يحتوي المعالج على عدد ثابت من النوى (مؤشرات ترابط الأجهزة) تحت تصرفه ، ويقوم ممثلو Akka بمعالجة الرسائل في ExecutionContext استنادًا إلى تجمع مؤشرات الترابط. بشكل افتراضي ، هذا هو مفترق تنفيذي مفترق على أساس ForkJoinPool المضافة في Java 7.

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

بشكل عام ، لن يعمل النظام بشكل أسرع إذا قمت بإنشاء الكثير من الممثلين.

الفاعلون عديمو الجنسية


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

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

بشكل عام: لا تستخدم الممثلين إذا لم يكن لديك دولة - فهي غير مخصصة لهذا الغرض.

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


All Articles