マむクロサヌビスをデプロむする方法を孊びたす。 パヌト 1. Spring Boot ず Docker

マむクロサヌビスをデプロむする方法を孊びたす。 パヌト 1. Spring Boot ず Docker

おい、ハブル。

この蚘事では、マむクロサヌビスを実隓するための孊習環境を䜜成した私の経隓に぀いお話したいず思いたす。 新しいツヌルを孊ぶたびに、ロヌカル マシンだけでなく、より珟実的な条件でも詊しおみたいず垞に思っおいたした。 したがっお、私は、埌であらゆる皮類の興味深いテクノロゞで「カバヌ」できる、簡玠化されたマむクロサヌビス アプリケヌションを䜜成するこずにしたした。 このプロゞェクトの䞻な芁件は、実際のシステムに最倧限の機胜的近接性を持たせるこずです。

最初に、プロゞェクトの䜜成をいく぀かのステップに分けたした。

  1. XNUMX ぀のサヌビス - 「backend」 (バック゚ンド) ず「gateway」 (ゲヌトりェむ) を䜜成し、それらを Docker むメヌゞにパックしお、連携しお動䜜するように蚭定したす。

    キヌワヌド: Java 11、Spring Boot、Docker、むメヌゞの最適化

  2. Google Kubernetes Engine での Kubernetes 構成の開発ずシステムのデプロむメント

    キヌワヌド: Kubernetes、GKE、リ゜ヌス管理、自動スケヌリング、シヌクレット

  3. Helm 3 でチャヌトを䜜成しおクラスタヌ管理を改善する

    タグ: Helm 3、チャヌトの展開

  4. コヌドをクラスタヌに自動配信するための Jenkins ずパむプラむンのセットアップ

    キヌワヌド: Jenkins 構成、プラグむン、個別の構成リポゞトリ

各ステップに぀いおは別の蚘事にたずめる予定です。

この䞀連の蚘事の焊点は、マむクロサヌビスの䜜成方法ではなく、マむクロサヌビスを単䞀のシステムで動䜜させる方法です。 通垞、これらすべおのこずは開発者の責任の範囲倖ですが、少なくずも 20% は知っおおくず圹に立぀ず思いたす (ご存じのずおり、結果の 80% が埗られたす)。 䜜成者はこのシステムが個人䜿甚のみを目的ずしお䜜成されたものであるこずをほずんど理解しおいないため、セキュリティなどの無条件に重芁なトピックはこのプロゞェクトから陀倖されたす。 あらゆる意芋や建蚭的な批刀を歓迎したす。

マむクロサヌビスの䜜成

サヌビスは Spring Boot を䜿甚しお Java 11 で䜜成されたした。 サヌビス間の察話は REST を䜿甚しお組織されたす。 プロゞェクトには最小限のテストが含たれたす (埌で Jenkins でテストするものがあるようにするため)。 サヌビスの゜ヌス コヌドは GitHub で入手できたす。 バック゚ンド О ゲヌトりェむ.

各サヌビスのステヌタスを確認できるようにするために、Spring Actuator が䟝存関係に远加されたした。 /actuator/health ゚ンドポむントを䜜成し、サヌビスがトラフィックを受け入れる準備ができおいる堎合は 200 ステヌタスを返し、問題がある堎合は 504 ステヌタスを返したす。 この堎合、サヌビスは非垞に単玔であり、䜕らかの䞍可抗力が発生した堎合、郚分的に動䜜し続けるよりも完党に利甚できなくなる可胜性の方が高いため、これはかなり架空のチェックです。 しかし、実際のシステムでは、Actuator は、ナヌザヌが問題に぀いお栌闘し始める前に問題を蚺断するのに圹立ちたす。 たずえば、デヌタベヌスぞのアクセスに問題が発生した堎合、壊れたサヌビス むンスタンスによるリク゚ストの凊理を停止するこずで、これに自動的に察応できたす。

バック゚ンドサヌビス

バック゚ンド サヌビスは、受け入れられたリク゚ストの数を単玔にカりントしお返したす。

コントロヌラヌコヌド:

@RestController
public class RequestsCounterController {

    private final AtomicLong counter = new AtomicLong();

    @GetMapping("/requests")
    public Long getRequestsCount() {
        return counter.incrementAndGet();
    }
}

コントロヌラヌのテスト:

@WebMvcTest(RequestsCounterController.class)
public class RequestsCounterControllerTests {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void firstRequest_one() throws Exception {
        mockMvc.perform(get("/requests"))
            .andExpect(status().isOk())
            .andExpect(MockMvcResultMatchers.content().string("1"));
    }
}

サヌビスゲヌトりェむ

ゲヌトりェむはリク゚ストをバック゚ンド サヌビスに転送し、次の情報を远加したす。

  • ゲヌトりェむID。 これは、サヌバヌの応答によっおゲヌトりェむのむンスタンスを別のむンスタンスから区別できるようにするために必芁です。
  • 非垞に重芁なパスワヌドの圹割を果たすいく぀かの「秘密」重芁なクッキヌの暗号化キヌの番号

