Koyi yadda ake tura microservices. Part 1. Spring Boot da Docker

Koyi yadda ake tura microservices. Part 1. Spring Boot da Docker

Hai Habr.

A cikin wannan labarin, Ina so in yi magana game da gwaninta na ƙirƙirar yanayin koyo don gwaji tare da ƙananan ayyuka. Lokacin koyon kowane sabon kayan aiki, koyaushe ina so in gwada shi ba kawai akan injina na gida ba, har ma a cikin ƙarin yanayi na gaske. Sabili da haka, na yanke shawarar ƙirƙirar aikace-aikacen microservice mai sauƙi, wanda daga baya za'a iya "rataye" tare da kowane nau'in fasaha mai ban sha'awa. Babban abin da ake buƙata don aikin shine iyakar aikin kusancinsa zuwa ainihin tsarin.

Da farko, na raba ƙirƙirar aikin zuwa matakai da yawa:

  1. Ƙirƙirar ayyuka guda biyu - 'baya' da 'ƙofa', shirya su cikin hotunan docker kuma saita su don yin aiki tare.

    Mahimman kalmomi: Java 11, Boot Spring, Docker, inganta hoto

  2. Haɓaka tsarin Kubernetes da tsarin turawa a cikin Google Kubernetes Engine

    Mahimman kalmomi: Kubernetes, GKE, sarrafa albarkatun, autoscaling, asirin

  3. Ƙirƙiri ginshiƙi ta amfani da Helm 3 don ingantaccen sarrafa gungu

    Mahimman kalmomi: Helm 3, ƙaddamar da ginshiƙi

  4. Saita Jenkins da bututun mai don sadar da lamba ta atomatik zuwa gungu

    Mahimman kalmomi: Tsarin Jenkins, plugins, ma'ajin saiti daban

Na yi shirin keɓance labarin dabam ga kowane mataki.

Manufar wannan jerin abubuwan ba shine yadda ake rubuta microservices ba, amma yadda ake sanya su aiki a cikin tsari guda. Duk da yake duk waɗannan abubuwan yawanci ba su da alhakin haɓakawa, Ina tsammanin yana da amfani don zama aƙalla 20% saba da su (wanda aka sani yana lissafin kashi 80% na sakamakon). Wasu batutuwa masu mahimmanci, kamar tsaro, ba za a bar su a cikin wannan aikin ba, tunda marubucin ya ɗan fahimci wannan; ana ƙirƙira tsarin ne kawai don amfanin kansa. Ina maraba da duk wani ra'ayi da suka mai ma'ana.

Ƙirƙirar microservices

An rubuta ayyukan a cikin Java 11 ta amfani da Spring Boot. Ana shirya sadarwar tsakanin sabis ta amfani da REST. Aikin zai ƙunshi ƙaramin adadin gwaje-gwaje (domin daga baya a sami wani abu da za a gwada a Jenkins). Ana samun lambar tushe don ayyukan akan GitHub: baya и Gateway.

Don samun damar duba yanayin kowane sabis ɗin, an ƙara Mai kunnawa bazara zuwa dogaron su. Zai haifar da ƙarshen ƙarshen / actuator / lafiya kuma zai dawo da matsayi na 200 idan sabis ɗin yana shirye don karɓar zirga-zirga, ko 504 idan akwai matsaloli. A wannan yanayin, wannan bincike ne na gaskiya, tunda sabis ɗin suna da sauƙi, kuma a ƙarƙashin wani nau'in majeure na iya zama gaba ɗaya ba a samu ba fiye da ci gaba da aiki a wani yanki. Amma a cikin ainihin tsarin, Actuator zai iya taimakawa wajen gano matsala kafin masu amfani su fara bugawa a kai. Misali, idan matsaloli sun taso tare da samun damar shiga bayanan bayanai, za mu iya ba da amsa ta atomatik ga wannan ta hanyar dakatar da buƙatun aiki tare da gurɓataccen misalin sabis ɗin.

Sabis na baya

