«1. Введение

Microsoft Azure теперь имеет довольно надежную поддержку Java.

В этом руководстве мы шаг за шагом продемонстрируем, как заставить наше приложение Spring Boot работать на платформе Azure.

2. Зависимость и конфигурация Maven

Во-первых, нам нужна подписка Azure, чтобы использовать тамошние облачные сервисы; в настоящее время мы можем зарегистрировать бесплатную учетную запись здесь.

Затем войдите на платформу и создайте субъект-службу с помощью Azure CLI:

> az login
To sign in, use a web browser to open the page \
https://microsoft.com/devicelogin and enter the code XXXXXXXX to authenticate.
> az ad sp create-for-rbac --name "app-name" --password "password"
{
    "appId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
    "displayName": "app-name",
    "name": "http://app-name",
    "password": "password",
    "tenant": "tttttttt-tttt-tttt-tttt-tttttttttttt"
}

<server>
    <id>azure-auth</id>
    <configuration>
        <client>aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa</client>
        <tenant>tttttttt-tttt-tttt-tttt-tttttttttttt</tenant>
        <key>password</key>
        <environment>AZURE</environment>
    </configuration>
</server>

Теперь мы настроим параметры аутентификации субъекта-службы Azure в файле Maven settings.xml с помощью следующего раздела. , в разделе \u003cservers\u003e:

Мы будем полагаться на приведенную выше конфигурацию проверки подлинности при загрузке нашего приложения Spring Boot на платформу Microsoft с помощью azure-webapp-maven-plugin.

<plugin>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>azure-webapp-maven-plugin</artifactId>
    <version>1.1.0</version>
    <configuration>
        <!-- ... -->
    </configuration>
</plugin>

Давайте добавим следующий плагин Maven в pom.xml:

Мы можем проверить последнюю версию здесь.

У этого плагина есть ряд настраиваемых свойств, которые будут рассмотрены в следующем введении.

3. Развертывание приложения Spring Boot в Azure

Теперь, когда мы настроили среду, давайте попробуем развернуть наше приложение Spring Boot в Azure.

@GetMapping("/hello")
public String hello() {
    return "hello azure!";
}

Наше приложение отвечает «hello azure!», когда мы обращаемся к «/hello»:

Платформа теперь поддерживает развертывание Java Web App как для Tomcat, так и для Jetty. С помощью azure-webapp-maven-plugin мы можем развернуть наше приложение непосредственно в поддерживаемых веб-контейнерах в качестве приложения по умолчанию (ROOT) или развернуть через FTP.

Обратите внимание, что поскольку мы собираемся развернуть приложение в веб-контейнерах, мы должны упаковать его в виде WAR-архива. В качестве быстрого напоминания у нас есть статья, в которой рассказывается, как развернуть Spring Boot WAR в Tomcat.

3.1. Развертывание веб-контейнера

<configuration>
    <javaVersion>1.8</javaVersion>
    <javaWebContainer>tomcat 8.5</javaWebContainer>
    <!-- ... -->
</configuration>

Мы будем использовать следующую конфигурацию для azure-webapp-maven-plugin, если мы намерены выполнить развертывание на Tomcat в экземпляре Windows:

<configuration>
    <linuxRuntime>tomcat 8.5-jre8</linuxRuntime>
    <!-- ... -->
</configuration>

Для экземпляра Linux попробуйте следующую конфигурацию: ~ ~~

<configuration>
    <authentication>
        <serverId>azure-auth</serverId>
    </authentication>
    <appName>spring-azure</appName>
    <resourceGroup>baeldung</resourceGroup>
    <!-- ... -->
</configuration>

Давайте не будем забывать об аутентификации Azure:

Когда мы развернем наше приложение в Azure, мы увидим, что оно отображается как служба приложений. Итак, здесь мы указали свойство \u003cappName\u003e, чтобы назвать службу приложений. Кроме того, служба приложений как ресурс должна храниться в контейнере группы ресурсов, поэтому также требуется \u003cresourceGroup\u003e.

