Kawm paub siv microservices li cas. Part 1. Caij nplooj ntoos hlav khau raj thiab Docker

Kawm paub siv microservices li cas. Part 1. Caij nplooj ntoos hlav khau raj thiab Docker

Hlo Habr.

Hauv tsab xov xwm no, kuv xav tham txog kuv qhov kev paub dhau los tsim qhov chaw kawm rau kev sim nrog microservices. Thaum kawm txhua lub cuab yeej tshiab, kuv ib txwm xav sim nws tsis yog ntawm kuv lub tshuab hauv zos xwb, tab sis kuj nyob rau hauv cov xwm txheej zoo dua. Yog li ntawd, kuv txiav txim siab los tsim ib daim ntawv thov microservice yooj yim, uas tom qab ntawd tuaj yeem "dai" nrog txhua hom kev nthuav dav. Qhov kev xav tau tseem ceeb rau qhov project yog nws qhov siab tshaj plaws ua haujlwm ze rau qhov system tiag tiag.

Thaum xub thawj, kuv tau faib qhov kev tsim ntawm qhov project ua ob peb kauj ruam:

  1. Tsim ob qhov kev pabcuam - 'backend' thiab 'gateway', ntim lawv rau hauv cov duab docker thiab teeb tsa lawv ua haujlwm ua ke

    Keywords: Java 11, Caij nplooj ntoos hlav khau raj, Docker, duab optimization

  2. Kev txhim kho ntawm Kubernetes teeb tsa thiab xa tawm qhov system hauv Google Kubernetes Cav

    Keywords: Kubernetes, GKE, resource management, autoscaling, secrets

  3. Tsim ib daim ntawv qhia siv Helm 3 rau kev tswj xyuas pawg ua haujlwm zoo dua

    Ntsiab lus: Helm 3, daim ntawv xa tawm

  4. Teeb tsa Jenkins thiab cov raj xa dej kom xa cov lej xa mus rau pawg

    Keywords: Jenkins configuration, plugins, cais configs repository

Kuv npaj siab muab ib tsab xov xwm cais rau txhua kauj ruam.

Lub hom phiaj ntawm cov kab lus no tsis yog yuav ua li cas sau microservices, tab sis yuav ua li cas kom lawv ua haujlwm hauv ib qho system. Thaum tag nrho cov no feem ntau yog sab nraum tus tsim tawm lub luag haujlwm, kuv xav tias nws tseem muaj txiaj ntsig kom muaj tsawg kawg yog 20% ​​paub txog lawv (uas paub tias suav txog 80% ntawm qhov tshwm sim). Qee cov ntsiab lus tseem ceeb, xws li kev ruaj ntseg, yuav raug tso tawm ntawm qhov project no, txij li tus neeg sau nkag siab me ntsis txog qhov no; lub kaw lus tau tsim tshwj xeeb rau kev siv tus kheej. Kuv zoo siab txais tos txhua qhov kev xav thiab kev tawm tswv yim.

Tsim Microservices

Cov kev pabcuam tau sau rau hauv Java 11 siv Spring Boot. Kev sib txuas lus ntawm kev pabcuam yog tsim los siv REST. Qhov project yuav suav nrog tsawg kawg ntawm kev xeem (yog li tom qab ntawd yuav muaj qee yam sim hauv Jenkins). Lub hauv paus code rau cov kev pab cuam muaj nyob rau ntawm GitHub: thaub qab ΠΈ Rooj vag.

Txhawm rau txheeb xyuas lub xeev ntawm txhua qhov kev pabcuam, lub Spring Actuator tau ntxiv rau lawv qhov kev vam khom. Nws yuav tsim kom muaj qhov kawg / actuator / kev noj qab haus huv thiab yuav rov qab tau cov xwm txheej ntawm 200 yog tias qhov kev pabcuam npaj tau txais kev khiav tsheb, lossis 504 thaum muaj teeb meem. Nyob rau hauv cov ntaub ntawv no, qhov no yog ib tug es tsis muaj tseeb check, vim hais tias cov kev pab cuam yog heev yooj yim, thiab nyob rau hauv ib co kev quab yuam majeure lawv muaj peev xwm ua tau kiag li tsis muaj nyob rau hauv ib feem ntawm kev ua hauj lwm. Tab sis hauv cov tshuab tiag tiag, Actuator tuaj yeem pab kuaj xyuas qhov teeb meem ua ntej cov neeg siv pib ntaus nws. Piv txwv li, yog tias muaj teeb meem tshwm sim nrog kev nkag mus rau hauv cov ntaub ntawv, peb yuav tuaj yeem tuaj yeem teb rau qhov no los ntawm kev tso tseg cov kev thov ua haujlwm nrog qhov piv txwv tawg ntawm kev pabcuam.

