سؤال

أقوم ببناء خط أنابيب معالجة مع NServiceBus ، لكنني أواجه مشكلة في تكوين الموزعين من أجل جعل كل خطوة في العملية قابلة للتطوير. إليك بعض المعلومات:

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

نأمل أن تكون هذه الافتراضات جيدة وإلا فأنا في مشكلة أكثر مما اعتقدت.

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

  • يحتوي عمال Nodea على معالج iHandleMessages ، ونشر Eventa
  • يحتوي عمال NodeB على معالج iHandleMessages ، ونشر الحدث ب
  • يحتوي عمال Nodec على معالج iHandleMessages ، ثم يكتمل خط الأنابيب.

فيما يلي الأجزاء ذات الصلة من ملفات التكوين ، حيث يدل # على عدد العامل ، (أي أن هناك قوائم انتظار إدخال nodea.1 و nodea.2):

NodeA:
<MsmqTransportConfig InputQueue="NodeA.#" ErrorQueue="error" NumberOfWorkerThreads="1" MaxRetries="5" />
<UnicastBusConfig DistributorControlAddress="NodeA.Distrib.Control" DistributorDataAddress="NodeA.Distrib.Data" >
    <MessageEndpointMappings>
    </MessageEndpointMappings>
</UnicastBusConfig>

NodeB:
<MsmqTransportConfig InputQueue="NodeB.#" ErrorQueue="error" NumberOfWorkerThreads="1" MaxRetries="5" />
<UnicastBusConfig DistributorControlAddress="NodeB.Distrib.Control" DistributorDataAddress="NodeB.Distrib.Data" >
    <MessageEndpointMappings>
        <add Messages="Messages.EventA, Messages" Endpoint="NodeA.Distrib.Data" />
    </MessageEndpointMappings>
</UnicastBusConfig>

NodeC:
<MsmqTransportConfig InputQueue="NodeC.#" ErrorQueue="error" NumberOfWorkerThreads="1" MaxRetries="5" />
<UnicastBusConfig DistributorControlAddress="NodeC.Distrib.Control" DistributorDataAddress="NodeC.Distrib.Data" >
    <MessageEndpointMappings>
        <add Messages="Messages.EventB, Messages" Endpoint="NodeB.Distrib.Data" />
    </MessageEndpointMappings>
</UnicastBusConfig>

وهنا الأجزاء ذات الصلة من الموزع تكوين:

Distributor A:
<add key="DataInputQueue" value="NodeA.Distrib.Data"/>
<add key="ControlInputQueue" value="NodeA.Distrib.Control"/>
<add key="StorageQueue" value="NodeA.Distrib.Storage"/>

Distributor B:
<add key="DataInputQueue" value="NodeB.Distrib.Data"/>
<add key="ControlInputQueue" value="NodeB.Distrib.Control"/>
<add key="StorageQueue" value="NodeB.Distrib.Storage"/>

Distributor C:
<add key="DataInputQueue" value="NodeC.Distrib.Data"/>
<add key="ControlInputQueue" value="NodeC.Distrib.Control"/>
<add key="StorageQueue" value="NodeC.Distrib.Storage"/>

أنا أختبر باستخدام حالتين من كل عقدة ، ويبدو أن المشكلة تظهر في الوسط في العقدة B. هناك شيءان قد يحدثان بشكل أساسي:

  1. تشير كلتا حالات العقدة B إلى أنها تشترك في Eventa ، وأيضًا أن Nodec.distrib.data@mycomputer تشترك في الحدث الذي تنشره العقدة B. في هذه الحالة ، كل شيء يعمل بشكل رائع.
  2. تشير كلتا حالتين العقدة B إلى أنها تشترك في Eventa ، ومع ذلك ، يقول أحد العمال إن nodec.distrib.data@mycomputer يشترك مرتين ، في حين أن العامل الآخر لا يذكر ذلك.

في الحالة الثانية ، التي لا يتم التحكم فيها إلا من خلال الطريقة التي يوجه الموزع رسائل الاشتراك ، إذا كانت عقدة "Overachiever" تعالج Eventa ، فكل شيء على ما يرام. إذا كان "underachiever" يعالج Eventa ، فإن نشر EventB ليس لديه مشتركين ويموت سير العمل.

لذلك ، أسئلتي:

  1. هل هذا النوع من الإعداد ممكن؟
  2. هل التكوين صحيح؟ من الصعب العثور على أي أمثلة للتكوين مع موزعين يتجاوزون إعداد ناشر واحد من المستوى الواحد/عامل 2.
  3. هل من المنطقي أن يكون لديك عملية وسيط مركزي واحد تقوم بجميع عمليات شرطي حركة المرور غير المكثفة غير المكثفة ، ويرسل فقط الرسائل إلى العمليات وراء الموزعين عندما تكون المهمة طويلة الأمد ويجب موازنة التحميل؟
    • ثم يمكن للعقد المتوازنة في التحميل ببساطة الرد على الوسيط المركزي ، وهو ما يبدو أسهل.
    • من ناحية أخرى ، يبدو ذلك على خلاف مع اللامركزية التي هي قوة nservicebus.
    • وإذا كان هذا هو الإجابة ، والحدث الذي تم تشغيله على المدى الطويل هو رد ، كيف يمكنك الاحتفاظ بالنشر الذي يتيح القابلية للاستمتاع لاحقًا على الأحداث المنشورة؟
هل كانت مفيدة؟

المحلول

المشكلة التي تواجهها هي أن العقد الخاصة بك لا ترى قائمة المشتركين في بعضها البعض. السبب في أنك تواجه هذه المشكلة هو أن تجربتك سيناريو الإنتاج (Scale-Out) في ظل ملف تعريف NServicebus الافتراضي (Lite) الذي لا يدعم التوسع ولكنه يجعل تطوير الآلة المفردة مثمرة للغاية.

لحل المشكلة ، قم بتشغيل مضيف NserviceBus باستخدام ملف تعريف الإنتاج كما هو موضح في هذه الصفحة:

http://docs.particular.net/nservicebus/hosting/nservicebus-host/profiles

سيتيح ذلك للعقد المختلفة مشاركة نفس قائمة المشتركين.

بخلاف ذلك ، فإن التكوين الخاص بك هو الصحيح.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top