Разворачиваем несколько веб сайтов в рамках одной веб роли

Tags: azure, azure web role

Привет!

Сегодня я хочу рассказать о том, как мы можем развернуть несколько веб сайтов в рамках одной Web Role в Azure.

Для начала я немного расскажу про контекст задачи. Есть у меня один проект который мы делаем на Azure. Проект представляет собой интернет магазин, как бы банально это не звучало. Проект разбит на две части – клиентский сайт интернет магазина и панель администратора. Каждая часть представляет из себя отдельный сайт на ASP .NET MVC. Нагрузка на сам интернет магазин будет довольно большой, но вот нагрузка на панель администратора будет минимальной. У меня стояла задача помочь клиенту немного сэкономить деньги, ведь даже 2 экземпляра размера extra small это около 30 USD в месяц. Я много раз видел, как разные люди на просторах интернета предлагают добавлять виртуальные приложения к основному веб сайту нашей роли, но мне такой вариант не понравился. В конце концов, панель администратора это не виртуальное приложение. Так что я решил рассказать, как разместить несколько сайтов в рамках одной роли.

Для размещения нескольких сайтов на одной веб роли нам необходимо:

  1. Модифицировать файл ServiceDefinition.csdef нашего cloud service. Нам нужно добавить сюда описание второго сайта.
  2. Настроить сборку cloud service таким образом, чтобы при его сборке автоматически собирался второй веб сайт.
  3. Скопировать собранный второй веб сайт в нужное место, для того, чтобы он попал в 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>

Давайте обратим внимание на путь ServiceDefinition\WebRole\Sites. Все сайты описанные в этом контейнере будут созданы на каждом экземпляре нашей роли. Сейчас тут есть только один сайт, нам нужно добавить второй. Для начала скопируем элемент 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. Сделано это было следующим образом:

  1. Открываем Visual Studio.
  2. В Solution Explorer жмем правой кнопкой по нашему решению (WebRoleMultipleSites) и выбираем Project Dependencies.
  3. В выпадающем списке выбираем проект 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, а по умолчанию этого нет.

No Comments

Add a Comment

Поделиться