> mvn clean package azure-webapp:deploy
...
[INFO] Start deploying to Web App spring-baeldung...
[INFO] Authenticate with ServerId: azure-auth
[INFO] [Correlation ID: cccccccc-cccc-cccc-cccc-cccccccccccc] \
Instance discovery was successful
[INFO] Target Web App doesn't exist. Creating a new one...
[INFO] Creating App Service Plan 'ServicePlanssssssss-bbbb-0000'...
[INFO] Successfully created App Service Plan.
[INFO] Successfully created Web App.
[INFO] Starting to deploy the war file...
[INFO] Successfully deployed Web App at \
https://spring-baeldung.azurewebsites.net
...

Теперь мы готовы нажать на курок, используя цель azure-webapp:deploy Maven, и мы увидим результат:

Теперь мы можем получить доступ к https://spring-baeldung.azurewebsites. net/hello и увидите ответ: «hello azure!».

<configuration>
    <!-- ... -->
    <appServicePlanName>ServicePlanssssssss-bbbb-0000</appServicePlanName>
</configuration>

В процессе развертывания Azure автоматически создал для нас план службы приложений. Подробные сведения о планах службы приложений Azure см. в официальном документе. Если у нас уже есть план службы приложений, мы можем установить свойство \u003cappServicePlanName\u003e, чтобы не создавать новый план:

3.2. Развертывание по FTP

<configuration>
    <authentication>
        <serverId>azure-auth</serverId>
    </authentication>
    <appName>spring-baeldung</appName>
    <resourceGroup>baeldung</resourceGroup>
    <javaVersion>1.8</javaVersion>

    <deploymentType>ftp</deploymentType>
    <resources>
        <resource>
            <directory>${project.basedir}/target</directory>
            <targetPath>webapps</targetPath>
            <includes>
                <include>*.war</include>
            </includes>
        </resource>
    </resources>
</configuration>

Для развертывания через FTP мы можем использовать конфигурацию:

В приведенной выше конфигурации мы заставляем подключаемый модуль размещать файл WAR в каталоге ${project.basedir}/target и развертывать его в Каталог веб-приложений контейнера Tomcat.

> mvn clean package azure-webapp:deploy
...
[INFO] Start deploying to Web App spring-baeldung...
[INFO] Authenticate with ServerId: azure-auth
[INFO] [Correlation ID: cccccccc-cccc-cccc-cccc-cccccccccccc] \
Instance discovery was successful
[INFO] Target Web App doesn't exist. Creating a new one...
[INFO] Creating App Service Plan 'ServicePlanxxxxxxxx-xxxx-xxxx'...
[INFO] Successfully created App Service Plan.
[INFO] Successfully created Web App.
...
[INFO] Finished uploading directory: \
/xxx/.../target/azure-webapps/spring-baeldung --> /site/wwwroot
[INFO] Successfully uploaded files to FTP server: \
xxxx-xxxx-xxx-xxx.ftp.azurewebsites.windows.net
[INFO] Successfully deployed Web App at \
https://spring-baeldung.azurewebsites.net

Предположим, что наш последний артефакт называется azure-0.1.war, после начала развертывания мы увидим следующий вывод:

Обратите внимание, что здесь мы не развертывали наше приложение в качестве веб-приложения по умолчанию. для Tomcat, поэтому мы можем получить к нему доступ только через «https://spring-baeldung.azurewebsites.net/azure-0.1/hello». Сервер ответит «привет, лазурь!» как и ожидалось.

4. Развертывание с пользовательскими настройками приложения

Большую часть времени нашему приложению Spring Boot требуется доступ к данным для предоставления услуг. Теперь Azure поддерживает такие базы данных, как SQL Server, MySQL и PostgreSQL.

Для простоты мы будем использовать MySQL в приложении в качестве источника данных, так как его конфигурация очень похожа на другие службы баз данных Azure.

4.1. Включить In-App MySQL в Azure

az group create --location japanwest --name bealdung-group
az appservice plan create --name baeldung-plan --resource-group bealdung-group --sku B1
az webapp create --name baeldung-webapp --resource-group baeldung-group \
  --plan baeldung-plan --runtime java|1.8|Tomcat|8.5

