Как я могу гарантировать, что сердцебиение "остаться в живых" отправлено? - PullRequest
3 голосов
/ 24 марта 2009

У нас есть клиентское приложение RMI, написанное на Java, которое должно периодически отправлять сообщения «оставайся в живых» в серверное приложение. Мы реализовали это в виде отдельного потока пульса, который отправляет сообщение о том, что осталось в живых, на сервер, а затем спит в течение 15 секунд, используя Thread.sleep ().

Тема имеет высокий приоритет:

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

Однако, когда ящик, на котором работает клиент, использует много ЦП, мы обнаруживаем, что пропуски пульса пропускаются, что заставляет сервер считать, что наше клиентское приложение умерло.

Мы добавили вызовы Thread.yield () в мой основной поток, хотя это не помогло устранить проблему.

Есть ли способ гарантировать, что сердцебиение будет отправлено вовремя, пока мое приложение еще работает?

Ответы [ 6 ]

3 голосов
/ 24 марта 2009

Вы не можете действительно гарантировать это. Вы можете отправить сердцебиение в другом потоке, чтобы предотвратить добавление пульса к вашей задержке. Также может быть целесообразно установить задержку между двумя контрольными импульсами равной половине времени, которое сервер использует для определения того, что клиент мёртв, то есть, если ваш сервер блокирует ваш клиент по истечении 15 секунд, (попытайтесь) отправлять контрольные сигналы каждые 7,5 секунд.

2 голосов
/ 24 марта 2009

Зависит от того, какой процесс использует процессор.

Если это не ваш процесс, и поэтому клиентский процесс действительно не отвечает, тогда он, по сути, не является живым, поэтому нецелесообразно отправлять heartbeart. Наличие сердцебиения, которое говорит: «Я активен и могу обрабатывать сообщения», когда ящик слишком загружен, чтобы сделать это, может ввести в заблуждение.

Если в сообщении сердцебиения говорится о том, что «этот процесс запущен, но может пройти полчаса, пока я не вернусь к вам», отправьте это сообщение на сервер. Или установите тайм-аут на тот, который соответствует отзывчивости клиента.

1 голос
/ 28 марта 2009

Вы можете реализовать многопоточность в пользовательском режиме в непоточной среде, свободно разбрасывая в своем коде самописную функцию yield.

Точно так же вы можете свободно распределять вызовы функций проверки сердцебиения в своем коде. Откажитесь от потока, просто регулярно вызывайте функцию сердцебиения, которая проверяет, нужно ли отправлять сердцебиение.

Это грубое решение, но, если вы попробовали правильное решение, и оно не работает, возможно, вам стоит прибегнуть к нему.

Фактически, вы могли бы поместить макрос в начало каждого вызова функции, который быстро проверяет время и при необходимости вызывает функцию сердцебиения.

(А, у вас есть макросы на Java? Думаю, нет - но вы поняли).

1 голос
/ 24 марта 2009

Вам необходимо настроить количество «пропущенных тактовых импульсов», которое сервер ожидает, прежде чем решить, что клиент недоступен.

Так, например, если ваш интервал сердцебиения составляет 15 секунд, а количество пропущенных сердцебиений равно 4, то сервер подождет максимум 60 секунд (1 минуту), прежде чем решить, что клиент недоступен.

0 голосов
/ 24 марта 2009

Если вы хотите, чтобы сервер объявил, что он жив, вам, возможно, лучше представить открытый сокет. На вашем клиенте просто читайте из этого сокета. Он заблокируется (так как ваш сервер ничего не пишет), и если сервер исчезнет / выключится, ваш клиент получит IOException, указывающее, что сокет / порт сервера исчез.

Это не будет зависеть от того, будет ли сервер своевременно передавать пульс. Он использует мало ресурсов (порт TCP на стороне сервера и почти без полосы пропускания) и своевременно сообщает, когда сервер (или серверный компьютер) становится недоступным.

0 голосов
/ 24 марта 2009

Возможно, лучшим решением будет использование таймера scheduleAtFixedRate . При этом, если одно выполнение задерживается (чего нельзя избежать в Java), последующие вызовы не будут затронуты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...