Migracja z aplikacji Google App Engine w Javie do Cloud Run za pomocą pakietu Buildpacks

1. Omówienie

Ta seria ćwiczeń z programowania (samodzielne, praktyczne samouczki) ma na celu pomóc deweloperom w modernizowaniu aplikacji w Google App Engine (Standard) w języku Java, poprzez przeprowadzenie ich przez serię migracji. Wykonując te czynności, możesz zaktualizować aplikację, aby była bardziej przenośna, i zdecydować się na spakowanie jej do kontenera na potrzeby Cloud Run, czyli usługi Google Cloud, która jest usługą siostrza App Engine do hostowania kontenerów, oraz innych usług hostowania kontenerów.

Z tego samouczka dowiesz się, jak skonteneryzować aplikację App Engine w celu wdrożenia jej w usłudze Cloud Run obsługiwanej w pełni za pomocą pakietów Buildpack. Pakiety kompilacji to projekt CNCF, który umożliwia przekształcenie aplikacji bezpośrednio z kodu źródłowego w wysoce przenośne obrazy, które można uruchamiać w dowolnej chmurze.

Oprócz pokazania Ci wymaganych czynności, które należy wykonać, aby przenieść aplikację z App Engine do Cloud Run, pokażemy Ci też, jak uaktualnić aplikację App Engine w Javie 8 do wersji Java 17.

Jeśli aplikacja, którą chcesz przenieść, intensywnie korzysta ze starszych usług w pakiecie App Engine lub innych funkcji App Engine, ten przewodnik może być dla Ciebie bardziej odpowiedni niż ten.

Dowiesz się, jak:

  • Korzystanie z Cloud Shell
  • Włącz interfejsy Cloud Run API, Artifact Registry API i Cloud Build API
  • Konteneryzowanie aplikacji za pomocą pakietów kompilacji w Cloud Build
  • Wdrażanie obrazów kontenera w Cloud Run

Czego potrzebujesz

Ankieta

Jak wykorzystasz ten samouczek?

Tylko przeczytać Przeczytać i wykonać ćwiczenia

Jak oceniasz swoje doświadczenia z Javą?

Początkujący Średnio zaawansowany Zaawansowany

Jak oceniasz korzystanie z usług Google Cloud?

Początkujący Średnio zaawansowany Zaawansowany

2. Tło

Systemy PaaS, takie jak App Engine i Cloud Functions, zapewniają wiele udogodnień dla Twojego zespołu i aplikacji, np. umożliwiają administratorom systemów i zespołom Devops skupienie się na tworzeniu rozwiązań. Dzięki platformom bezserwerowym Twoja aplikacja może automatycznie skalować się w miarę potrzeby, a także zmniejszać do zera dzięki płatnościom za użycie, co pomaga kontrolować koszty. Możesz też używać różnych popularnych języków programowania.

Jednak elastyczność kontenerów również jest kusząca. Kontenery umożliwiają wybór dowolnego języka, biblioteki i pliku binarnego, co łączy zalety obu rozwiązań: wygodę obsługi rozwiązań bezserwerowych i elastyczność kontenerów. Właśnie na tym polega Google Cloud Run.

Ten projekt nie obejmuje nauki korzystania z Cloud Run. Informacje na ten temat znajdziesz w dokumentacji Cloud Run. Celem tego ćwiczenia jest zapoznanie się z konteneryzacją aplikacji App Engine na potrzeby Cloud Run (lub innych usług hostowanych w kontenerach). Zanim przejdziesz dalej, musisz wiedzieć kilka rzeczy, przede wszystkim to, że wrażenia użytkownika będą nieco inne.

Z tego Codelab dowiesz się, jak tworzyć i wdrażać kontenery. Dowiedz się, jak skonteneryzować aplikację za pomocą pakietów kompilacji, zrezygnować z konfiguracji App Engine i zdefiniować kroki kompilacji dla Cloud Build. Oznacza to rezygnację z niektórych funkcji App Engine. Jeśli nie chcesz podążać tą ścieżką, możesz uaktualnić środowisko wykonawcze Java do wersji 11/17, a jednocześnie pozostawić aplikacje w App Engine.

3. Konfiguracja/praca

1. Konfigurowanie projektu

W tym samouczku użyjesz przykładowej aplikacji z repozytorium appengine-java-migration-samples w zupełnie nowym projekcie. Upewnij się, że projekt ma aktywne konto rozliczeniowe.

