Страницы

Поиск по вопросам

воскресенье, 12 января 2020 г.

Выбор альтернативного сервиса при отказе основного.

#c_sharp #wcf #очередь #cluster


Реализуем кластерное решение для wcf сервисов. Подскажите есть ли какое-нибудь проверенное
решение для проверки доступности другого сервиса и выбора альтернативного, при отказе
основного. 
Например. 
На wcf сервис приходят сообщения от клиента и он их ставит в очередь. Очередь реализовала
на отдельном сервере и отдельным сервисом. Если этот сервис с очередью выйдет из строя,
нужно отправлять сообщения на резервный сервис, определенный заранее. Есть ли какие-то
красивые решения для реализации в автоматическом режиме по средствам wcf или проверять
в коде доступность одного сервиса и так далее?
    


Ответы

Ответ 1



Про штатные средства для подобных проверок в WCF я не слышал (точнее, слышал о WS-Discovery, начиная с .NET 4.0, но не пробовал и не уверен, что оно вообще подходит). Поэтому расскажу про велосипеды. Нужно быстро узнавать о падении стороннего сервиса Суть в периодическом "пинге" сервиса. Заводите таймер/отдельный поток, который проверяет доступность сервиса. Если сервис недоступен, имеет смысл сделать дополнительные 2-3 попытки с возрастающим интервалом между ними (как и в случае со всеми остальными методами), поскольку могут быть кратковременные перебои в сети. Если в итоге сервис не отвечает, производите операцию переключения (меняете адрес сервиса на дополнительный и делаете все остальные вещи, которые могут быть с этим связаны). Повторные попытки, само собой, нужно делать при получении определенных исключений (например, CommunicationException). Контроля над сторонним сервисом нет Если сервис не предлагает специально предназначенной для проверки статуса операции (типа Ping(), Heartbeat(), CheckStatus() и т.д.), то можно запрашивать его метаданные: bool isServiceUp = true; try { string address = "http://server/Service.svc?wsdl"; var mexClient = new MetadataExchangeClient( new Uri(address), MetadataExchangeClientMode.HttpGet); mexClient.GetMetadata(); } catch (Exception e) { // если сервис недоступен, получим исключение isServiceUp = false; } Контроль над сторонним сервисом есть В сервис добавляется "проверочный" метод (Ping()/Heartbeat()/CheckStatus()). В самом простом варианте этот метод пуст, но он также может возвращать и данные о своем состоянии (особенно если внутри себя он использует несколько разных систем - БД, другой сервис и т.д.). О падении сервиса достаточно узнавать в момент его вызова В этом случае все несколько проще, потому что вам не нужно специально проверять сервис. Если при очередном вызове сервиса он не ответил, пробуете еще 2-3 раза. Если после этого сервис не ответил, производите операцию переключения и снова пробуете сделать вызов. Какой бы вариант вы не выбрали, вам понадобятся следующие блоки: код переключения сервисов (как минимум подмена одного адреса на другой) обобщенный код повтора операций, чтобы любой метод можно было вызвать как InvokeWithRetry(() => SomeMethod()) обобщенный код, который соединяет эти два блока вместе и вызывает переключение сервисов в случае необходимости

Комментариев нет:

Отправить комментарий