Поскольку не существует однострочного способа создания веб-приложения с включенным In-App MySQL, мы должны сначала создать веб-приложение с помощью CLI:

Затем включить MySQL в приложении на портале:

«После включения MySQL в приложении мы можем найти базу данных по умолчанию, URL-адрес источника данных и информацию об учетной записи по умолчанию в файле с именем MYSQLCONNSTR_xxx.txt в каталоге /home/data/mysql файловой системы.

4.2. Приложение Spring Boot с использованием MySQL в приложении Azure

@PostMapping("/user")
public String register(@RequestParam String name) {
    userRepository.save(userNamed(name));
    return "registered";
}

@GetMapping("/user")
public Iterable<User> userlist() {
    return userRepository.findAll();
}

Здесь для демонстрации мы создаем сущность пользователя и две конечные точки, используемые для регистрации и перечисления пользователей:

spring.datasource.url=jdbc:h2:file:~/test
spring.datasource.username=sa
spring.datasource.password=

Мы собираемся использовать базу данных H2 в нашей локальную среду и переключите ее на MySQL в Azure. Как правило, мы настраиваем свойства источника данных в файле application.properties:

<configuration>
    <authentication>
        <serverId>azure-auth</serverId>
    </authentication>
    <javaVersion>1.8</javaVersion>
    <resourceGroup>baeldung-group</resourceGroup>
    <appName>baeldung-webapp</appName>
    <appServicePlanName>bealdung-plan</appServicePlanName>
    <appSettings>
        <property>
            <name>spring.datasource.url</name>
            <value>jdbc:mysql://127.0.0.1:55738/localdb</value>
        </property>
        <property>
            <name>spring.datasource.username</name>
            <value>uuuuuu</value>
        </property>
        <property>
            <name>spring.datasource.password</name>
            <value>pppppp</value>
        </property>
    </appSettings>
</configuration>

В то время как для развертывания Azure нам нужно настроить azure-webapp-maven-plugin в \u003cappSettings\u003e:

> mvn clean package azure-webapp:deploy
...
[INFO] Start deploying to Web App custom-webapp...
[INFO] Authenticate with ServerId: azure-auth
[INFO] [Correlation ID: cccccccc-cccc-cccc-cccc-cccccccccccc] \
Instance discovery was successful
[INFO] Updating target Web App...
[INFO] Successfully updated Web App.
[INFO] Starting to deploy the war file...
[INFO] Successfully deployed Web App at \
https://baeldung-webapp.azurewebsites.net

Теперь мы можем start to deploy:

Из лога видно, что развертывание завершено.

> curl -d "" -X POST https://baeldung-webapp.azurewebsites.net/user\?name\=baeldung
registered

> curl https://baeldung-webapp.azurewebsites.net/user
[{"id":1,"name":"baeldung"}]

Давайте проверим наши новые конечные точки:

Ответ сервера говорит сам за себя. Оно работает!

5. Развертывание контейнерного приложения Spring Boot в Azure

В предыдущих разделах мы показали, как развертывать приложения в контейнерах сервлетов (в данном случае Tomcat). Как насчет развертывания в качестве автономного исполняемого jar-файла?

На данный момент нам может понадобиться контейнеризировать наше приложение Spring Boot. В частности, мы можем докеризовать его и загрузить образ в Azure.

<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>1.1.0</version>
    <configuration>
        <!-- ... -->
    </configuration>
</plugin>

У нас уже есть статья о том, как докеризировать приложение Spring Boot, но здесь мы собираемся использовать другой плагин maven: docker-maven-plugin, чтобы автоматизировать докеризацию для нас:

последнюю версию можно найти здесь.

5.1. Реестр контейнеров Azure

Во-первых, нам нужен реестр контейнеров в Azure для загрузки образа докера.

az acr create --admin-enabled --resource-group baeldung-group \
  --location japanwest --name baeldungadr --sku Basic

Итак, давайте создадим его:

