Повторное подключение при отказоустойчивости TIBCO EMS для C # (TIBCO.EMS.dll)
Вопрос
У нас есть решение TIBCO EMS, которое использует встроенную систему отработки отказа сервера в среде 2-4 серверов.Если администраторы TIBCO переводят службы аварийного переключения с одного сервера EMS на другой, предполагается, что соединения будут автоматически перенесены на новый сервер на уровне обслуживания EMS.Для наших приложений на C #, использующих службу EMS, этого не происходит - наши пользовательские подключения не переносятся на новый сервер после отработки отказа, и мы не уверены, почему.
Наше приложение подключается к EMS только при запуске, поэтому, если администраторы TIBCO выполнят аварийный переход после того, как пользователи запустят наше приложение, им, пользователям, необходимо перезапустить приложение, чтобы повторно подключиться к новому серверу (наше EMS-соединение использует строку сервера, включающую все 4 производственных EMS-сервера - если первая попытка завершается неудачей, оно переходит на следующий сервер в строке и пытается снова).
Я ищу автоматизированный подход, который будет периодически пытаться повторно подключиться к EMS, если обнаружит, что соединение разорвано, но я не уверен, как лучше всего это сделать.
Есть какие-нибудь идеи?Мы используем TIBCO.EMS.dll версию 4.4.2 и .Net 2.x (приложение SmartClient)
Будем признательны за любую помощь.
Решение
Этот пост должен обобщить мои текущие комментарии и объяснить мой подход более подробно ...
Типы TIBCO 'ConnectionFactory' и 'Connection' являются тяжелыми, поточно-ориентированными типами. TIBCO предлагает вам использовать один ConnectionFactory (для каждой фабрики, настроенной для сервера) и одно соединение для каждой фабрики.
Сервер также выглядит ответственным за аварийное переключение и повторное подключение 'Connection' на месте, поэтому давайте подтвердим, что он выполняет свою работу, а затем используем эту функцию.
Создание решения на стороне клиента будет немного более сложным, чем решение проблемы с настройкой сервера или клиента. Все сеансы, которые вы создали из неуспешного соединения, необходимо создать заново (не говоря уже о производителях, потребителях и местах назначения). Нет "переподключения" или "обновить" методы любого типа. Сеансы также не поддерживают ссылку на родительское соединение.
Вам придется управлять поиском объектов подключения / сеанса и сходить с ума, заново инициализируя всех! или реализовать какой-либо обработчик событий сбоя сеанса, который может получить новое соединение и повторно подключить их.
Итак, пока давайте покопаемся и посмотрим, настроен ли клиент на получение уведомления об отказоустойчивости (руководство пользователя на стр. 292). И убедитесь, что возбужденное исключение перехвачено, содержит URL-адрес аварийного переключения и обрабатывается правильно.
Другие советы
Во-первых, да, я отвечаю на свой собственный вопрос.Однако важно отметить, что без аджмастреана я был бы никем.большое вам спасибо!
ОДИН:ConnectionFactory.SetReconnAttemptCount, SetReconnAttemptDelay, SetReconnAttemptTimeout должны быть установлены соответствующим образом.Я думаю, что значения по умолчанию повторяются слишком быстро (порядка 1/2 секунды между повторными попытками).Нашим серверам EMS может потребоваться много времени для отработки отказа из-за нехватки сетевого хранилища и т.д., Поэтому 5 повторных попыток с интервалом в 1/2 секунды - это далеко не достаточно.
ДВА:Я считаю важным включить клиент-серверное и серверно-клиентское сердцебиение.Не удалось проверить, но без них клиент может не получить уведомление о том, что сервер отключен от сети или переключается в режим отработки отказа.Это, конечно, настройка на стороне сервера для EMS.
ТРИ:вы можете отслеживать событие перехода на другой ресурс, установив Tibems.SetExceptionOnFTSwitch(значение true);а затем подключаем обработчик событий исключения.При работе в среде с одним сервером вы увидите сообщение "Соединение прервано".Однако, если вы находитесь в отказоустойчивой многосерверной среде, вы увидите следующее:"Соединение выполнило отказоустойчивое переключение на ".Строго говоря, вам не нужно это уведомление, но оно может быть полезно (особенно при тестировании).
ЧЕТЫРЕ:По-видимому, в документации EMS неясно, что переподключение соединения НЕ будет работать в среде с одним сервером.Вы должны работать в многосерверной, отказоустойчивой среде.Однако здесь есть одна хитрость.Вы можете поместить один и тот же сервер в список подключений дважды - странно, я знаю, но это работает, и это позволяет работать встроенной логике повторного подключения.
какой - то код:
private void initEMS()
{
Tibems.SetExceptionOnFTSwitch(true);
_ConnectionFactory = new TIBCO.EMS.TopicConnectionFactory(<server>);
_ConnectionFactory.SetReconnAttemptCount(30); // 30retries
_ConnectionFactory.SetReconnAttemptDelay(120000); // 2minutes
_ConnectionFactory.SetReconnAttemptTimeout(2000); // 2seconds
_Connection = _ConnectionFactory.CreateTopicConnectionM(<username>, <password>);
_Connection.ExceptionHandler += new EMSExceptionHandler(_Connection_ExceptionHandler);
}
private void _Connection_ExceptionHandler(object sender, EMSExceptionEventArgs args)
{
EMSException e = args.Exception;
// args.Exception = "Connection has been terminated" -- single server failure
// args.Exception = "Connection has performed fault-tolerant switch to <server url>" -- fault-tolerant multi-server
MessageBox.Show(e.ToString());
}
Клиентские приложения могут получать уведомления о сбое, устанавливая системное свойство tibco.tibjms.ft.switch.exception
Может быть, библиотека нуждается в этом для работы?