Sabis ɗin baya zai ƙidaya kawai kuma ya dawo da adadin buƙatun da aka karɓa.

Lambar mai sarrafawa:

@RestController
public class RequestsCounterController {

    private final AtomicLong counter = new AtomicLong();

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

Gwajin sarrafawa:

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

Sabis na Gateway

Ƙofar za ta tura buƙatun zuwa sabis na baya, tare da ƙarin bayani mai zuwa:

  • gateway id. Ana buƙatar ta yadda za a iya bambanta misali ɗaya na ƙofa daga wani ta hanyar amsawar uwar garke
  • Wani “asiri” wanda zai taka rawar wata muhimmiyar kalmar sirri (lambar maɓalli don ɓoyayyen kuki mai mahimmanci)

Kanfigareshan a aikace-aikace.properties:

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

Adafta don sadarwa tare da baya:

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

Mai sarrafawa:

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

Kaddamar:

Bari mu kaddamar da baya:

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

Bari mu fara ƙofar:

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

Binciken:

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

Komai yana aiki. Mai karatu mai hankali zai lura cewa babu wani abu da zai hana mu isa ga bangon baya kai tsaye, ketare ƙofa (http://localhost:8081/requests). Don gyara wannan, sabis ɗin dole ne a haɗa su cikin hanyar sadarwa ɗaya, kuma ƙofa kawai yakamata ya “tsare” waje.
Hakanan, duka sabis ɗin suna raba tsarin fayil iri ɗaya, suna haifar da zaren, kuma a lokaci ɗaya na iya fara tsoma baki tare da juna. Zai yi kyau mu ware ƙananan ayyukan mu. Ana iya samun wannan ta hanyar rarraba aikace-aikace a cikin injuna daban-daban (kuɗi mai yawa, mai wahala), ta amfani da injunan kama-da-wane (ƙananan albarkatu, dogon farawa) ko yin amfani da kwantena. Kamar yadda aka zata, za mu zaɓi zaɓi na uku kuma Docker a matsayin kayan aiki na kwantena.

Docker

A takaice, Docker yana ƙirƙirar kwantena keɓe, ɗaya kowane aikace-aikace. Don amfani da Docker, kuna buƙatar rubuta Dockerfile - umarni don ginawa da gudanar da aikace-aikacen. Na gaba, zaku iya gina hoton, saka shi zuwa wurin rajistar hoto (No. Dockerhub) kuma tura microservice ɗin ku a cikin kowane mahalli mara izini a cikin umarni ɗaya.

Dockerfile

Ɗaya daga cikin mahimman halayen hoto shine girmansa. Karamin hoto zai zazzage da sauri daga wurin ajiya mai nisa, ya ɗauki ƙasa da sarari, kuma sabis ɗin zai fara sauri. An gina kowane hoto akan tushen hoto na asali, kuma ana bada shawara don zaɓar mafi ƙarancin zaɓi. Kyakkyawan zaɓi shine Alpine, cikakken rarraba Linux tare da ƙaramin fakiti.

Da farko, bari mu yi ƙoƙarin rubuta Dockerfile “kan gaba” (Zan ce nan da nan cewa wannan hanya mara kyau ce, kar a yi):

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

Anan muna amfani da hoton tushe mai tsayi tare da JDK da aka riga aka shigar don gina aikinmu. Yin amfani da umarnin ADD, muna ƙara directory ɗin src na yanzu zuwa hoton, yi masa alama yana aiki (WORKDIR) kuma fara ginin. Umurnin EXPOSE 8080 yana sigina ga docker cewa aikace-aikacen da ke cikin kwandon zai yi amfani da tashar jiragen ruwa 8080 (wannan ba zai sa aikace-aikacen ya sami dama daga waje ba, amma zai ba da damar shigar da aikace-aikacen, alal misali, daga wani akwati akan hanyar sadarwar docker iri ɗaya. ).

Don haɗa ayyuka zuwa hotuna, kuna buƙatar gudanar da umarni daga tushen kowane aikin:

docker image build . -t msvc-backend:1.0.0

A sakamakon haka, muna samun hoton 456 MB a girman (wanda hoton JDK 340 ya ɗauki MB). Kuma duk duk da gaskiyar cewa azuzuwan a cikin aikinmu ana iya ƙidaya su a yatsa ɗaya. Don rage girman hotonmu:

  • Muna amfani da taro mai matakai da yawa. A mataki na farko za mu tara aikin, a cikin na biyu za mu shigar da JRE, kuma a mataki na uku za mu kwafi duk wannan zuwa sabon hoton Alpine mai tsabta. Gabaɗaya, hoton ƙarshe zai ƙunshi abubuwan da ake buƙata kawai.
  • Bari mu yi amfani da java modularization. Farawa tare da Java 9, zaku iya amfani da kayan aikin jlink don ƙirƙirar JRE daga kayan aikin da kuke buƙata kawai

Ga masu sha'awar, anan akwai labari mai kyau game da hanyoyin rage girman hoto https://habr.com/ru/company/ruvds/blog/485650/.

Fayil na Karshe:

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

Mun sake ƙirƙirar hoton, kuma daga ƙarshe ya zama siriri sau 6, wanda ya kai 77 MB. Ba sharri ba. Bayan haka, za a iya loda hotunan da aka gama zuwa wurin rajistar hoto domin a samu hotunanku don saukewa daga Intanet.

Gudanar da sabis tare a Docker

Da farko, dole ne ayyukanmu su kasance a kan hanyar sadarwa iri ɗaya. Akwai nau'ikan cibiyoyin sadarwa da yawa a cikin Docker, kuma muna amfani da mafi mahimmancin su - gada, wanda ke ba ku damar kwantena na cibiyar sadarwa da ke gudana akan runduna ɗaya. Bari mu ƙirƙiri hanyar sadarwa tare da umarni mai zuwa:

docker network create msvc-network

Na gaba, bari mu ƙaddamar da akwati na baya mai suna 'backend' tare da hoton microservices-backend: 1.0.0:

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

Yana da kyau a lura cewa hanyar sadarwar gada tana ba da gano sabis daga cikin akwatin don kwantena da sunayensu. Wato, sabis ɗin baya zai kasance a cikin cibiyar sadarwar Docker a http://backend:8080.

Bari mu fara ƙofar:

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

A cikin wannan umarni muna nuna cewa muna tura tashar jiragen ruwa 80 na rundunar mu zuwa tashar jiragen ruwa 8080 na kwantena. Muna amfani da zaɓuɓɓukan env don saita masu canjin yanayi waɗanda za a karanta ta atomatik ta bazara kuma a soke kaddarorin daga aikace-aikacen.properties.

Bayan ƙaddamarwa, kira http://localhost/ kuma tabbatar da cewa komai yana aiki, kamar yadda yake a cikin yanayin da ya gabata.

ƙarshe

A sakamakon haka, mun ƙirƙiri ƙananan ƙananan ayyuka guda biyu, mun tattara su a cikin kwantena na docker kuma muka ƙaddamar da su tare a kan injin guda ɗaya. Sakamakon tsarin, duk da haka, yana da rashin amfani da yawa:

  • Rashin haƙuri mara kyau - komai yana aiki akan sabar ɗaya a gare mu
  • Matsakaicin rashin ƙarfi - yayin da nauyin ke ƙaruwa, zai yi kyau a tura ƙarin misalin sabis ta atomatik kuma daidaita nauyi a tsakanin su.
  • Ƙaddamar da rikitarwa - muna buƙatar shigar da aƙalla umarni 3, tare da wasu sigogi (wannan don sabis 2 ne kawai)

Don magance matsalolin da ke sama, akwai mafita da yawa kamar Docker Swarm, Nomad, Kubernetes ko OpenShift. Idan an rubuta dukkan tsarin a cikin Java, zaku iya duba zuwa Spring Cloud (kyau labarin).

В kashi na gaba Zan gaya muku yadda na kafa Kubernetes da tura aikin zuwa Injin Kubernetes na Google.

source: www.habr.com

Add a comment