Привет!
Сегодня я хочу рассказать о том, как мы можем развернуть несколько веб сайтов в рамках одной Web Role в Azure.
Для начала я немного расскажу про контекст задачи. Есть у меня один проект который мы делаем на Azure. Проект представляет собой интернет магазин, как бы банально это не звучало. Проект разбит на две части – клиентский сайт интернет магазина и панель администратора. Каждая часть представляет из себя отдельный сайт на ASP .NET MVC. Нагрузка на сам интернет магазин будет довольно большой, но вот нагрузка на панель администратора будет минимальной. У меня стояла задача помочь клиенту немного сэкономить деньги, ведь даже 2 экземпляра размера extra small это около 30 USD в месяц. Я много раз видел, как разные люди на просторах интернета предлагают добавлять виртуальные приложения к основному веб сайту нашей роли, но мне такой вариант не понравился. В конце концов, панель администратора это не виртуальное приложение. Так что я решил рассказать, как разместить несколько сайтов в рамках одной роли.
Для размещения нескольких сайтов на одной веб роли нам необходимо:
- Модифицировать файл ServiceDefinition.csdef нашего cloud service. Нам нужно добавить сюда описание второго сайта.
- Настроить сборку cloud service таким образом, чтобы при его сборке автоматически собирался второй веб сайт.
- Скопировать собранный второй веб сайт в нужное место, для того, чтобы он попал в cloud service package.
Полностью готовый демонстрационный проект можно скачать тут (500 Kb).
Модифицируем файл ServiceDefinition.csdef нашего cloud service
Изначально файл ServiceDefinition.csdef выглядит так:
<?xml version="1.0" encoding="utf-8"?> <ServiceDefinition name="WebRoleMultipleSites.Azure" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2013-10.2.2"> <WebRole name="WebRoleMultipleSites.ClientSite" vmsize="ExtraSmall"> <Sites> <Site name="Web"> <Bindings> <Binding name="Endpoint1" endpointName="Endpoint1" /> </Bindings> </Site> </Sites> <Endpoints> <InputEndpoint name="Endpoint1" protocol="http" port="80" /> </Endpoints> <Imports> </Imports> </WebRole> </ServiceDefinition>
Давайте обратим внимание на путь ServiceDefinitionWebRoleSites. Все сайты описанные в этом контейнере будут созданы на каждом экземпляре нашей роли. Сейчас тут есть только один сайт, нам нужно добавить второй. Для начала скопируем элемент Site, а потом внесем в копию несколько корректировок.
<Site name="Admin" physicalDirectory=".Admin"> <Bindings> <Binding name="Endpoint1" endpointName="Endpoint1" hostHeader="demo-admin.testing.in.ua" /> </Bindings> </Site>
Во-первых мы изменили значение атрибута name элемента Site на Admin. Потом мы добавили атрибут physicalDirectory для элемента Site. Он указывает где нам брать скомпилированный код для нового сайта. И в завершение мы добавили атрибут hostHeader в элемент Binding, который будет использован как имя домена для привязки второго сайта.
Тут я хочу заметить, все эти параметры являются обязательными и их нельзя опускать. Оба сайта будут привязаны к одному порту, об этом нам говорит одинаковое значение атрибута endpointName у обоих сайтов, а это значит, что IIS сможет правильно перенаправлять запросы базируясь только на имени домена.
Настраиваем сборку cloud service таким образом, чтобы при её сборке автоматически собирался второй веб сайт
Тут я просто добавил зависимость построения проекта WebRoleMultipleSites.Azure от проекта WebRoleMultipleSites.AdminSite. Сделано это было следующим образом:
- Открываем Visual Studio.
- В Solution Explorer жмем правой кнопкой по нашему решению (WebRoleMultipleSites) и выбираем Project Dependencies.
- В выпадающем списке выбираем проект WebRoleMultipleSites.Azure и устанавливаем отметку напротив проекта WebRoleMultipleSites.AdminSite
Копируем собранный второй веб сайт в нужное место, для того, чтобы он попал в cloud service package
Тут я использовал слегка топорное решение так как спешил, но я уверен, что поигравшись с настройками msbuild можно будет сделать его более элегантным и я займусь этим в скором времени.
На данном этапе нам нужно добавить скрипт, который будет выполнятся перед сборкой проекта WebRoleMultipleSites.Azure. Я добавил простое копирование файлов таким образом:
xcopy $(SolutionDir)WebRoleMultipleSites.AdminSite $(TargetDir)Admin /S /I /Y /F /R
Подробнее про команду xcopy можно почитать тут.
Результат
Зайдя после публикации на сервис по RDP мы увидим 2 отдельных сайта в консоли IIS
А также мы увидим 2 отдельные папки на файловой системе
Также, если мы воспользуемся командой nslookup, то увидим, что два созданных мною имени demo-client.testing.in.ua и demo-admin.testing.in.ua это всего лишь синонимы для 2-sites-web-role.cloudapp.net
В окне браузера мы увидим следующее:
Для домена 2-sites-web-role.cloudapp.net у нас ошибка 503 по той причине, что я добавил привязку основного сайта к доменному имени demo-client.testing.in.ua, а по умолчанию этого нет.
2 thoughts on “Разворачиваем несколько веб сайтов в рамках одной веб роли”