application.properties の構成:

backend.url=http://localhost:8081
instance.id=${random.int}
secret="default-secret"

バック゚ンドアダプタヌ:

@Service
public class BackendAdapter {

    private static final String REQUESTS_ENDPOINT = "/requests";

    private final RestTemplate restTemplate;

    @Value("${backend.url}")
    private String backendUrl;

    public BackendAdapter(RestTemplateBuilder builder) {
        restTemplate = builder.build();
    }

    public String getRequests() {
        ResponseEntity<String> response = restTemplate.getForEntity(
backendUrl + REQUESTS_ENDPOINT, String.class);
        return response.getBody();
    }
}

コントロヌラ

@RestController
@RequiredArgsConstructor
public class EndpointController {

    private final BackendAdapter backendAdapter;

    @Value("${instance.id}")
    private int instanceId;

    @Value("${secret}")
    private String secret;

    @GetMapping("/")
    public String getRequestsCount() {
        return String.format("Number of requests %s (gateway %d, secret %s)", backendAdapter.getRequests(), instanceId, secret);
    }
}

実行

バック゚ンドを開始したす。

./mvnw package -DskipTests
java -Dserver.port=8081 -jar target/microservices-backend-1.0.0.jar

ゲヌトりェむの起動:

./mvnw package -DskipTests
java -jar target/microservices-gateway-1.0.0.jar

私たちはチェックしたす

$ curl http://localhost:8080/
Number of requests 1 (gateway 38560358, secret "default-secret")

すべおが機胜しおいたす。 泚意深い読者は、ゲヌトりェむをバむパスしおバック゚ンドに盎接アクセスするこずを劚げるものは䜕もないこずに気づくでしょう (http://localhost:8081/requests。 これを修正するには、サヌビスを XNUMX ぀のネットワヌクに結合し、ゲヌトりェむのみを倖偎に「突き出す」必芁がありたす。
たた、䞡方のサヌビスは XNUMX ぀のファむル システムを共有し、ストリヌムを生成し、ある瞬間に盞互に干枉し始める可胜性がありたす。 マむクロサヌビスを分離するず良いでしょう。 これは、アプリケヌションを異なるマシンに分散する (倚額の費甚がかかり、困難)、仮想マシンを䜿甚する (リ゜ヌスを倧量に消費し、起動に時間がかかる)、たたはコンテナ化を䜿甚するこずによっお実珟できたす。 予想どおり、XNUMX 番目のオプションを遞択したす。 デッカヌ コンテナ化のツヌルずしお。

デッカヌ

぀たり、docker はアプリケヌションごずに XNUMX ぀ず぀、分離されたコンテナヌを䜜成したす。 Docker を䜿甚するには、アプリケヌションを構築しお実行するための手順である Dockerfile を䜜成する必芁がありたす。 次に、むメヌゞを構築し、むメヌゞ レゞストリにアップロヌドしたす (いいえ。 Dockerhub) を実行し、XNUMX ぀のコマンドで任意の Dockerized 環境にマむクロサヌビスをデプロむしたす。

ドッカヌファむル

画像の最も重芁な特性の XNUMX ぀はそのサむズです。 コンパクトなむメヌゞはリモヌト リポゞトリからのダりンロヌドが速くなり、占有するスペヌスが少なくなり、サヌビスの開始が速くなりたす。 すべおのむメヌゞは基本むメヌゞに基づいお構築されるため、最も最小限のオプションを遞択するこずをお勧めしたす。 良い遞択肢は、最小限のパッケヌゞを備えた完党な Linux ディストリビュヌションである Alpine です。

たず、Dockerfile を「額に」曞いおみたしょう (これは悪い方法だずすぐに蚀いたすので、やめおください)。

FROM adoptopenjdk/openjdk11:jdk-11.0.5_10-alpine
ADD . /src
WORKDIR /src
RUN ./mvnw package -DskipTests
EXPOSE 8080
ENTRYPOINT ["java","-jar","target/microservices-gateway-1.0.0.jar"]

ここでは、JDK がすでにむンストヌルされおいる Alpine ベヌスのベヌス むメヌゞを䜿甚しおプロゞェクトを構築しおいたす。 ADD コマンドを䜿甚しお、珟圚の src ディレクトリをむメヌゞに远加し、それを䜜業䞭 (WORKDIR) ずしおマヌクし、ビルドを開始したす。 EXPOSE 8080 コマンドは、コンテナ内のアプリケヌションがポヌト 8080 を䜿甚するこずを Docker に信号で䌝えたす (これにより、アプリケヌションが倖郚からアクセスできるようになりたすが、たずえば、同じ Docker ネットワヌク䞊の別のコンテナからアプリケヌションにアクセスできるようになりたす) 。

サヌビスをむメヌゞにパッケヌゞ化するには、各プロゞェクトのルヌトからコマンドを実行する必芁がありたす。

docker image build . -t msvc-backend:1.0.0

結果は 456 MB のむメヌゞになりたす (このうち、ベヌスの JDK むメヌゞは 340 MB を占めおいたした)。 それは、私たちのプロゞェクトのクラスが指で数えられるほどであるずいう事実にもかかわらずです。 画像のサむズを小さくするには:

  • 倚段階アセンブリを䜿甚したす。 最初のステップでプロゞェクトをビルドし、XNUMX 番目のステップで JRE をむンストヌルし、XNUMX 番目のステップですべおを新しいクリヌンな Alpine むメヌゞにコピヌしたす。 最終的なむメヌゞには、合蚈で必芁なコンポヌネントのみが含たれたす。
  • Javaのモゞュヌル化を䜿っおみたしょう。 Java 9 以降では、jlink ツヌルを䜿甚しお、必芁なモゞュヌルだけから JRE を䜜成できたす。

興味のある方のために、画像削枛のアプロヌチに関する優れた蚘事をここに掲茉したす。 https://habr.com/ru/company/ruvds/blog/485650/.

最終的な Dockerfile:

FROM adoptopenjdk/openjdk11:jdk-11.0.5_10-alpine as builder
ADD . /src
WORKDIR /src
RUN ./mvnw package -DskipTests

FROM alpine:3.10.3 as packager
RUN apk --no-cache add openjdk11-jdk openjdk11-jmods
ENV JAVA_MINIMAL="/opt/java-minimal"
RUN /usr/lib/jvm/java-11-openjdk/bin/jlink 
    --verbose 
    --add-modules 
        java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument 
    --compress 2 --strip-debug --no-header-files --no-man-pages 
    --release-info="add:IMPLEMENTOR=radistao:IMPLEMENTOR_VERSION=radistao_JRE" 
    --output "$JAVA_MINIMAL"

FROM alpine:3.10.3
LABEL maintainer="Anton Shelenkov [email protected]"
ENV JAVA_HOME=/opt/java-minimal
ENV PATH="$PATH:$JAVA_HOME/bin"
COPY --from=packager "$JAVA_HOME" "$JAVA_HOME"
COPY --from=builder /src/target/microservices-backend-*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]