> az acr credential show --name baeldungadr --query passwords[0]
{
  "additionalProperties": {},
  "name": "password",
  "value": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

Нам также понадобится информация аутентификации Container Registry, и ее можно запросить, используя:

<server>
    <id>baeldungadr</id>
    <username>baeldungadr</username>
    <password>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</password>
</server>

Затем добавьте следующую конфигурацию аутентификации сервера в Maven settings.xml :

5.2. Конфигурация подключаемого модуля Maven

<properties>
    <!-- ... -->
    <azure.containerRegistry>baeldungadr</azure.containerRegistry>
    <docker.image.prefix>${azure.containerRegistry}.azurecr.io</docker.image.prefix>
</properties>

<build>
    <plugins>
        <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>1.0.0</version>
            <configuration>
                <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
                <registryUrl>https://${docker.image.prefix}</registryUrl>
                <serverId>${azure.containerRegistry}</serverId>
                <dockerDirectory>docker</dockerDirectory>
                <resources>
                    <resource>
                        <targetPath>/</targetPath>
                        <directory>${project.build.directory}</directory>
                        <include>${project.build.finalName}.jar</include>
                    </resource>
                </resources>
            </configuration>
        </plugin>
        <!-- ... -->
    </plugins>
</build>

Давайте добавим следующую конфигурацию подключаемого модуля Maven в файл pom.xml:

В приведенной выше конфигурации мы указали имя образа докера, URL-адрес реестра и некоторые свойства, аналогичные свойствам FTP-развертывания.

FROM frolvlad/alpine-oraclejdk8:slim
VOLUME /tmp
ADD azure-0.1.jar app.jar
RUN sh -c 'touch /app.jar'
EXPOSE 8080
ENTRYPOINT [ "sh", "-c", "java -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]

Обратите внимание, что плагин будет использовать значения в \u003cdockerDirectory\u003e для поиска Dockerfile. Мы помещаем Dockerfile в каталог docker, и его содержимое:

5.3. Запуск приложения Spring Boot в экземпляре Docker

> mvn docker:build -DpushImage
...
[INFO] Building image baeldungadr.azurecr.io/azure-0.1
...
Successfully built aaaaaaaaaaaa
Successfully tagged baeldungadr.azurecr.io/azure-0.1:latest
[INFO] Built baeldungadr.azurecr.io/azure-0.1
[INFO] Pushing baeldungadr.azurecr.io/azure-0.1
The push refers to repository [baeldungadr.azurecr.io/azure-0.1]
...
latest: digest: sha256:0f0f... size: 1375

Теперь мы можем создать образ Docker и отправить его в реестр Azure:

После завершения загрузки давайте проверим реестр baeldungadr. Мы увидим образ в списке репозиториев:

Теперь мы готовы запустить экземпляр образа:

> curl http://a.x.y.z:8080/hello
hello azure!

После загрузки экземпляра мы можем получить доступ к службам, предоставляемым нашим приложением, через его публичный IP-адрес: ~~ ~

5.4. Развертывание контейнера Docker

Предположим, у нас есть реестр контейнеров, независимо от того, находится ли он в Azure, Docker Hub или в нашем частном реестре.

<configuration>
    <containerSettings>
        <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
        <registryUrl>https://${docker.image.prefix}</registryUrl>
        <serverId>${azure.containerRegistry}</serverId>
    </containerSettings>
    <!-- ... -->
</configuration>

С помощью следующей конфигурации azure-webapp-maven-plugin мы также можем развернуть наше веб-приложение Spring Boot в контейнерах:

После запуска mvn azure-webapp:deploy подключаемый модуль поможет развернуть наш архив веб-приложения на экземпляр указанного образа.

Затем мы можем получить доступ к веб-службам через IP-адрес экземпляра или URL-адрес службы приложений Azure.

6. Заключение

В этой статье мы рассказали, как развернуть приложение Spring Boot в Azure в виде развертываемого файла WAR или исполняемого файла JAR в контейнере. Несмотря на то, что мы рассмотрели большинство функций azure-webapp-maven-plugin, некоторые дополнительные возможности еще предстоит изучить. Пожалуйста, проверьте здесь для более подробной информации.