Di chuyển từ ứng dụng Java của Google App Engine sang Cloud Run bằng Buildpack (Gói bản dựng)

1. Tổng quan

Loạt lớp học lập trình này (hướng dẫn thực hành theo tốc độ của riêng bạn) nhằm mục đích giúp các nhà phát triển Java của Google App Engine (Chuẩn) hiện đại hoá ứng dụng của họ bằng cách hướng dẫn họ thực hiện một loạt quy trình di chuyển. Bằng cách làm theo các bước này, bạn có thể cập nhật ứng dụng để có tính di động cao hơn và quyết định tạo vùng chứa cho ứng dụng đó trên Cloud Run, dịch vụ lưu trữ vùng chứa của Google Cloud (tương tự như App Engine) và các dịch vụ lưu trữ vùng chứa khác.

Hướng dẫn này hướng dẫn bạn cách tạo vùng chứa cho một ứng dụng App Engine để triển khai vào dịch vụ được quản lý hoàn toàn của Cloud Run bằng cách sử dụng Buildpack. Buildpack là một dự án của CNCF, cho phép bạn lấy ứng dụng trực tiếp từ mã nguồn sang hình ảnh có tính di động cao, có thể chạy trên mọi đám mây.

Ngoài việc hướng dẫn các bước bắt buộc để chuyển từ App Engine sang Cloud Run, bạn cũng sẽ tìm hiểu cách nâng cấp ứng dụng App Engine Java 8 lên Java 17.

Nếu ứng dụng mà bạn muốn di chuyển sử dụng nhiều dịch vụ đi kèm cũ của App Engine hoặc các tính năng cụ thể khác của App Engine, thì hướng dẫn Truy cập vào các dịch vụ đi kèm của App Engine cho Java 11/17 có thể phù hợp hơn so với lớp học lập trình này.

Bạn sẽ tìm hiểu cách

  • Sử dụng Cloud Shell
  • Bật API Cloud Run, Artifact Registry và Cloud Build
  • Tạo vùng chứa cho ứng dụng bằng Buildpack trên Cloud Build
  • Triển khai hình ảnh vùng chứa lên Cloud Run

Bạn cần có

Khảo sát

Bạn sẽ sử dụng hướng dẫn này như thế nào?

Chỉ đọc Đọc và hoàn thành bài tập

Bạn đánh giá thế nào về trải nghiệm của mình với Java?

Người mới bắt đầu Trung cấp Thành thạo

Bạn đánh giá thế nào về trải nghiệm khi sử dụng các dịch vụ của Google Cloud?

Người mới bắt đầu Trung cấp Thành thạo

2. Thông tin khái quát

Các hệ thống PaaS như App Engine và Cloud Functions mang lại nhiều tiện ích cho nhóm và ứng dụng của bạn, chẳng hạn như cho phép Quản trị viên hệ thống và DevOps tập trung vào việc xây dựng các giải pháp. Với các nền tảng không có máy chủ, ứng dụng của bạn có thể tự động mở rộng quy mô khi cần, giảm quy mô xuống 0 với mô hình thanh toán theo mức sử dụng để giúp kiểm soát chi phí và sử dụng nhiều ngôn ngữ phát triển phổ biến.

Tuy nhiên, tính linh hoạt của vùng chứa cũng rất hấp dẫn. Với khả năng chọn bất kỳ ngôn ngữ, thư viện và tệp nhị phân nào, vùng chứa mang đến cho bạn cả hai lợi ích: sự thuận tiện của mô hình không máy chủ cùng với tính linh hoạt của vùng chứa. Đó là tất cả những gì mà Google Cloud Run mang lại.

Lớp học lập trình này không đề cập đến cách sử dụng Cloud Run. Nội dung này có trong tài liệu về Cloud Run. Mục tiêu ở đây là giúp bạn làm quen với cách tạo vùng chứa cho ứng dụng App Engine cho Cloud Run (hoặc các dịch vụ khác được lưu trữ trong vùng chứa). Có một số điều bạn cần biết trước khi chuyển sang phiên bản mới, chủ yếu là trải nghiệm người dùng sẽ có chút khác biệt.

Trong lớp học lập trình này, bạn sẽ tìm hiểu cách tạo và triển khai các vùng chứa. Bạn sẽ tìm hiểu cách đóng gói ứng dụng bằng Buildpack, di chuyển khỏi cấu hình App Engine và xác định các bước tạo bản dựng cho Cloud Build. Việc này sẽ liên quan đến việc ngừng sử dụng một số tính năng cụ thể của App Engine. Nếu không muốn làm theo cách này, bạn vẫn có thể nâng cấp lên thời gian chạy Java 11/17 trong khi vẫn giữ các ứng dụng của mình trên App Engine.

3. Thiết lập/Công việc chuẩn bị

1. Thiết lập dự án

Trong hướng dẫn này, bạn sẽ sử dụng một ứng dụng mẫu trong kho lưu trữ appengine-java-migration-samples trên một dự án hoàn toàn mới. Đảm bảo dự án có một tài khoản thanh toán đang hoạt động.

