كيف يمكنني ضمان "البقاء على قيد الحياة" يتم إرسال نبضات القلب؟

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

سؤال

لدينا تطبيق عميل RMI مكتوب بلغة جافا، الذي يحتاج الى ارسال "البقاء على قيد الحياة" رسائل دورية إلى تطبيق ملقم. قمنا بتنفيذ هذا على أنه موضوع مستقل ضربات القلب، والذي يرسل الرسالة على قيد الحياة البقاء على الخادم، ثم ينام لمدة 15 ثانية باستخدام Thread.sleep ().

ويتم تعيين موضوع أن يكون أولوية عالية:

Thread heartbeatThread = new Thread(new HeartbeatRunnable(server));
heartbeatThread.setPriority(Thread.MAX_PRIORITY);
heartbeatThread.start();

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

واضاف لدينا Thread.yield () يدعو في بلدي موضوع الرئيسي، على الرغم من أن هذا لم يجعل المشكلة تختفي.

هل هناك أي طريقة لضمان أن يتم إرسال دقات القلب في الوقت المحدد في حين طلبي لا يزال قيد التشغيل؟

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

المحلول

ويمكنك تنفيذ خيوط وضع المستخدم في بيئة غير مترابطة من نثر متحررا وظيفة "العائد" الذاتي مكتوب في التعليمات البرمجية.

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

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

في الواقع ما يمكن أن تفعله هو وضع ماكرو في بداية كل مكالمة وظيفة، والتي لا فحص سريع على الوقت وباستدعاء الدالة ضربات القلب عند الضرورة.

و(آه، هل لديك وحدات الماكرو في جاوة لا أعتقد ذلك - ولكن تحصل على هذه الفكرة)

.

نصائح أخرى

وأنت لا تستطيع أن تضمن ذلك حقا. هل يمكن أن ترسل نبضات القلب في موضوع مختلف لمنع الوقت الذي يستغرقه لإرسال نبضات القلب التي تضاف إلى تأخير بك. كما قد يكون من المستحسن تعيين التأخير بين اثنين من دقات القلب لنصف الوقت يستخدم الخادم أن تقرر عميل ميت، أي إذا الأوقات الخادم الخاص بك من العميل بعد 15 ثانية، (تحاول) إرسال نبضات كل 7.5 ثانية.

وهذا يعتمد ما هي العملية التي تستخدم وحدة المعالجة المركزية.

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

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

ويجب تكوين عدد من "ضربات القلب غاب" أن الملقم ينتظر قبل اتخاذ قرار أن العميل غير متوفر.

وهكذا، على سبيل المثال، إذا كان الفاصل الزمني لنبض الخاص بك هو 15 ثانية، وعدد دقات القلب غاب هو 4، ثم الملقم سوف ننتظر تصل بحد أقصى 60 ثانية (1 دقيقة) قبل أن تقرر أن العميل لا يمكن الوصول إليه.

ولعل أفضل حل هو استخدام الموقت <لأ href = "http://java.sun.com/javase/6/docs/api/java/util/Timer.html#scheduleAtFixedRate(java.util.TimerTask ،٪ 20long،٪ 20long) "يختلط =" نوفولو noreferrer "> scheduleAtFixedRate . مع هذا، إذا تأخر تنفيذ واحد (والتي لا يمكن تجنبها في جاوة)، لن تتأثر المكالمات اللاحقة.

إذا كنت تريد خادم ليعلن أنه على قيد الحياة، قد يكون من الافضل تقديم مأخذ مفتوحة. على العميل الخاص بك مجرد قراءة من أن مأخذ. انها سوف منع (منذ الخادم الخاص بك لا يكتب أي شيء)، وإذا يختفي الخادم / إيقاف العميل الخاص بك سوف تحصل على IOException مشيرا إلى أن خادم مقبس / الميناء قد اختفى.

وهذا لن يكون معتمدا على الخادم توفير دقات القلب في الوقت المناسب. ويستخدم القليل من الموارد (منفذ TCP على نهاية الخدمة وبجانب أي عرض النطاق الترددي) وحان الوقت في الكشف عند الخادم (أو جهاز الخادم) يصبح غير متوفر.

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