練習 - 將 Java EE (Jakarta EE) 應用程式部署到 Azure App Service 上的 JBoss EAP
在本練習中,您會將 Java EE (Jakarta EE) 應用程式部署到 Azure App Service 上的 JBoss EAP。 您使用 Maven 外掛程式來設定專案、編譯和部署應用程式,以及設定資料來源。
設定應用程式搭配適用於 Azure App Service 的 Maven 外掛程式
讓我們透過在適用於 Azure App Service 的 Maven 外掛程式中執行設定目標,以設定應用程式。
./mvnw com.microsoft.azure:azure-webapp-maven-plugin:2.9.0:config
重要
如果您變更了 MySQL 伺服器的區域,應該也變更為 Java EE 應用程式伺服器的相同區域,將延遲降至最低。
在命令中,針對 [JAVA 版本] 選取 [JAVA 11],並針對執行階段堆疊選取 JBoss EAP 7.2。
Input 元素 | 值 |
---|---|
Available subscriptions: |
Your appropriate subsctioption |
Choose a Web Container Web App [\<create\>]: |
1: <create> |
Define value for OS [Linux]: |
Linux |
Define value for javaVersion [Java 17]: |
2: Java 11 |
Define value for runtimeStack: |
1: Jbosseap 7 |
Define value for pricingTier [P1v3]: |
P1v3 |
Confirm (Y/N) [Y]: |
Y |
執行命令之後,您會在終端中看到類似下列訊息:
$ ./mvnw com.microsoft.azure:azure-webapp-maven-plugin:2.9.0:config
[INFO] Scanning for projects...
[INFO]
[INFO] ---------< com.microsoft.azure.samples:jakartaee-app-on-jboss >---------
[INFO] Building jakartaee-app-on-jboss 1.0-SNAPSHOT
[INFO] --------------------------------[ war ]---------------------------------
[INFO]
[INFO] --- azure-webapp-maven-plugin:2.5.0:config (default-cli) @ jakartaee-app-on-jboss ---
[WARNING] The POM for com.microsoft.azure.applicationinsights.v2015_05_01:azure-mgmt-insights:jar:1.0.0-beta is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details
[INFO] Auth type: OAUTH2
Username: YOUR_EMAIL_ADDRESS@microsoft.com
Available subscriptions:
[INFO] Subscription: YOUR_SUBSCRIPTION(********-****-****-****-************)
[INFO] It may take a few minutes to load all Java Web Apps, please be patient.
Web Container Web Apps in subscription Microsoft Azure Internal Billing-CDA:
* 1: <create>
2: jakartaee-app-on-jboss-yoshio (linux, jbosseap 7.2-java8)
Please choose a Web Container Web App [<create>]:
Define value for OS [Linux]:
* 1: Linux
2: Windows
3: Docker
Enter your choice:
Define value for javaVersion [Java 8]:
* 1: Java 8
2: Java 11
Enter your choice:
Define value for runtimeStack:
1: Jbosseap 7.2
2: Jbosseap 7
* 3: Tomcat 8.5
4: Tomcat 9.0
Enter your choice: 1
Define value for pricingTier [P1v3]:
1: P3v3
2: P2v3
* 3: P1v3
Enter your choice:
Please confirm webapp properties
Subscription Id : ********-****-****-****-************
AppName : jakartaee-app-on-jboss-1625038814881
ResourceGroup : jakartaee-app-on-jboss-1625038814881-rg
Region : westeurope
PricingTier : P1v3
OS : Linux
Java : Java 8
Web server stack: Jbosseap 7.2
Deploy to slot : false
Confirm (Y/N) [Y]:
[INFO] Saving configuration to pom.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:43 min
[INFO] Finished at: 2021-06-30T16:40:47+09:00
[INFO] ------------------------------------------------------------------------
$
命令完成後,您可以看到 Maven pom.xml
檔案中新增了下列項目。
<build>
<finalName>ROOT</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-webapp-maven-plugin</artifactId>
<version>2.9.0</version>
<configuration>
<schemaVersion>v2</schemaVersion>
<resourceGroup>jakartaee-app-on-jboss-1625038814881-rg</resourceGroup>
<appName>jakartaee-app-on-jboss-1625038814881</appName>
<pricingTier>P1v3</pricingTier>
<region>centralus</region>
<runtime>
<os>Linux</os>
<javaVersion>Java 11</javaVersion>
<webContainer>Jbosseap 7</webContainer>
</runtime>
<deployment>
<resources>
<resource>
<directory>${project.basedir}/target</directory>
<includes>
<include>*.war</include>
</includes>
</resource>
</resources>
</deployment>
</configuration>
</plugin>
</plugins>
</build>
重要
檢查 <region>
元素。 如果與 MySQL 的安裝位置不同,請變更為相同的位置。
新增要部署到 Azure 的上述設定之後,請新增下列 XML 項目以部署啟動檔案。 資源 <type>startup</type>
會將指定的指令碼部署為 startup.sh
(Linux) 或 startup.cmd
(Windows) 至 /home/site/scripts/
。 我們在下列步驟中設定啟動指令碼。
<!-- Please add following lines -->
<resource>
<type>startup</type>
<directory>${project.basedir}/src/main/webapp/WEB-INF/</directory>
<includes>
<include>createMySQLDataSource.sh</include>
</includes>
</resource>
<!-- Please add following lines -->
注意
您可以指定要在 XML 中部署的下列資源:
type=<war|jar|ear|lib|startup|static|zip>
- 如果未指定
path
,type=war
會將 war 檔案部署到/home/site/wwwroot/app.war
type=war&path=webapps/<appname>\
的行為會與 wardeploy 完全相同,其會將應用程式解壓縮到 /home/site/wwwroot/webapps/<appname>type=jar
會將 war 檔案部署到/home/site/wwwroot/app.jar
。 將會忽略path
參數type=ear
會將 war 檔案部署到/home/site/wwwroot/app.ear
。 將會忽略path
參數type=lib
會將 jar 部署到 /home/site/libs。 必須指定path
參數type=static
會將指令碼部署到/home/site/scripts
。 必須指定path
參數type=startup
會將指令碼部署為startup.sh
(Linux) 或startup.cmd
(Windows) 至/home/site/scripts/
。 將會忽略path
參數type=zip
會將 zip 解壓縮至/home/site/wwwroot
。path
參數是選用的。
- 如果未指定
現在,從上述 XML 檔案中檢查資源群組名稱和應用程式名稱的值。 請注意這些名稱,或更妥善地將它們指派給環境變數。
<resourceGroup>jakartaee-app-on-jboss-1625038814881-rg</resourceGroup>
<appName>jakartaee-app-on-jboss-1625038814881</appName>
如果您使用 Bash,請使用下列命令來設定環境變數。 您稍後會使用這些值。
export RESOURCEGROUP_NAME=jakartaee-app-on-jboss-1625038814881-rg
export WEBAPP_NAME=jakartaee-app-on-jboss-1625038814881
編譯和建置 Java EE 應用程式
設定 Azure App Service 部署設定之後,請編譯並封裝原始程式碼。
./mvnw clean package
下列輸出會出現在終端機中:
[INFO] Packaging webapp
[INFO] Assembling webapp [jakartaee-app-on-jboss] in [/private/tmp/mslearn-jakarta-ee-azure/target/ROOT]
[INFO] Processing war project
[INFO] Copying webapp resources [/private/tmp/mslearn-jakarta-ee-azure/src/main/webapp]
[INFO] Webapp assembled in [369 msecs]
[INFO] Building war: /private/tmp/mslearn-jakarta-ee-azure/target/ROOT.war
[INFO] WEB-INF/web.xml already added, skipping
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.656 s
[INFO] Finished at: 2023-03-04T12:35:43-05:00
[INFO] ------------------------------------------------------------------------
在 Azure App Service 上將 Java EE 應用程式部署至 JBoss EAP
在編譯並封裝程式碼之後,請部署應用程式:
./mvnw azure-webapp:deploy
下列訊息會出現在終端機中:
[INFO] Creating resource group jakartaee-app-on-jboss-1625038814881-rg in region westeurope...
[INFO] Successfully created resource group jakartaee-app-on-jboss-1625038814881-rg.
[INFO] Creating app service plan...
[INFO] Successfully created app service plan asp-jakartaee-app-on-jboss-1625038814881.
[INFO] Creating web app jakartaee-app-on-jboss-1625038814881...
[INFO] Successfully created Web App jakartaee-app-on-jboss-1625038814881.
[INFO] Trying to deploy artifact to jakartaee-app-on-jboss-1625038814881...
[INFO] Deploying (/private/tmp/mslearn-jakarta-ee-azure/target/ROOT.war)[war] ...
[INFO] Successfully deployed the artifact to https://jakartaee-app-on-jboss-1625038814881.azurewebsites.net
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 02:11 min
[INFO] Finished at: 2023-03-04T12:38:39-05:00
[INFO] ------------------------------------------------------------------------
記住已部署應用程式的 URL,特別是 Maven 輸出中的下列程式碼:
[INFO] Successfully deployed the artifact to https://jakartaee-app-on-jboss-1625038814881.azurewebsites.net
設定資料庫連接
範例應用程式會連線到您的 MySQL 資料庫,並顯示資料。
pom.xml
的Maven 專案設定中,我們指定了 MySQL JDBC 驅動程式,如下所示:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-jdbc-driver}</version>
</dependency>
因此,JBoss EAP 會自動將 JDBC 驅動程式安裝到您的部署套件 (ROOT.war
)。 您可以參考 MySQL JDBC 驅動程式的名稱,如下所示:
ROOT.war_com.mysql.cj.jdbc.Driver_8_0
在 JBoss EAP 中建立 MySQL DataSource 物件
若要存取適用於 MySQL 的 Azure 資料庫,您需要在 JBoss EAP 中設定 DataSource
物件,並在原始程式碼中指定 JNDI 名稱。
為了在 JBoss EAP 中建立 MySQL DataSource
物件,我們建立了下列啟動殼層指令碼。 指令檔 createMySQLDataSource.sh
位於 /WEB-INF
目錄下。
注意
在指令碼中,我們使用 JBoss CLI 命令繫結 MySQL DataSource。 連接字串、使用者名稱和密碼會使用環境變數 MYSQL_CONNECTION_URL
、MYSQL_USER
和 MYSQL_PASSWORD
。
接下來會顯示指令檔的來源。 此指令檔已上傳至 App Service,但尚未設定為叫用。
#!/usr/bin/bash
# In order to use the variables in JBoss CLI scripts
# https://access.redhat.com/solutions/321513
#
sed -i -e "s|.*<resolve-parameter-values.*|<resolve-parameter-values>true</resolve-parameter-values>|g" /opt/eap/bin/jboss-cli.xml
/opt/eap/bin/jboss-cli.sh --connect <<EOF
data-source add --name=JPAWorldDataSourceDS \
--jndi-name=java:jboss/datasources/JPAWorldDataSource \
--connection-url=${MYSQL_CONNECTION_URL} \
--driver-name=ROOT.war_com.mysql.cj.jdbc.Driver_8_0 \
--user-name=${MYSQL_USER} \
--password=${MYSQL_PASSWORD} \
--min-pool-size=5 \
--max-pool-size=20 \
--blocking-timeout-wait-millis=5000 \
--enabled=true \
--driver-class=com.mysql.cj.jdbc.Driver \
--jta=true \
--use-java-context=true \
--valid-connection-checker-class-name=org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker \
--exception-sorter-class-name=com.mysql.cj.jdbc.integration.jboss.ExtendedMysqlExceptionSorter
exit
EOF
現在設定您的 App Service 執行個體,以叫用啟動指令碼:
az webapp config set --startup-file '/home/site/scripts/startup.sh' \
-n ${WEBAPP_NAME} \
-g ${RESOURCEGROUP_NAME}
指令碼本執行之後,每次將應用程式伺服器重新開機時,就會叫用。
注意
如果您的部署成品不是 ROOT.war
,則也必須變更 --driver-name=YOUR_ARTIFACT.war_com.mysql.cj.jdbc.Driver_8_0
值。
設定環境變數以連線至 MySQL
設定啟動指令碼之後,請將 App Service 設定為使用特定環境變數:
az webapp config appsettings set \
--resource-group ${RESOURCEGROUP_NAME} --name ${WEBAPP_NAME} \
--settings \
MYSQL_CONNECTION_URL='jdbc:mysql://mysqlserver-**********.mysql.database.azure.com:3306/world?useSSL=true&requireSSL=false' \
MYSQL_PASSWORD='************' \
MYSQL_USER=azureuser
提示
MYSQL_CONNECTION_URL
、MYSQL_USER
和 MYSQL_PASSWORD
值已在上一個單元中設定。
確認程式碼中的 DataSource 參考
若要從您的應用程式存取 MySQL 資料庫,必須在應用程式專案中設定資料來源參考。 我們使用 Java 持續性 API (JPA) 來實作資料庫存取程式碼。
DataSource
參考的設定已新增至 persistence.xml
,也就是 JPA 的設定檔。
存取以下檔案:
├── src
│ ├── main
│ │ ├── resources
│ │ │ └── META-INF
│ │ │ └── persistence.xml
檢查 DataSource
名稱是否與設定中使用的名稱相符。 程式碼已建立 JNDI 名稱作為 java:jboss/datasources/JPAWorldDataSource
:
<persistence-unit name="JPAWorldDatasourcePU" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/JPAWorldDataSource</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.generate_statistics" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
</properties>
</persistence-unit>
</persistence>
然後,您可以存取 PersistenceContext
單位名稱所參考的 MySQL 資料庫,如下所示:
@Transactional(REQUIRED)
@RequestScoped
public class CityService {
@PersistenceContext(unitName = "JPAWorldDatasourcePU")
EntityManager em;
存取應用程式
在範例應用程式中,我們實作了三個 REST 端點。 您可以使用網頁瀏覽器或 curl
命令來存取應用程式,並驗證這些端點。
若要存取應用程式,您需要參考先前章節中取得的應用程式 URL:
[INFO] Successfully deployed the artifact to
https://jakartaee-app-on-jboss-1606464084546.azurewebsites.net
執行下列命令,以取得 JSON 格式的所有大陸資訊。
$ curl https://${WEBAPP_NAME}.azurewebsites.net/area
["North America","Asia","Africa","Europe","South America","Oceania","Antarctica"]$
如果您在 URL 中指定大陸,就可以取得指定大陸內的所有國家/地區。
$ curl https://${WEBAPP_NAME}.azurewebsites.net/area/Asia | jq '.[] | { name: .name, code: .code }'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 100 16189 100 16189 0 0 65278 0 --:--:-- --:--:-- --:--:-- 65542
{
"name": "Afghanistan",
"code": "AFG"
}
{
"name": "United Arab Emirates",
"code": "ARE"
}
{
"name": "Armenia",
"code": "ARM"
}
{
"name": "Azerbaijan",
"code": "AZE"
}
{
"name": "Bangladesh",
"code": "BGD"
}
....
最後,如果您在 /countries
之後指定國碼 (地區碼),則可以取得國家/地區內人口超過一百萬的所有城市。
$ curl https://${WEBAPP_NAME}.azurewebsites.net/countries/JPN | jq '.[].name'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 100 788 100 788 0 0 2671 0 --:--:-- --:--:-- --:--:-- 2662
"Tokyo"
"Jokohama [Yokohama]"
"Osaka"
"Nagoya"
"Sapporo"
"Kioto"
"Kobe"
"Fukuoka"
"Kawasaki"
"Hiroshima"
"Kitakyushu"
練習摘要
您現在已驗證應用程式 REST 端點,並測試您的應用程式是否可以從 MySQL 資料庫取得資料。
在下一個單元中,您將檢查伺服器記錄。