Jeśli chcesz przenieść istniejącą aplikację App Engine do Cloud Run, możesz zamiast tego użyć tej aplikacji.

Aby włączyć wymagane interfejsy API w projekcie, uruchom to polecenie:

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

2. Pobierz przykładową aplikację bazową

Skopiuj przykładową aplikację na własnym komputerze lub w Cloud Shell, a następnie przejdź do folderu baseline.

Przykładowa aplikacja to Servlet w Javie 8, przeznaczona do wdrożenia w App Engine. Postępuj zgodnie z instrukcjami w pliku README, aby przygotować tę aplikację do wdrożenia w App Engine.

3. (Opcjonalnie) Wdróż aplikację bazową

Poniższe czynności są konieczne tylko wtedy, gdy chcesz sprawdzić, czy aplikacja działa w App Engine, zanim przeprowadzimy ją do Cloud Run.

Zapoznaj się z instrukcjami w pliku README.md:

  1. Zainstaluj interfejs wiersza poleceń gcloud lub przypomnij sobie, jak z niego korzystać
  2. Zainicjuj gcloud CLI dla projektu za pomocą gcloud init
  3. Utwórz projekt App Engine za pomocą gcloud app create
  4. Wdrażanie przykładowej aplikacji w App Engine
./mvnw package appengine:deploy -Dapp.projectId=$PROJECT_ID
  1. Sprawdź, czy aplikacja działa w App Engine bez problemów

4. Tworzenie repozytorium Artifact Registry

Po skonteneryzowaniu aplikacji musisz mieć miejsce na przesyłanie i przechowywanie obrazów. Zalecanym sposobem na rozwiązanie tego problemu w Google Cloud jest użycie Artifact Registry.

Utwórz repozytorium o nazwie migration za pomocą gcloud w ten sposób:

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

Pamiętaj, że to repozytorium używa typu formatu docker, ale dostępnych jest kilka typów.

W tym momencie masz już podstawową aplikację App Engine, a Twój projekt Google Cloud jest gotowy do przeniesienia jej do Cloud Run.

4. Modyfikowanie plików aplikacji

Jeśli Twoja aplikacja intensywnie korzysta z usług w starszych pakietach App Engine, konfiguracji lub innych funkcji dostępnych tylko w App Engine, zalecamy dalsze korzystanie z tych usług podczas przechodzenia na nowe środowisko uruchomieniowe. Ten projekt pokazuje ścieżkę migracji aplikacji, które już korzystają z samodzielnych usług lub mogą zostać przekształcone w takie.

1. Przechodzenie na Java 17

Jeśli Twoja aplikacja jest napisana w wersji Java 8, rozważ przejście na nowszą wersję LTS, np. 11 lub 17, aby otrzymywać aktualizacje zabezpieczeń i mieć dostęp do nowych funkcji językowych.

Najpierw zaktualizuj właściwości w swoim pliku pom.xml, aby uwzględnić te elementy:

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

Spowoduje to ustawienie wersji projektu na 17, poinformowanie wtyczki kompilatora, że chcesz uzyskać dostęp do funkcji języka Java 17, oraz żądanie zgodności skompilowanych klas z Java 17 JVM.

2. Serwer WWW

Istnieje kilka różnic między App Engine a Cloud Run, które warto wziąć pod uwagę podczas przenoszenia się między nimi. Jedną z różnic jest to, że środowisko wykonawcze Java 8 w App Engine zapewniało i zarządzało serwerem Jetty dla hostowanych aplikacji, a Cloud Run tego nie robi. Użyjemy Spring Boot do utworzenia serwera WWW i kontenera servleta.

Dodaj te zależności:

<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 domyślnie osadza serwer Tomcat, ale w tym przykładzie wykluczymy ten element i użyjemy Jetty, aby zminimalizować różnice w domyślnym zachowaniu po migracji.

3. Konfiguracja Spring Boot

Spring Boot może używać serwerletów bez ich modyfikacji, ale aby były one możliwe do znalezienia, trzeba je skonfigurować.

Utwórz w pakiecie com.example.appengine klasę 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);
    }
}

Pamiętaj, że obejmuje to adnotację @ServletComponentScan, która (w domyślnym pakiecie) będzie wyglądać tak samo w przypadku dowolnego @WebServlets i będzie dostępna zgodnie z oczekiwaniami.

4. Konfiguracja kompilacji