Nếu dự định di chuyển một ứng dụng App Engine hiện có sang Cloud Run, bạn có thể sử dụng ứng dụng đó để làm theo.

Chạy lệnh sau để bật các API cần thiết cho dự án của bạn:

gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com run.googleapis.com

2. Tải ứng dụng mẫu Baseline

Sao chép ứng dụng mẫu trên máy của riêng bạn hoặc Cloud Shell, sau đó chuyển đến thư mục baseline.

Mẫu này là một ứng dụng Datastore dựa trên Servlet, Java 8, dùng để triển khai trên App Engine. Làm theo hướng dẫn trong tệp README về cách chuẩn bị ứng dụng này để triển khai App Engine.

3. (Không bắt buộc) Triển khai ứng dụng cơ sở

Bạn chỉ cần thực hiện bước sau nếu muốn xác nhận rằng ứng dụng hoạt động trên App Engine trước khi chúng tôi di chuyển sang Cloud Run.

Tham khảo các bước trong tệp README.md:

  1. Cài đặt/Làm quen lại với CLI gcloud
  2. Khởi động CLI gcloud cho dự án của bạn bằng gcloud init
  3. Tạo dự án App Engine bằng gcloud app create
  4. Triển khai ứng dụng mẫu lên App Engine
./mvnw package appengine:deploy -Dapp.projectId=$PROJECT_ID
  1. Xác nhận rằng ứng dụng chạy trên App Engine mà không gặp vấn đề

4. Tạo kho lưu trữ Artifact Registry

Sau khi tạo vùng chứa cho ứng dụng, bạn cần có một nơi để đẩy và lưu trữ hình ảnh. Cách được đề xuất để thực hiện việc này trên Google Cloud là sử dụng Artifact Registry.

Tạo kho lưu trữ có tên migration bằng gcloud như sau:

gcloud artifacts repositories create migration --repository-format=docker \
--description="Docker repository for the migrated app" \
--location="northamerica-northeast1"

Xin lưu ý rằng kho lưu trữ này sử dụng loại định dạng docker, nhưng có một số loại kho lưu trữ.

Đến đây, bạn đã có ứng dụng App Engine cơ bản và dự án trên đám mây của Google đã sẵn sàng để di chuyển ứng dụng đó sang Cloud Run.

4. Sửa đổi tệp ứng dụng

Trong trường hợp ứng dụng của bạn sử dụng nhiều dịch vụ, cấu hình hoặc các tính năng khác chỉ có trên App Engine, bạn nên tiếp tục truy cập vào các dịch vụ đó trong khi nâng cấp lên thời gian chạy mới. Lớp học lập trình này minh hoạ một lộ trình di chuyển cho các ứng dụng đã sử dụng các dịch vụ độc lập hoặc có thể được tái cấu trúc một cách khả thi để làm như vậy.

1. Nâng cấp lên Java 17

Nếu ứng dụng của bạn đang chạy trên Java 8, hãy cân nhắc nâng cấp lên một phiên bản LTS mới hơn như 11 hoặc 17 để luôn được cập nhật các bản vá bảo mật và sử dụng các tính năng ngôn ngữ mới.

Bắt đầu bằng cách cập nhật các thuộc tính trong pom.xml để thêm những nội dung sau:

<properties>
    <java.version>17</java.version>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
</properties>

Thao tác này sẽ đặt phiên bản dự án thành 17, thông báo cho trình bổ trợ trình biên dịch rằng bạn muốn truy cập vào các tính năng ngôn ngữ Java 17 và muốn các lớp đã biên dịch tương thích với JVM Java 17.

2. Bao gồm cả máy chủ web

Có một số điểm khác biệt giữa App Engine và Cloud Run mà bạn nên cân nhắc khi chuyển đổi giữa hai nền tảng này. Một điểm khác biệt là trong khi thời gian chạy Java 8 của App Engine cung cấp và quản lý một máy chủ Jetty cho các ứng dụng mà nó lưu trữ, thì Cloud Run lại không. Chúng ta sẽ sử dụng Spring Boot để cung cấp cho chúng ta một máy chủ web và vùng chứa servlet.

Thêm các phần phụ thuộc sau:

<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>

Theo mặc định, Spring Boot sẽ nhúng một máy chủ Tomcat, nhưng mẫu này sẽ loại trừ cấu phần phần mềm đó và gắn với Jetty để giảm thiểu sự khác biệt trong hành vi mặc định sau khi di chuyển.

3. Thiết lập Spring Boot

Mặc dù Spring Boot có thể sử dụng lại các servlet của bạn mà không cần sửa đổi, nhưng bạn sẽ cần phải định cấu hình một số thành phần để đảm bảo các servlet đó có thể phát hiện được.

Tạo lớp MigratedServletApplication.java sau đây trong gói com.example.appengine:

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);
    }
}

Xin lưu ý rằng điều này bao gồm chú thích @ServletComponentScan. Chú thích này sẽ tìm kiếm (trong gói hiện tại theo mặc định) mọi @WebServlets và cung cấp chúng như dự kiến.

4. Cấu hình bản dựng

