كيفية ضمان نقل الرسائل عن طريق السحب/الاقتراع من خادم الويب

StackOverflow https://stackoverflow.com/questions/4030433

سؤال

هذا يبني على كيفية إرسال الرسائل بين الشركات. إذا قررت أن شركة S (upplier) يجب أن تصطدم أوامر من الشركة (ب) بطريقة بسيطة على أساس HTTP ما هو أفضل تطبيق.

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

ما هي أفضل ممارسة لتنفيذ مثل هذا النظام؟

هل كانت مفيدة؟

المحلول

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

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

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

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

سأفترض أن B يريد تأكيدًا بأن S قد أخذ طلبًا ، وبالتالي نحتاج إلى تحديث المعلومات في كل من B و S عند نقل الطلب.

يجب أن تقدم B خدمات مثل هذه:

 Give me the next order(s)

 I have stored {orders ...}

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

 I have stored order <65,004> please give me the next

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

نصائح أخرى

ما تبحث عنه هو التزام مرحلتين. تم وصفه جيدًا في الإنترنت ، هنا على سبيل المثال:

http://en.wikipedia.org/wiki/two-phase_commit_protocol

جوهره:

تستمر عملية الالتزام على النحو التالي:

* Phase 1
      o Each participating resource manager coordinates local 
        operations and forces all log records out:
      o If successful, respond "OK"
      o If unsuccessful, either allow a time-out or respond "OOPS" 
* Phase 2
      o If all participants respond "OK":
            * Coordinator instructs participating resource managers to "COMMIT"
            * Participants complete operation writing the log record
              for the commit 
      o Otherwise:
            * Coordinator instructs participating resource managers to "ROLLBACK"
            * Participants complete their respective local undos 

يجب أن تعمل لأي نوع من البيانات.

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

أسهل طريقة هي ، في حالتك ، بمجرد أن يتلقى الخادم طلب استطلاع ، يرسله x عدد الردود ، كل ذلك مع نفس الشيء GUID. علي سبيل المثال.

S: B, anything new?
S: B, anything new?
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
B: Yes, S, I need some shoes (order #124).
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
B: Yes, S, I need some shoes (order #124).
S: B, anything new?
B: Yes, S, I need some shoes (order #124).
S: B, anything new?
B: Yes, S, I need some shoes (order #124).
...

S قد تحصل على غير مرغوب فيه بالأوامر ، ولكن بما أن # يتم إرسالها مع كل طلب ، فهي ليست مشكلة كبيرة. إذا فاتنا ذلك من قبل ، فإننا نحصل عليه الآن. إذا لم نحصل عليه من قبل ، Woohoo! لدينا الآن. النظام يعمل! ستلاحظ ذلك B يرسل الرسائل 5 أوقات في مثالي. في سيناريو واقعي ، من المحتمل أن ترسل رسالة مئات أو آلاف المرات ، حتى تحصل على الموثوقية المطلوبة.

الآن الحل أعلاه هو المعالجة وعرض النطاق الترددي المكثف ، لكنه يعمل. طريقة أكثر ذكاءً هي القيام بما يفعله TCP: لديك مصافحة ثلاثية.

S: Hello B. Are you there? -> SYN
B: Hello S, yep I'm here. What's up? -> SYN+ACK
S: Oh good, you're there. -> ACK
S: B, anything new?
B: Yes, S, I need a jacket (order #123).

لكن .. http يفعل هذا بالفعل. لذلك إذا لم يصل شيء ما إلى مكان ما ، فستعرف. توقيت الاتصال ، اندلع الاتصال ، إلخ.

الآن ، يمكنك إعادة كتابة هذه السيناريوهات ضمن مستوى التطبيق (أدخل WS-ReliableSaging) ، ولكن TCP حقًا موثوق بالفعل. يتهمهم بعض منتقدي أطر عمل الصابون (ISH) و Paux -Protocols (وهي تعمل فوق HTTP عادةً) بإعادة اختراع العجلة بشكل أساسي - ومشاكل العجلة - على مستوى أعلى من التجريد.

خلاصة القول هي أن أي نظام يمكن أن يفشل ، بما في ذلك أنظمة المراسلة الموثوقة.

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

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

S ---> D ( Call a service which would list record keys)
D----> S ( provide xml of keys)
S----> D ( Request each of the records)
D----> S ( Submit record)

في حالة إدخال رقم قياسي جديد بعد التزامن ، يمكن للوجهة استدعاء خدمة تم نشرها في المصدر ، والتي ستتعامل مع سجل جديد.

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

هتافات!

أعتقد أنك تحاول أن تقول أن الشركة ب هي مشارك سلبي. يحتاج S (المورد) فقط إلى القدرة على الحصول على جميع الطلبات التي تنشرها (الاتساق النهائي). لكن B لا يحتاج أو يهتم بما لدى الطلبات بالفعل (لا حاجة إلى الالتزام).

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

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

قد يكون ذلك قبيحًا ، لكن يبدو أنك لا تتوقع الكثير من التعقيد من الشركة B. استخدم SSL و Auth ويتم تأمينه ومشفره.

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

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