Azure: взаимодействие внутри WebRole (netTcpBinding) с полными службами IIS
Мне нужно изменить некоторые параметры конфигурации на лету в проекте Windows Azure - и они должны быть изменены с помощью вызова веб-службы (обновление конфигурации приложения либо через API платформы, либо через сайт управления Azure здесь не предусмотрено).
Проект имеет несколько веб - ролей и рабочих ролей-все они должны будут знать о новой конфигурации, когда она будет изменена.
Конфигурация сохраняется в долговременном хранилище, а также кэшируется во время время выполнения в статической переменной.
Мое решение состояло в том, чтобы создать внутреннюю конечную точку (tcp) для моих ролей и использовать ее для циклического перебора всех ролей и экземпляров в этих ролях, создать клиент на лету и сообщить экземпляру о новой настройке. (в значительной степени идентично: http://msdn.microsoft.com/en-us/gg457891 )
Сначала я запустил ServiceHost в ролевой точке WebRole... и я был сбит с толку, почему все, казалось, работало нормально, когда я шагнул через коммуникации (статические переменные, где они были установлены правильно) - но когда я делал другие вызовы webservice, статическая переменная, казалось, "забыла", на что я ее установил.
Это имело место как локально, так и в промежуточной среде Azure.
В этот момент я понял, что, поскольку мы используем полный режим IIS, RoleEntryPoint и веб-службы работают в двух отдельных процессах - один в заглушке Azure, а другой в IIS.
"не проблема", - сказал я., Я просто перемещу строку кода, которая запускает ServiceHost из моей RoleEntryPoint в глобальную.asax - в этот момент ServiceHost будет запущен в том же самом процессе, что и остальная часть сайта - и статические переменные будут теми же самыми.
Вот где у меня есть проблема; это отлично работает на моей локальной машине, работающей в среде dev. Как только я развертываюсь на промежуточном этапе, я начинаю получать сообщения об ошибках, сообщающие, что канал, используемый для подключения к службе, не может быть закрыт, потому что он находится в "неисправном состоянии".
Вопрос:
- Чем отличается среда Azure от среды разработки, которая является причиной этого?
- Как я могу исправить или обойти проблему? Есть ли у кого-нибудь общие советы о том, как я должен получить более описательную ошибку?.. должен ли я включить полную диагностику wcf в Azure, чтобы получить это, или есть какой-то другой способ получить сведения об исключении?
Последующие Действия:
Через пульт дистанционного управления рабочий стол я узнал несколько интересных вещей:
-
Активация без HTTP не установлена по умолчанию на веб-ролях Azure. Я считаю, что это можно преодолеть с помощью сценария запуска:
Start /w pkgmgr / iu: WCF-NonHTTP-активация;
-
Веб-сайт, созданный в IIS веб-ролью, не имеет Сети.протокол tcp включен по умолчанию. Я также считаю, что это можно преодолеть с помощью сценария запуска:
%systemroot%system32inetsrvappcmd.приложение exe set "Имя сайта здесь" / enabledProtocols: https, http, net.tcp
У меня не было времени, чтобы сделать это полностью, поскольку крайние сроки вынудили меня временно применить некоторые обходные пути.
Некоторые полезные ссылки, связанные с этой темой:
Http://msdn.microsoft.com/en-us/magazine/cc163357.aspx
Http://forums.iis.net/t/1160443.aspx
2 ответа:
Обновление (6/27/2011):
Удивительно, но кто-то в Microsoft (чей блог я комментировал) действительно дал мне ответ на этот вопрос.Команды Azure и WCF обновили эту запись:
Ссылка содержит всю информацию, необходимую для работы с этим.
И огромное спасибо Явору Георгиеву, премьер-министру MSFT с выиграть.
Прошло довольно много времени с тех пор, как я задавал этот вопрос, и никаких ответов, так что позвольте мне оставить это:Согласно моим последующим действиям в этом посте, есть способы сделать эту работу... но они сложны и трудно реализуемы.
Для рабочих ролей netTcpBinding работает идеально. Здесь нет проблем. Идите вперед и используйте его.
Для веб-ролей у вас есть проблемы.Но netTcpBinding - это то, что вам нужно использовать для раскрытия внутренних конечных точек. Что же делать?
Хорошо, вот что я сделал:
- запустить службу привязки nettcpbinding В класса roleentrypoint, используя метод servicehost.
- создайте стандартную службу WCF в своей веб-роли с помощью SOAP / JSON / Whatever you want.
- когда вы получаете запросы через netTcpBinding, прокси-сервер их вместе со службой WCF на адаптере loopback.
- должным образом защитите свою "внутреннюю" службу WCF с помощью сертификатов клиента SSL.
Это не идеально... но это работает, и это не страшно.
Я подозреваю, что необходимость делать такие вещи не очень распространена, и я действительно не могу придумать никакой причины, по которой вам нужно было бы, кроме как динамически изменять настройки во время выполнения... а это значит, что ты не захлопываешь эти службы как сумасшедший.
Очевидно, YMMV.
У меня было жалкое время, чтобы заставить HTTP работать между экземплярами в staging, и я сдался, когда мне показалось, что мне нужно возиться с
netsh
, чтобы дать моим процессам разрешение слушать через HttpListener (блин!). Поэтому я переключился на TCP через сокеты. HTTP просто добавляет накладные расходы в сценарии передачи данных типа "Точка-точка".