Migrowanie aplikacji Tomcat do usługi Azure Container Apps

W tym przewodniku opisano, co należy wiedzieć, kiedy chcesz przeprowadzić migrację istniejącej aplikacji Tomcat do uruchomienia w usłudze Azure Container Apps (ACA).

Przed migracją

Aby zapewnić pomyślną migrację, przed rozpoczęciem wykonaj kroki oceny i spisu opisane w poniższych sekcjach.

Utworzenie spisu zasobów zewnętrznych

Zasoby zewnętrzne, takie jak źródła danych, brokery komunikatów JMS i inne, są wstrzykiwane za pośrednictwem interfejsu Java Naming and Directory Interface (JNDI). Niektóre takie zasoby mogą wymagać migracji lub ponownej konfiguracji.

W aplikacji

Sprawdź plik META-INF/context.xml. Poszukaj elementów <Resource> wewnątrz elementu <Context>.

Na serwerach aplikacji

Sprawdź pliki $CATALINA_BASE/conf/context.xml i $CATALINA_BASE/conf/server.xml oraz pliki .xml w katalogach $CATALINA_BASE/conf/[nazwa-aparatu]/[nazwa-hosta].

W plikach context.xml zasoby JNDI będą opisywane przez elementy <Resource> w elemencie <Context> najwyższego poziomu.

W plikach server.xml zasoby JNDI będą opisywane przez elementy <Resource> w elemencie <GlobalNamingResources>.

Źródła danych

Źródła danych to zasoby JNDI z atrybutem type ustawionym na javax.sql.DataSource. Dla każdego źródła danych należy udokumentować następujące informacje:

  • Jaka jest nazwa źródła danych?
  • Jaka jest konfiguracja puli połączeń?
  • Gdzie mogę znaleźć plik JAR sterownika JDBC?

Aby uzyskać więcej informacji, zobacz przewodnik JNDI Datasource How-To (Źródło danych JNDI — porady) w dokumentacji serwera Tomcat.

Wszystkie inne zasoby zewnętrzne

Nie jest możliwe udokumentowanie każdej możliwej zależności zewnętrznej w tym przewodniku. Twój zespół odpowiada za sprawdzenie, czy każda zależność zewnętrzna aplikacji może być spełniona po migracji.

Utworzenie spisu wpisów tajnych

Hasła i bezpieczne ciągi

Sprawdź wszystkie pliki właściwości i konfiguracji na serwerach produkcyjnych pod kątem wszelkich ciągów wpisów tajnych i haseł. Sprawdź pliki server.xml i context.xml w katalogu $CATALINA_BASE/conf. Możesz również znaleźć pliki konfiguracji zawierające hasła lub poświadczenia wewnątrz aplikacji. Mogą one obejmować plik META-INF/context.xml oraz, w przypadku aplikacji Spring Boot, pliki application.properties lub application.yml.

Określanie, czy i jak jest używany system plików

Każde użycie systemu plików na serwerze aplikacji będzie wymagało ponownej konfiguracji lub, w rzadkich przypadkach, zmiany architektury. Można zidentyfikować niektóre lub wszystkie z następujących scenariuszy.

Zawartość statyczna tylko do odczytu

Jeśli aplikacja aktualnie obsługuje zawartość statyczną, potrzebna jest dodatkowa lokalizacja. Warto rozważyć przeniesienie zawartości statycznej do usługi Azure Blob Storage i dodanie usługi Azure CDN, aby zapewnić błyskawiczne pobieranie na całym świecie. Aby uzyskać więcej informacji, zobacz Hostowanie statycznej witryny internetowej w usłudze Azure Storage i Szybki start: integrowanie konta usługi Azure Storage z usługą Azure CDN. Możesz również bezpośrednio wdrożyć zawartość statyczną w aplikacji w planie Azure Spring Apps Enterprise. Aby uzyskać więcej informacji, zobacz Wdrażanie internetowych plików statycznych.

Dynamicznie publikowana zawartość statyczna

Jeśli aplikacja zezwala na zawartość statyczną, która została przekazana/utworzona przez aplikację, ale pozostaje niezmienna po jej utworzeniu, możesz użyć usług Azure Blob Storage i Azure CDN, jak opisano powyżej, oraz usługi Azure Function do obsługiwania przekazywania i odświeżania usługi CDN. Udostępniliśmy przykładową implementację do użycia w temacie Przekazywanie zawartości statycznej i jej wstępne ładowanie w usłudze CDN za pomocą usługi Azure Functions. Możesz również bezpośrednio wdrożyć zawartość statyczną w aplikacji w planie Azure Spring Apps Enterprise. Aby uzyskać więcej informacji, zobacz Wdrażanie internetowych plików statycznych.

Określanie mechanizmu trwałości sesji

