1. 總覽
本系列程式碼實驗室 (自學式實作教學課程) 旨在協助 Google App Engine (標準) Java 開發人員完成一系列遷移作業,進而將應用程式現代化。按照這些步驟操作,即可更新應用程式,使其更具可攜性,並決定是否要將應用程式容器化,以便用於 Cloud Run (Google Cloud 的容器代管服務,與 App Engine 類似) 和其他容器代管服務。
本教學課程說明如何使用建構套件,將 App Engine 應用程式容器化,以便部署至 Cloud Run 全代管服務。Buildpacks 是 CNCF 專案,可讓您直接從應用程式原始碼建立高度可攜式映像檔,並在任何雲端上執行。
除了說明從 App Engine 遷移至 Cloud Run 的必要步驟,我們也會教您如何將 Java 8 App Engine 應用程式升級至 Java 17。
如果您想遷移的應用程式大量使用 App Engine 舊版套裝組合服務或其他 App Engine 專屬功能,建議您參閱「存取 Java 11/17 適用的 App Engine 套裝組合服務」指南,而非這個程式碼研究室。
在接下來的研究室中
- 使用 Cloud Shell
- 啟用 Cloud Run、Artifact Registry 和 Cloud Build API
- 使用 Cloud Build 上的 Buildpacks 將應用程式容器化
- 將容器映像檔部署至 Cloud Run
軟硬體需求
- Google Cloud Platform 專案,並啟用有效的 GCP 帳單帳戶和 App Engine
- 熟悉常見的 Linux 指令
- 具備開發及部署 App Engine 應用程式的基本知識
- 您想遷移至 Java 17 並部署至 Cloud Run 的 Java 8 Servlet 應用程式 (可以是 App Engine 上的應用程式,或只是來源)
問卷調查
您會如何使用本教學課程?
你對 Java 的體驗如何?
您對使用 Google Cloud 服務的體驗滿意嗎?
2. 背景
App Engine 和 Cloud Functions 等 PaaS 系統可為團隊和應用程式提供許多便利功能,例如讓系統管理員和 DevOps 專注於建構解決方案。使用無伺服器平台時,應用程式可視需要自動擴充資源,並在用量為零時縮減資源,以按用量計費的方式控管費用,還能使用各種常見的開發語言。
不過,容器的彈性也相當吸引人。容器可讓您選擇任何語言、程式庫和二進位檔,兼具無伺服器架構的便利性與容器的彈性。這就是 Google Cloud Run 的用途。
本程式碼研究室不會說明如何使用 Cloud Run,相關內容請參閱 Cloud Run 說明文件。本節的目標是讓您熟悉如何將 App Engine 應用程式容器化,以便在 Cloud Run (或其他容器代管服務) 中執行。繼續操作前,請先瞭解幾件事,主要是使用者體驗會略有不同。
在本程式碼研究室中,您將瞭解如何建構及部署容器。您將瞭解如何使用 Buildpack 將應用程式容器化、從 App Engine 設定遷移,以及定義 Cloud Build 的建構步驟。這項作業會涉及停用特定 App Engine 功能。如果不想採用這種做法,您還是可以將應用程式保留在 App Engine 上,同時升級至 Java 11/17 執行階段。
3. 設定/準備工作
1. 設定專案
在本教學課程中,您將使用 全新專案中的 appengine-java-migration-samples 存放區範例應用程式。確認專案具備有效的帳單帳戶。
如果您打算將現有的 App Engine 應用程式移至 Cloud Run,可以改用該應用程式來進行後續步驟。
執行下列指令,為專案啟用必要 API:
gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com run.googleapis.com
2. 取得基準範例應用程式
在自己的電腦或 Cloud Shell 上複製範例應用程式,然後前往 baseline 資料夾。
這個範例是 Java 8 的 Servlet 型 Datastore 應用程式,適用於部署至 App Engine。請按照 README 中的操作說明,準備將這個應用程式部署至 App Engine。
3. (選用) 部署基準應用程式
如果您想在遷移至 Cloud Run 前,確認應用程式可在 App Engine 上運作,才需要執行下列步驟。
請參閱 README.md 中的步驟:
- 安裝/重新熟悉
gcloudCLI - 使用
gcloud init為專案初始化 gcloud CLI - 使用
gcloud app create建立 App Engine 專案 - 將範例應用程式部署至 App Engine
./mvnw package appengine:deploy -Dapp.projectId=$PROJECT_ID
- 確認應用程式在 App Engine 上順利執行
4. 建立 Artifact Registry 存放區
將應用程式容器化後,您需要將映像檔推送至某處並儲存。在 Google Cloud 中,建議使用 Artifact Registry 執行這項操作。
使用 gcloud 建立名為 migration 的存放區,如下所示:
gcloud artifacts repositories create migration --repository-format=docker \
--description="Docker repository for the migrated app" \
--location="northamerica-northeast1"
請注意,這個存放區使用 docker 格式類型,但有多種存放區類型可供使用。
此時您已擁有基準 App Engine 應用程式,Google Cloud 專案也已準備好將其遷移至 Cloud Run。
4. 修改應用程式檔案
如果您的應用程式大量使用 App Engine 的舊版套裝組合服務、設定或其他僅限 App Engine 的功能,建議您在升級至新版執行階段時繼續存取這些服務。本程式碼研究室會說明應用程式的遷移路徑,這些應用程式已使用獨立服務,或可進行重構以使用獨立服務。
1. 升級至 Java 17
如果您的應用程式使用 Java 8,建議升級至較新的 LTS 候選版本 (例如 11 或 17),以便取得安全性更新並使用新的語言功能。
首先,請更新 pom.xml 中的屬性,加入下列項目:
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
這會將專案版本設為 17,通知編譯器外掛程式您想存取 Java 17 語言功能,並希望編譯的類別與 Java 17 JVM 相容。
2. 包括網路伺服器
在 App Engine 和 Cloud Run 之間遷移時,請考量兩者之間的差異。其中一項差異是,App Engine 的 Java 8 執行階段會為代管的應用程式提供及管理 Jetty 伺服器,但 Cloud Run 不會。我們會使用 Spring Boot 提供網路伺服器和 Servlet 容器。
新增下列相依項目:
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.6.6</version>
<exclusions>
<!-- Exclude the Tomcat dependency -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Use Jetty instead -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
<version>2.6.6</version>
</dependency>
<!-- ... -->
</dependencies>
Spring Boot 預設會嵌入 Tomcat 伺服器,但本範例會排除該構件,並繼續使用 Jetty,盡量減少遷移後預設行為的差異。
3. 設定 Spring Boot
Spring Boot 能夠重複使用您的 Servlet,無須修改,但需要進行一些設定,確保 Servlet 可供探索。
在 com.example.appengine 套件中建立下列 MigratedServletApplication.java 類別:
package com.example.appengine;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
@EnableAutoConfiguration
public class MigratedServletApplication {
public static void main(String[] args) {
SpringApplication.run(MigratedServletApplication.class, args);
}
}
請注意,這包括 @ServletComponentScan 註解,該註解會 (預設在目前套件中) 尋找任何 @WebServlets,並如預期提供這些註解。
4. 建構設定
接著,移除將應用程式封裝為 WAR 的設定。這不需要太多設定,特別是使用 Maven 做為建構工具的專案,因為 JAR 封裝是預設行為。
移除 pom.xml 檔案中的 packaging 標記:
<packaging>war</packaging>
接著,新增 spring-boot-maven-plugin:
<plugins>
<!-- ... -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.6.6</version>
</plugin>
<!-- ... -->
</plugins>
5. 從 App Engine 設定、服務和依附元件遷移
如本程式碼研究室開頭所述,Cloud Run 和 App Engine 的設計宗旨是提供不同的使用者體驗。App Engine 提供的某些現成功能 (例如 Cron 和 Task Queue 服務) 必須手動重新建立,我們會在後續單元中詳細說明。
範例應用程式不會使用舊版套裝服務,但如果您的應用程式會使用,請參閱下列指南:
- 從服務套件遷移,尋找合適的獨立服務。
- 將 XML 設定檔遷移至 YAML:適用於遷移至 Java 11/17 執行階段,但仍使用 App Engine 的使用者。
由於您之後會部署至 Cloud Run,因此可以移除 appengine-maven-plugin:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<!-- can be set w/ -DprojectId=myProjectId on command line -->
<projectId>${app.projectId}</projectId>
<!-- set the GAE version or use "GCLOUD_CONFIG" for an autogenerated GAE version -->
<version>GCLOUD_CONFIG</version>
</configuration>
</plugin>
5. 容器化及部署應用程式
此時,您已準備好直接從原始碼將應用程式部署至 Cloud Run。這個絕佳選項會在幕後使用 Cloud Build,提供自動部署體驗。請注意,如要使用這項功能,您必須擁有至少下列其中一項權限的帳戶,並已按照這些環境設定步驟操作,或是使用 Cloud Shell:
- 擁有者角色
- 編輯者角色
- 下列角色組合:
- Cloud Build 編輯者角色
- Artifact Registry 管理員角色
- 儲存空間管理員角色
- Cloud Run 管理員角色
- 服務帳戶使用者角色
備妥這些必要條件後,只要在來源目錄中執行下列指令即可:
gcloud run deploy SERVICE --source .
執行部署指令時,系統會提示您輸入幾項資訊,例如:
- 提供原始碼位置
- 提供服務名稱
- 啟用 Cloud Run API
- 選取所在區域
回應這些提示後,建構及部署程序就會開始,Cloud Build 會執行下列動作:
- 將來源壓縮成 zip 檔案,並儲存至 Cloud Storage bucket
- 在背景使用 Cloud Native Computing Foundation Buildpacks 建構映像檔
- 建立登錄檔來儲存產生的容器映像檔 (如果尚未建立)
- 並建立 Cloud Run 服務來代管應用程式 (如果尚未建立)
建構及部署完成後,您應該會收到訊息,說明新修訂版本已上線,並處理 100% 的流量。
6. 摘要/清除
恭喜,您已升級、容器化及遷移應用程式,本教學課程到此結束!
接下來,您可以進一步瞭解 CI/CD 和軟體供應鏈安全功能,這些功能現在都能透過 Cloud Build 部署:
選用:清除及/或停用服務
如果您在本教學課程期間將範例應用程式部署至 App Engine,請記得停用該應用程式,以免產生費用。準備好進行下一個程式碼研究室時,可以重新啟用。停用 App Engine 應用程式後,應用程式不會收到任何流量,因此不會產生費用,但如果Datastore 用量超出免費配額,系統仍會收費,因此請刪除足夠的資料,確保用量低於配額限制。
7. 其他資源
App Engine 遷移模組程式碼研究室問題/意見回饋
如果發現本程式碼研究室有任何問題,請先搜尋問題,再提出回報。搜尋及建立新問題的連結:
遷移資源
線上資源
以下是可能與本教學課程相關的線上資源:
App Engine
- App Engine 說明文件
- App Engine 定價和配額資訊
- 比較第一代和第二代平台
- 對舊版執行階段的長期支援
其他雲端資訊
- Google Cloud「永久免費」方案
- Google Cloud CLI (
gcloudCLI) - 所有 Google Cloud 說明文件
影片
授權
這項內容採用的授權為 Creative Commons 姓名標示 2.0 通用授權。