Następnie usuń konfigurację, aby spakować aplikację jako plik WAR. Nie wymaga to wielu ustawień, zwłaszcza w przypadku projektów, które używają Maven jako narzędzia do kompilacji, ponieważ pakowanie jar jest domyślnym zachowaniem.

Usuń tag packaging w pliku pom.xml:

<packaging>war</packaging>

Następnie dodaj 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. Migracja z konfiguracji, usług i zależności App Engine

Jak wspomniano na początku tego ćwiczenia, Cloud Run i App Engine są zaprojektowane tak, aby zapewniać użytkownikom różne wrażenia. Niektóre funkcje dostępne w App Engine, takie jak usługi Cron i Kolejka zadań, trzeba odtworzyć ręcznie. Zostaną one omówione bardziej szczegółowo w kolejnych modułach.

Przykładowa aplikacja nie korzysta ze starszych usług w pakiecie, ale użytkownicy, których aplikacje korzystają z tych usług, mogą skorzystać z tych przewodników:

Od teraz będziesz wdrażać aplikację w Cloud Run, więc możesz usunąć 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. Konteneryzacja i wdrażanie aplikacji

W tym momencie możesz wdrożyć aplikację do Cloud Run bezpośrednio z kodu źródłowego. To doskonała opcja, która wykorzystuje Cloud Build w tle, aby zapewnić automatyczne wdrażanie. Aby korzystać z tej funkcji, musisz mieć konto z co najmniej jednym z tych uprawnień i wykonać te czynności konfiguracyjne środowiska lub użyć Cloud Shell:

Po spełnieniu tych wymagań wstępnych po prostu uruchom to polecenie z katalogu źródłowego:

gcloud run deploy SERVICE --source .

Podczas wykonywania polecenia wdrażania pojawi się kilka próśb, np. o:

  • Podanie lokalizacji kodu źródłowego
  • Podanie nazwy usługi
  • Włączanie Cloud Run API
  • Wybieranie regionu

Po odpowiedzi na te prompty rozpoczyna się proces kompilacji i wdrażania, podczas którego Cloud Build wykonuje te czynności:

  • kompresuje i zapisuje źródło w zasobniku Cloud Storage
  • do kompilacji obrazu korzysta w tle pakiety kompilacji Cloud Native Computing Foundation
  • tworzy rejestr, w którym zapisywany jest wynikowy obraz kontenera (jeśli jeszcze nie istnieje).
  • Tworzy też usługę Cloud Run do hostowania aplikacji (jeśli jeszcze nie istnieje).

Po zakończeniu kompilacji i wdrożenia powinien wyświetlić się komunikat wyjaśniający, że nowa wersja jest już aktywna i obsługuje 100% ruchu.

6. Podsumowanie/czyszczenie

Gratulacje! Aplikacja została zaktualizowana, spakowana do kontenera i przeniesiona. To koniec tego samouczka.

Kolejny krok to poznanie funkcji zabezpieczeń CI/CD i łańcucha dostaw oprogramowania, które są w zasięgu ręki, które można wdrożyć za pomocą Cloud Build.

Opcjonalnie: czyszczenie lub wyłączenie usługi

Jeśli w ramach tego samouczka wdrożono przykładową aplikację w App Engine, pamiętaj, aby ją wyłączyć, aby uniknąć opłat. Gdy będziesz gotowy/gotowa przejść do kolejnego Codelab, możesz ponownie włączyć tę funkcję. Gdy aplikacje App Engine są wyłączone, nie będą generować ruchu, który powoduje naliczanie opłat. Użycie bazy danych może jednak być obciążone opłatą, jeśli przekroczy bezpłatny limit. Usuń więc wystarczającą liczbę aplikacji, aby nie przekroczyć tego limitu.

Jeśli z kolei nie chcesz kontynuować migracji i chcesz całkowicie usunąć wszystko, możesz usunąć usługę lub zamknąć projekt.

7. Dodatkowe materiały

Problemy i opinie dotyczące ćwiczeń w Codelab dotyczących modułu migracji App Engine

Jeśli podczas korzystania z tych ćwiczeń z programowania zauważysz jakiekolwiek problemy, najpierw je wyszukaj. Linki do wyszukiwania i tworzenia nowych problemów:

Zasoby dotyczące migracji

Zasoby online

Poniżej znajdziesz zasoby online, które mogą być przydatne w tym samouczku:

App Engine

Inne informacje dotyczące Cloud

Filmy

Licencja

To zadanie jest licencjonowane na podstawie ogólnej licencji Creative Commons Attribution 2.0.