將 Tomcat 應用程式遷移至 Azure Container Apps
本指南說明當您想要移轉現有的Tomcat應用程式以在 Azure Container Apps 上執行時應該注意的事項。
移轉前
為確保成功移轉,在開始之前,請先完成下列各節中所述的評量和清查步驟。
清查外部資源
外部資源,例如數據源、JMS 訊息代理程式,以及其他資源會透過 Java 命名和目錄介面 (JNDI) 插入。 某些這類資源可能需要移轉或重新設定。
在應用程式內
檢查META-INF/context.xml檔案。 尋找 <Resource>
元素內的 <Context>
元素。
在應用程式伺服器上
檢查 $CATALINA_BASE/conf/context.xml 和 $CATALINA_BASE/conf/server.xml 檔案,以及 $CATALINA_BASE/conf/[engine-name]/[host-name] 目錄中找到的.xml檔案。
在context.xml檔案中,最上層<Context>
元素內的元素將會描述 <Resource>
JNDI 資源。
在server.xml檔案中,專案內的<GlobalNamingResources>
元素將會描述 <Resource>
JNDI 資源。
資料來源
資料來源是 JNDI 資源, type
屬性設定為 javax.sql.DataSource
。 針對每個數據源,記載下列資訊:
- 數據源名稱為何?
- 連線集區設定是什麼?
- 哪裡可以找到 JDBC 驅動程式 JAR 檔案?
如需詳細資訊,請參閱 Tomcat檔中的JNDI資料源操作說明 。
所有其他外部資源
在本指南中記載每個可能的外部相依性並不可行。 您的小組有責任確認您可以在移轉後滿足應用程式的每個外部相依性。
清查秘密
密碼和安全字串
檢查生產伺服器上的所有屬性和組態檔,以取得任何秘密字串和密碼。 請務必在 $CATALINA_BASE/conf 中檢查server.xml和context.xml。 您也可以在應用程式內找到包含密碼或認證的組態檔。 這可能包括 META-INF/context.xml,以及 Spring Boot 應用程式、 application.properties 或 application.yml 檔案。
判斷是否要使用檔案系統及如何使用
每當使用應用程式伺服器上的檔案系統時,都必須重新設定,或在罕見的情況下,還需要進行架構變更。 您可以識別下列部分或所有案例。
唯讀靜態內容
如果應用程式目前提供靜態內容,則必須為其提供替代位置。 您可能想要考慮將靜態內容移至 Azure Blob 儲存體,並新增 Azure CDN 以進行全球快速下載。 如需詳細資訊,請參閱 Azure 儲存體中的靜態網站裝載和快速入門:整合 Azure 儲存體帳戶與 Azure CDN。
動態發佈的靜態內容
如果您的應用程式允許您應用程式上傳/產生的靜態內容,但在建立後不可變,則您可以使用上述的 Azure Blob 儲存體和 CDN,搭配 Azure 函式來處理上傳和 CDN 重新整理。 我們已在使用 Azure Functions 上傳和透過 CDN 預先載入靜態內容中提供範例實作供您使用。
識別會話持續性機制
若要識別正在使用中的會話持續性管理員,請檢查 應用程式和 Tomcat 組態中的context.xml 檔案。 尋找 <Manager>
項目,然後記下 屬性的值 className
。
Tomcat 的內建 PersistentManager 實作,例如 StandardManager 或 FileStore,並非專為搭配分散式、縮放平臺使用而設計,例如 ACA。 ACA 可能會在數個實例之間進行負載平衡,並隨時以透明方式重新啟動任何實例,因此不建議將可變狀態保存到文件系統。
如果需要會話持續性,您必須使用替代 PersistentManager
實作來寫入外部數據存放區,例如具有 Redis 快取的 VMware Tanzu 會話管理員。
特殊情況
某些生產案例可能需要更多變更或施加更多限制。 雖然這類案例可能不常發生,但請務必確保它們無法套用至您的應用程式或正確解決。
判斷應用程式是否依賴排程的作業
排程的作業,例如讓排程器工作或cron作業無法與容器化Tomcat部署搭配使用。 如果您的應用程式相應放大,每個排程期間可能會執行一次以上的排程工作。 這種情況可能會導致非預期的後果。
清查應用程式伺服器內部或外部的任何排程工作。
判斷您的應用程式是否包含 OS 特定程式代碼
如果您的應用程式包含主機 OS 上具有相依性的任何程式代碼,則必須重構它以移除這些相依性。 例如,您可能需要使用 或 \
取代檔案系統路徑File.Separator
中的任何用法/
,或Paths.get
如果您的應用程式在 Windows 上執行。
判斷是否使用MemoryRealm
MemoryRealm 需要保存的 XML 檔案。 在 ACA 上,您必須將此檔案新增至容器映像,或將其上傳至可供容器使用的共享記憶體。 (如需詳細資訊,請參閱 識別工作階段持續性機制 區段。) pathName
參數必須據以修改。
若要判斷目前是否MemoryRealm
使用,請檢查您的server.xml和context.xml檔案,並搜尋 <Realm>
屬性設定為org.apache.catalina.realm.MemoryRealm
的專案className
。
就地測試
建立容器映像之前,請先將應用程式移轉至您想要在ACA上使用的 JDK 和 Tomcat。 徹底測試您的應用程式,以確保相容性和效能。
參數化組態
在移轉前,您可能會在server.xml和context.xml檔案中識別秘密和外部相依性,例如數據源。 因此,針對識別的每個專案,將任何使用者名稱、密碼、連接字串 或URL取代為環境變數。
注意
Microsoft 建議您使用最安全的可用驗證流程。 此程式中所述的驗證流程,例如資料庫、快取、傳訊或 AI 服務,在應用程式中需要高度的信任,而且不會在其他流程中帶來風險。 只有在更安全的選項,例如無密碼或無密鑰連線的受控識別時,才能使用此流程。 針對本機計算機作業,偏好使用無密碼或無密鑰連線的使用者身分識別。
例如,假設 context.xml 檔案包含下列元素:
<Resource
name="jdbc/dbconnection"
type="javax.sql.DataSource"
url="jdbc:postgresql://postgresdb.contoso.com/wickedsecret?ssl=true"
driverClassName="org.postgresql.Driver"
username="postgres"
password="{password}"
/>
在此情況下,您可以變更它,如下列範例所示:
<Resource
name="jdbc/dbconnection"
type="javax.sql.DataSource"
url="${postgresdb.connectionString}"
driverClassName="org.postgresql.Driver"
username="${postgresdb.username}"
password="${postgresdb.password}"
/>
遷移
注意
某些 Tomcat 部署可能會有多個應用程式在單一 Tomcat 伺服器上執行。 如果您的部署是這種情況,強烈建議您在個別 Pod 中執行每個應用程式。 這可讓您優化每個應用程式的資源使用率,同時將複雜度和結合度降至最低。
準備部署成品
複製容器上的Tomcat快速入門 GitHub 存放庫。 此存放庫包含 Dockerfile 和 Tomcat 組態檔,其中包含許多建議的優化。 在下列步驟中,我們概述您可能需要對這些檔案所做的修改,再建置容器映像並部署至 ACA。
新增 JNDI 資源
編輯 server.xml 以新增您在移轉前步驟中準備的資源,例如數據源,如下列範例所示:
注意
Microsoft 建議您使用最安全的可用驗證流程。 此程式中所述的驗證流程,例如資料庫、快取、傳訊或 AI 服務,在應用程式中需要高度的信任,而且不會在其他流程中帶來風險。 只有在更安全的選項,例如無密碼或無密鑰連線的受控識別時,才能使用此流程。 針對本機計算機作業,偏好使用無密碼或無密鑰連線的使用者身分識別。
<!-- Global JNDI resources
Documentation at /docs/jndi-resources-howto.html
-->
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml"
/>
<!-- Migrated datasources here: -->
<Resource
name="jdbc/dbconnection"
type="javax.sql.DataSource"
url="${postgresdb.connectionString}"
driverClassName="org.postgresql.Driver"
username="${postgresdb.username}"
password="${postgresdb.password}"
/>
<!-- End of migrated datasources -->
</GlobalNamingResources>
如需其他數據源指示,請參閱Tomcat檔中 JNDI 資料源操作說明的下列各節:
組建並推送映像
建置映像並將其上傳至 Azure Container Registry (ACR) 以供 ACA 使用的最簡單方式是使用 az acr build
命令。 此命令不需要在您的電腦上安裝 Docker。 例如,如果您從 tomcat-container-quickstart 存放庫取得 Dockerfile,以及目前目錄中的應用程式套件 petclinic.war,您可以使用下列命令在 ACR 中建置容器映射:
az acr build \
--registry $acrName \
--image "${acrName}.azurecr.io/petclinic:{{.Run.ID}}"
--build-arg APP_FILE=petclinic.war \
--build-arg SERVER_XML=prod.server.xml .
如果您的 WAR 檔案名為 ROOT.war,--build-arg APP_FILE...
您可以省略 參數。 如果您的伺服器 XML 檔案名為 server.xml,您可以省略 --build-arg SERVER_XML...
參數。 這兩個檔案必須位於與 Dockerfile 相同的目錄中。
或者,您可以使用 Docker CLI,使用下列命令在本機建置映像。 這種方法可以簡化在初始部署至 ACR 之前測試和精簡映像。 不過,它需要安裝 Docker CLI 並執行 Docker 精靈。
# Build the image locally.
sudo docker build . --build-arg APP_FILE=petclinic.war -t "${acrName}.azurecr.io/petclinic:1"
# Run the image locally.
sudo docker run -d -p 8080:8080 "${acrName}.azurecr.io/petclinic:1"
# You can now access your application with a browser at http://localhost:8080.
# Sign in to ACR.
sudo az acr login --name $acrName
# Push the image to ACR.
sudo docker push "${acrName}.azurecr.io/petclinic:1"
如需詳細資訊,請參閱 使用 Azure Container Registry 建置和儲存容器映射。
部署至 Azure 容器應用程式
下列命令顯示範例部署:
az containerapp create \
--resource-group <RESOURCE_GROUP> \
--name <APP_NAME> \
--environment <ENVIRONMENT_NAME> \
--image <IMAGE_NAME> \
--target-port 8080 \
--ingress 'external' \
--registry-server <REGISTRY_SERVER> \
--min-replicas 1
如需更深入的快速入門,請參閱 快速入門:部署您的第一個容器應用程式。
移轉後
既然您已將應用程式移轉至 ACA,您應該確認它如預期般運作。 完成之後,我們有一些建議可讓您的應用程式更原生雲端。
建議
設計和實作商務持續性和災害復原策略。 針對任務關鍵性應用程式,請考慮多區域部署架構。 如需詳細資訊,請參閱 Azure Kubernetes Service (AKS) 中商務持續性和災害復原的最佳做法。
評估 logging.properties 檔案中的專案。 請考慮排除或減少一些記錄輸出以改善效能。
請考慮監視程序代碼快取大小,並將 參數
-XX:InitialCodeCacheSize
和-XX:ReservedCodeCacheSize
新增至JAVA_OPTS
Dockerfile 中的變數,以進一步優化效能。 如需詳細資訊,請參閱 Oracle 檔中的 Codecache Tuning 。請考慮新增 Azure 監視器警示規則和動作群組,以快速偵測和解決異常狀況。
請考慮在另一個區域中復寫 Azure Container Apps 部署,以降低延遲和更高的可靠性和容錯能力。 使用 Azure 流量管理員 在部署之間進行負載平衡,或使用 Azure Front Door 新增 SSL 卸除和 Web 應用程式防火牆 與 DDoS 保護。
如果不需要異地復寫,請考慮新增 Azure 應用程式閘道 以新增 SSL 卸除,並使用 DDoS 保護 Web 應用程式防火牆。