Aby zidentyfikować używanego menedżera trwałości sesji, sprawdź pliki context.xml w aplikacji i konfiguracji serwera Tomcat. Poszukaj elementu <Manager>, a następnie zanotuj wartość atrybutu className.

Wbudowane implementacje programu PersistentManager serwera Tomcat, takie jak StandardManager lub FileStore , nie są przeznaczone do użytku z rozproszoną, skalowaną platformą, taką jak ACA. Usługa ACA może równoważyć obciążenie między kilkoma wystąpieniami i w dowolnym momencie w sposób niewidoczny ponownie uruchomić dowolne wystąpienie, dlatego utrwalanie stanu modyfikowalnego w systemie plików nie jest zalecane.

Jeśli wymagana jest trwałość sesji, należy użyć alternatywnej PersistentManager implementacji, która będzie zapisywać w zewnętrznym magazynie danych, takim jak VMware Tanzu Session Manager z pamięcią podręczną Redis Cache.

Przypadki szczególne

Niektóre scenariusze produkcyjne mogą wymagać większej liczby zmian lub narzucić więcej ograniczeń. Chociaż takie scenariusze mogą być rzadkie, ważne jest, aby upewnić się, że są one niestosowalne do aplikacji lub poprawnie rozwiązane.

Określanie, czy aplikacja korzysta z zaplanowanych zadań

Nie można używać zaplanowanych zadań, takich jak zadania Quartz Scheduler lub cron, z konteneryzowanymi wdrożeniami usługi Tomcat. Jeśli aplikacja jest skalowana w poziomie, jedno zaplanowane zadanie może być uruchamiane więcej niż jeden raz w zaplanowanym okresie. Ta sytuacja może prowadzić do niezamierzonych konsekwencji.

Utwórz spis wszystkich zaplanowanych zadań, wewnątrz lub na zewnątrz serwera aplikacji.

Określanie, czy aplikacja zawiera kod właściwy dla systemu operacyjnego

Jeśli aplikacja zawiera dowolny kod z zależnościami w systemie operacyjnym hosta, musisz przeprowadzić jej refaktoryzację, aby usunąć te zależności. Na przykład może być konieczne zastąpienie każdego użycia symbolu / lub \ w ścieżkach systemu plików przez File.Separator lub Paths.get.

Określanie, czy jest używana klasa MemoryRealm

Klasa MemoryRealm wymaga utrwalonego pliku XML. W usłudze ACA należy dodać ten plik do obrazu kontenera lub przekazać go do udostępnionego magazynu, który jest dostępny dla kontenerów. (Aby uzyskać więcej informacji, zobacz Identyfikowanie sekcji mechanizmu trwałości sesji). Należy pathName odpowiednio zmodyfikować parametr .

Aby ustalić, czy klasa MemoryRealm jest aktualnie używana, sprawdź, czy w plikach server.xml i context.xml znajdują się elementy <Realm>, których atrybut className jest ustawiony na org.apache.catalina.realm.MemoryRealm.

Testowanie w miejscu

Przed utworzeniem obrazów kontenerów zmigruj aplikację do zestawu JDK i serwera Tomcat, którego zamierzasz używać w usłudze ACA. Dokładnie przetestuj swoją aplikację, aby zapewnić jej zgodność i wydajność.

Parametryzacja konfiguracji

Podczas wstępnej migracji w plikach server.xml i context.xml prawdopodobnie zostały zidentyfikowane klucze tajne i zależności zewnętrzne, takie jak źródła danych. W przypadku każdego zidentyfikowanego w ten sposób elementu zastąp wszelkie nazwy użytkownika, hasła, parametry połączenia lub adresy URL zmienną środowiskową.

Na przykład załóżmy, że plik context.xml zawiera następujący element:

<Resource
    name="jdbc/dbconnection"
    type="javax.sql.DataSource"
    url="jdbc:postgresql://postgresdb.contoso.com/wickedsecret?ssl=true"
    driverClassName="org.postgresql.Driver"
    username="postgres"
    password="t00secure2gue$$"
/>

W takim przypadku można go zmienić w sposób pokazany w następującym przykładzie:

<Resource
    name="jdbc/dbconnection"
    type="javax.sql.DataSource"
    url="${postgresdb.connectionString}"
    driverClassName="org.postgresql.Driver"
    username="${postgresdb.username}"
    password="${postgresdb.password}"
/>

Migracja

Uwaga

Niektóre wdrożenia produktu Tomcat mogą mieć wiele aplikacji uruchomionych na jednym serwerze Tomcat. Jeśli tak jest w tym wdrożeniu, zdecydowanie zalecamy uruchomienie każdej aplikacji w oddzielnym zasobniku. Pozwala to zoptymalizować wykorzystanie zasobów dla każdej aplikacji przy jednoczesnym zminimalizowaniu złożoności i sprzężenia klas.