Backend kev pabcuam

Cov kev pabcuam backend yuav tsuas suav thiab xa rov qab tus naj npawb ntawm kev thov txais.

Controller code:

@RestController
public class RequestsCounterController {

    private final AtomicLong counter = new AtomicLong();

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

Controller xeem:

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

Kev pabcuam rooj vag

Lub rooj vag yuav xa daim ntawv thov mus rau qhov kev pabcuam backend, ntxiv rau nws nrog cov ntaub ntawv hauv qab no:

  • gateway id. Nws yog qhov xav tau kom ib qho piv txwv ntawm lub rooj vag tuaj yeem sib txawv ntawm lwm qhov los ntawm cov lus teb rau cov neeg rau zaub mov
  • Ib qho "kev zais cia" uas yuav ua lub luag haujlwm ntawm tus password tseem ceeb (tus lej tseem ceeb rau kev nkag mus rau lub ncuav qab zib tseem ceeb)

Configuration hauv application.properties:

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

Adapter rau kev sib txuas lus nrog backend:

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

Controller:

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

Tua tawm:

Cia peb pib lub backend:

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

Cia peb pib lub rooj vag:

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

Peb tshawb xyuas:

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

Txhua yam ua haujlwm. Tus neeg nyeem zoo yuav nco ntsoov tias tsis muaj dab tsi tiv thaiv peb los ntawm kev nkag mus rau lub backend ncaj qha, hla lub rooj vag (http://localhost:8081/requests). Txhawm rau kho qhov no, cov kev pabcuam yuav tsum tau muab tso rau hauv ib lub network, thiab tsuas yog lub rooj vag yuav tsum "tso tawm" sab nraud.
Tsis tas li ntawd, ob qho tib si kev pabcuam sib koom ua ke cov ntaub ntawv tib yam, tsim cov xov, thiab ntawm ib qho chaw tuaj yeem pib cuam tshuam rau ib leeg. Nws yuav zoo rau cais peb microservices. Qhov no tuaj yeem ua tiav los ntawm kev faib cov ntawv thov thoob plaws cov tshuab sib txawv (ntau nyiaj ntau, nyuaj), siv cov tshuab virtual (peev txheej siv zog, ua haujlwm ntev) lossis siv ntim khoom. Raws li xav tau, peb xaiv qhov kev xaiv thib peb thiab docker raws li lub cuab yeej rau kev ntim khoom.

docker

Hauv luv luv, Docker tsim cov thawv cais, ib qho rau ib daim ntawv thov. Txhawm rau siv Docker, koj yuav tsum sau Dockerfile - cov lus qhia rau kev tsim thiab khiav daim ntawv thov. Tom ntej no, koj tuaj yeem tsim cov duab, muab tso rau hauv daim ntawv teev npe (No. Dockerhub) thiab xa koj cov kev pabcuam microservice hauv txhua qhov chaw dockerized hauv ib qho lus txib.

Dockerfile

Ib qho ntawm cov yam ntxwv tseem ceeb ntawm cov duab yog nws qhov loj me. Daim duab me me yuav rub tawm sai dua los ntawm qhov chaw cia khoom nyob deb, siv qhov chaw tsawg dua, thiab koj qhov kev pabcuam yuav pib sai dua. Txhua daim duab yog tsim los ntawm cov duab yooj yim, thiab nws raug nquahu kom xaiv qhov kev xaiv minimalistic tshaj plaws. Ib qho kev xaiv zoo yog Alpine, tag nrho-fledged Linux faib nrog tsawg kawg ntawm pob.

Ua ntej, cia peb sim sau Dockerfile "head-on" (Kuv mam li hais tam sim ntawd tias qhov no yog txoj kev phem, tsis txhob ua nws):

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

Ntawm no peb tab tom siv lub hauv paus duab Alpine nrog JDK twb tau teeb tsa los tsim peb qhov project. Siv cov lus txib ADD, peb ntxiv cov npe src tam sim no rau daim duab, kos nws ua haujlwm (WORKDIR) thiab pib tsim. EXPOSE 8080 hais kom ua teeb liab rau docker tias daim ntawv thov hauv lub thawv yuav siv nws qhov chaw nres nkoj 8080 (qhov no yuav tsis ua rau daim ntawv thov nkag tau los ntawm sab nraud, tab sis yuav tso cai rau daim ntawv thov nkag, piv txwv li, los ntawm lwm lub thawv ntawm tib lub docker network. ).

Txhawm rau ntim cov kev pabcuam rau hauv cov duab, koj yuav tsum khiav cov lus txib los ntawm lub hauv paus ntawm txhua qhov haujlwm:

docker image build . -t msvc-backend:1.0.0

Raws li qhov tshwm sim, peb tau txais cov duab ntawm 456 MB hauv qhov loj me (ntawm qhov uas lub hauv paus JDK 340 duab coj MB). Thiab tag nrho txawm tias qhov tseeb tias cov chav kawm hauv peb qhov project tuaj yeem suav rau ntawm ib tus ntiv tes. Txhawm rau txo qhov loj ntawm peb daim duab:

  • Peb siv ntau kauj ruam sib dhos. Nyob rau hauv thawj kauj ruam peb yuav sib sau ua ke qhov project, nyob rau hauv lub thib ob peb yuav nruab JRE, thiab nyob rau hauv lub thib peb kauj ruam peb yuav luam tag nrho cov no mus rau hauv ib tug tshiab huv Alpine duab. Nyob rau hauv tag nrho, daim duab kawg yuav muaj tsuas yog cov khoom tsim nyog.
  • Wb siv java modularization. Pib nrog Java 9, koj tuaj yeem siv cov cuab yeej jlink los tsim JRE los ntawm tsuas yog cov qauv koj xav tau

Rau cov xav paub, ntawm no yog ib tsab xov xwm zoo txog kev txo cov duab loj https://habr.com/ru/company/ruvds/blog/485650/.

Thaum kawg 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"]

Peb rov tsim cov duab, thiab nws thiaj li dhau los ua 6 lub sij hawm thinner, tus nqi rau 77 MB. Tsis phem. Tom qab ntawd, cov duab tiav tuaj yeem muab tso rau hauv daim ntawv sau npe kom koj cov duab muaj rau rub tawm hauv Is Taws Nem.

Khiav kev pabcuam ua ke hauv Docker

Yuav pib nrog, peb cov kev pabcuam yuav tsum nyob rau tib lub network. Muaj ntau ntau hom kev tes hauj lwm hauv Docker, thiab peb siv qhov tseem ceeb tshaj plaws ntawm lawv - choj, uas tso cai rau koj mus rau lub network ntim khiav ntawm tib tus tswv tsev. Cia peb tsim lub network nrog cov lus txib hauv qab no:

docker network create msvc-network

Tom ntej no, cia peb tso lub thawv backend hu ua 'backend' nrog cov duab microservices-backend: 1.0.0:

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

Nws yog ib qho tsim nyog sau cia tias tus choj network muab kev pabcuam nrhiav pom tawm ntawm lub thawv rau cov thawv los ntawm lawv cov npe. Ntawd yog, qhov kev pabcuam backend yuav muaj nyob rau hauv Docker network ntawm http://backend:8080.

Cia peb pib lub rooj vag:

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

Hauv cov lus txib no peb qhia tias peb xa mus rau chaw nres nkoj 80 ntawm peb tus tswv tsev mus rau qhov chaw nres nkoj 8080 ntawm lub thawv. Peb siv env cov kev xaiv los teeb tsa ib puag ncig hloov pauv uas yuav raug nyeem los ntawm lub caij nplooj ntoo hlav thiab hla cov khoom los ntawm application.properties.

Tom qab tso tawm, hu http://localhost/ thiab xyuas kom meej tias txhua yam ua haujlwm, zoo li hauv rooj plaub dhau los.

xaus

Raws li qhov tshwm sim, peb tsim ob lub microservices yooj yim, ntim rau hauv docker ntim thiab tso tawm ua ke ntawm tib lub tshuab. Qhov tshwm sim, txawm li cas los xij, muaj ntau qhov tsis zoo:

  • Kev zam txim tsis zoo - txhua yam ua haujlwm ntawm ib lub server rau peb
  • Tsis zoo scalability - raws li cov load nce, nws yuav zoo rau cia li xa mus rau lwm qhov kev pab cuam thiab sib npaug cov load ntawm lawv.
  • Launch complexity - peb yuav tsum nkag mus rau yam tsawg kawg 3 commands, nrog rau tej yam tsis (qhov no tsuas yog rau 2 kev pab cuam)

Txhawm rau daws cov teeb meem saum toj no, muaj ntau txoj kev daws teeb meem xws li Docker Swarm, Nomad, Kubernetes lossis OpenShift. Yog tias tag nrho cov kab ke sau hauv Java, koj tuaj yeem saib ntawm Spring Cloud (zoo tsab xov xwm).

Π’ lwm ntu Kuv yuav qhia koj txog yuav ua li cas kuv teeb tsa Kubernetes thiab siv qhov project rau Google Kubernetes Cav.

Tau qhov twg los: www.hab.com

Ntxiv ib saib