Tiếp theo, hãy xoá cấu hình để đóng gói ứng dụng của chúng ta dưới dạng WAR. Việc này không đòi hỏi nhiều cấu hình, đặc biệt là đối với các dự án sử dụng Maven làm công cụ tạo – vì đóng gói jar là hành vi mặc định.

Xoá thẻ packaging trong tệp pom.xml:

<packaging>war</packaging>

Tiếp theo, hãy thêm 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. Di chuyển khỏi cấu hình, dịch vụ và các phần phụ thuộc của App Engine

Như đã đề cập ở phần đầu của lớp học lập trình, Cloud Run và App Engine được thiết kế để mang đến những trải nghiệm khác nhau cho người dùng. Một số tính năng mà App Engine cung cấp sẵn (chẳng hạn như dịch vụ CronHàng đợi tác vụ) cần được tạo lại theo cách thủ công và sẽ được đề cập chi tiết hơn trong các học phần sau.

Ứng dụng mẫu không sử dụng các dịch vụ đi kèm cũ, nhưng người dùng có ứng dụng sử dụng các dịch vụ này có thể tham khảo các hướng dẫn sau:

Vì từ giờ trở đi bạn sẽ triển khai lên Cloud Run, nên bạn có thể xoá 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. Đóng gói và triển khai ứng dụng

Đến đây, bạn đã sẵn sàng triển khai ứng dụng của mình lên Cloud Run ngay từ mã nguồn. Đây là một lựa chọn tuyệt vời sử dụng Cloud Build ở chế độ nền để mang đến trải nghiệm triển khai không cần thao tác. Xin lưu ý rằng để sử dụng tính năng này, bạn cần có một tài khoản có ít nhất một trong các quyền sau và đã làm theo các bước thiết lập môi trường này – hoặc sử dụng Cloud Shell:

Sau khi đáp ứng các điều kiện tiên quyết đó, bạn chỉ cần chạy lệnh sau từ thư mục nguồn:

gcloud run deploy SERVICE --source .

Bạn sẽ được nhắc thực hiện một số việc trong quá trình chạy lệnh triển khai, chẳng hạn như:

  • Cung cấp vị trí mã nguồn
  • Cung cấp tên dịch vụ
  • Bật Cloud Run API
  • Chọn khu vực của bạn

Sau khi bạn phản hồi những lời nhắc đó, quá trình tạo và triển khai sẽ bắt đầu. Trong quá trình này, Cloud Build sẽ thực hiện những việc sau:

  • nén và lưu nguồn của bạn vào một bộ chứa bộ nhớ trên đám mây
  • sử dụng các gói bản dựng của Cloud Native Computing Foundation ở chế độ nền để tạo hình ảnh
  • tạo một sổ đăng ký để lưu trữ hình ảnh vùng chứa kết quả (nếu chưa có)
  • Và tạo một dịch vụ Cloud Run để lưu trữ ứng dụng của bạn (nếu chưa có)

Sau khi hoàn tất quá trình tạo và triển khai, bạn sẽ nhận được một thông báo giải thích rằng bản sửa đổi mới đang hoạt động và phục vụ 100% lưu lượng truy cập.

6. Tóm tắt/Dọn dẹp

Xin chúc mừng, bạn đã nâng cấp, đóng gói, di chuyển và ứng dụng của mình, vậy là bạn đã hoàn tất hướng dẫn này!

Từ đây, bước tiếp theo là tìm hiểu thêm về các tính năng bảo mật của CI/CD và chuỗi cung ứng phần mềm mà bạn có thể sử dụng ngay bây giờ khi triển khai bằng Cloud Build:

Không bắt buộc: Dọn dẹp và/hoặc tắt dịch vụ

Nếu bạn đã triển khai ứng dụng mẫu trên App Engine trong hướng dẫn này, hãy nhớ tắt ứng dụng để không bị tính phí. Khi đã sẵn sàng chuyển sang lớp học lập trình tiếp theo, bạn có thể bật lại tính năng này. Mặc dù các ứng dụng App Engine bị vô hiệu hoá sẽ không nhận được lưu lượng truy cập nào để phát sinh phí, nhưng mức sử dụng Datastore có thể tính phí nếu vượt quá hạn mức miễn phí. Vì vậy, hãy xoá đủ để nằm trong giới hạn đó.

Mặt khác, nếu không muốn tiếp tục di chuyển và muốn xoá hoàn toàn mọi thứ, bạn có thể xoá dịch vụ hoặc tắt hoàn toàn dự án.

7. Tài nguyên khác

Vấn đề/ý kiến phản hồi về lớp học lập trình mô-đun di chuyển App Engine

Nếu bạn gặp vấn đề với lớp học lập trình này, vui lòng tìm kiếm vấn đề của bạn trước khi báo cáo. Đường liên kết để tìm kiếm và tạo vấn đề mới:

Tài nguyên di chuyển

Tài nguyên trực tuyến

Dưới đây là các tài nguyên trực tuyến có thể liên quan đến hướng dẫn này:

App Engine

Thông tin khác về Cloud

Video

Giấy phép

Tác phẩm này được cấp phép theo giấy phép Ghi công theo Creative Commons 2.0 Chung.