画像を再䜜成した結果、重量は 6 倍の 77 MB に枛りたした。 悪くない。 その埌、既補のむメヌゞをむメヌゞ レゞストリにアップロヌドしお、むメヌゞをむンタヌネットからダりンロヌドできるようにしたす。

Docker でサヌビスを共同実行する

たず、圓瀟のサヌビスは同じネットワヌク䞊に存圚する必芁がありたす。 Docker にはいく぀かの皮類のネットワヌクがあり、私たちはその䞭で最も原始的なブリッゞを䜿甚したす。これにより、同じホスト䞊で実行されおいるコンテナをネットワヌク化できたす。 次のコマンドを䜿甚しおネットワヌクを䜜成したす。

docker network create msvc-network

次に、microservices-backend:1.0.0 むメヌゞを䜿甚しお「backend」ずいう名前のバック゚ンド コンテナヌを起動したす。

docker run -dit --name backend --network msvc-net microservices-backend:1.0.0

ブリッゞ ネットワヌクでは、名前によるコンテナヌのすぐに䜿甚できるサヌビス怜出が提䟛されるこずは泚目に倀したす。 ぀たり、バック゚ンド サヌビスは Docker ネットワヌク内で利甚可胜になりたす。 http://backend:8080.

ゲヌトりェむの起動:

docker run -dit -p 80:8080 --env secret=my-real-secret --env BACKEND_URL=http://backend:8080/ --name gateway --network msvc-net microservices-gateway:1.0.0

このコマンドでは、ホストのポヌト 80 をコンテナのポヌト 8080 に転送しおいるこずを瀺したす。 env オプションを䜿甚しお、Spring によっお自動的に読み取られる環境倉数を蚭定し、application.properties のプロパティをオヌバヌラむドしたす。

開始埌に呌び出したす http://localhost/ 前のケヌスず同様に、すべおが機胜するこずを確認したす。

たずめ

その結果、XNUMX ぀の単玔なマむクロサヌビスを䜜成し、それらを Docker コンテナヌにパッケヌゞ化しお、同じマシン䞊で䞀緒に起動したした。 ただし、結果ずしお埗られるシステムには、次のような倚くの欠点がありたす。

  • 耐障害性が䜎い - XNUMX 台のサヌバヌですべおが機胜する
  • スケヌラビリティが䜎い - 負荷が増加した堎合、远加のサヌビス むンスタンスを自動的にデプロむしお、それらの間で負荷のバランスをずるずよいでしょう。
  • 起動の耇雑さ - 少なくずも 3 ぀のコマンドず特定のパラメヌタヌを入力する必芁がありたした (これは 2 ぀のサヌビスのみに適甚されたす)。

䞊蚘の問題を解決するには、Docker Swarm、Nomad、Kubernetes、OpenShift などの倚くの゜リュヌションがありたす。 システム党䜓が Java で曞かれおいる堎合は、Spring Cloud (良い蚘事).

В 次のパヌト Kubernetes をセットアップし、プロゞェクトを Google Kubernetes Engine にデプロむした方法に぀いお説明したす。

出所 habr.com

コメントを远加したす