Przygotowanie komputera do wdrożenia

Sklonuj repozytorium GitHub tomcat on Containers ( Szybki start ) w usłudze GitHub. To repozytorium zawiera pliki konfiguracji Dockerfile i Tomcat z wieloma zalecanymi optymalizacjami. W poniższych krokach opisano modyfikacje, które prawdopodobnie trzeba będzie wprowadzić do tych plików przed utworzeniem obrazu kontenera i wdrożeniem w usłudze ACA.

Dodawanie zasobów JNDI

Edytuj plik server.xml , aby dodać zasoby przygotowane w krokach przed migracją, takich jak źródła danych, jak pokazano w poniższym przykładzie:

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

Aby uzyskać dodatkowe instrukcje dotyczące źródła danych, zapoznaj się z następującymi sekcjami przewodnika JNDI Datasource How-To (Źródło danych JNDI — porady) w dokumentacji serwera Tomcat:

Kompilacja i wypychanie obrazu

Najprostszym sposobem kompilowania i przekazywania obrazu do usługi Azure Container Registry (ACR) do użycia przez usługę az acr build ACA jest użycie polecenia . To polecenie nie wymaga, aby platforma Docker była zainstalowana na komputerze. Jeśli na przykład masz plik Dockerfile z repozytorium tomcat-container-quickstart i pakiet aplikacji petclinic.war w bieżącym katalogu, możesz skompilować obraz kontenera w usłudze ACR za pomocą następującego polecenia:

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 .

Możesz pominąć parametr --build-arg APP_FILE..., jeśli plik WAR ma nazwę ROOT.war. Możesz pominąć parametr --build-arg SERVER_XML..., jeśli plik XML serwera ma nazwę server.xml. Oba pliki muszą znajdować się w tym samym katalogu co plik Dockerfile.

Alternatywnie możesz użyć interfejsu wiersza polecenia platformy Docker do utworzenia obrazu lokalnie przy użyciu następujących poleceń. Takie podejście może uprościć testowanie i udoskonalanie obrazu przed początkowym wdrożeniem w usłudze ACR. Jednak wymaga instalacji interfejsu wiersza polecenia platformy Docker i uruchomienia demona platformy 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"

Aby uzyskać więcej informacji, zobacz Kompilowanie i przechowywanie obrazów kontenerów za pomocą usługi Azure Container Registry.

Wdrażanie w usłudze Azure Container Apps

Następujące polecenie przedstawia przykładowe wdrożenie:

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

Aby uzyskać bardziej szczegółowy przewodnik Szybki start, zobacz Szybki start: wdrażanie pierwszej aplikacji kontenera.

Po migracji

Po przeprowadzeniu migracji aplikacji do usługi ACA należy sprawdzić, czy działa zgodnie z oczekiwaniami. Po wykonaniu tych czynności skorzystaj z naszych zaleceń, które mogą sprawić, że aplikacja będzie bardziej natywna w chmurze.

Zalecenia

  • Zaprojektuj i zaimplementuj strategię ciągłości działania i odzyskiwania po awarii. W przypadku aplikacji o krytycznym znaczeniu rozważ zastosowanie architektury wdrażania w wielu regionach. Aby uzyskać więcej informacji, zobacz Najlepsze rozwiązania dotyczące ciągłości działania i odzyskiwania po awarii w usłudze Azure Kubernetes Service (AKS).

  • Oceń elementy w pliku logging.properties. Rozważ wyeliminowanie lub zredukowanie niektórych danych wyjściowych rejestrowania, aby zwiększyć wydajność.

  • Rozważ monitorowanie rozmiaru pamięci podręcznej kodu i dodawanie parametrów -XX:InitialCodeCacheSize oraz -XX:ReservedCodeCacheSize do JAVA_OPTS zmiennej w pliku Dockerfile w celu dalszej optymalizacji wydajności. Aby uzyskać więcej informacji, zobacz Dostrajanie pamięci podręcznej kodu w dokumentacji programu Oracle.

  • Rozważ dodanie reguł alertów i grup akcji usługi Azure Monitor, aby szybko wykrywać i rozwiązywać problemy z warunkami aberrant.

  • Rozważ replikowanie wdrożenia usługi Azure Container Apps w innym regionie w celu uzyskania mniejszego opóźnienia i większej niezawodności i odporności na uszkodzenia. Usługa Azure Traffic Manager umożliwia równoważenie obciążenia między wdrożeniami lub używanie usługi Azure Front Door do dodawania odciążania protokołu SSL i zapory aplikacji internetowej z ochroną przed atakami DDoS.

  • Jeśli replikacja geograficzna nie jest konieczna, rozważ dodanie bramy aplikacja systemu Azure w celu dodania odciążania protokołu SSL i zapory aplikacji internetowej z ochroną przed atakami DDoS.