Омӯзиши ҷобаҷогузории микросервисҳо. Қисми 1. Баҳори Boot ва Docker

Омӯзиши ҷобаҷогузории микросервисҳо. Қисми 1. Баҳори Boot ва Docker

Салом, Хабр.

Дар ин мақола, ман мехоҳам дар бораи таҷрибаи худ дар эҷоди муҳити омӯзишӣ барои таҷриба бо хидматҳои микросервис сӯҳбат кунам. Ҳангоми омӯхтани ҳар як асбоби нав, ман ҳамеша мехостам онро на танҳо дар мошини маҳаллии худ, балки дар шароити воқеӣ низ санҷам. Аз ин рӯ, ман тасмим гирифтам, ки як барномаи соддакардашудаи хидматрасонии хурд эҷод кунам, ки онро баъдтар бо ҳама гуна технологияҳои ҷолиб "овехта" кардан мумкин аст. Талаботи асосии лоиҳа наздикии максималии функсионалии он ба системаи воқеӣ мебошад.

Дар аввал ман эҷоди лоиҳаро ба якчанд марҳила тақсим кардам:

  1. Ду хидмат эҷод кунед - 'backend' ва 'gateway', онҳоро дар тасвирҳои докер ҷойгир кунед ва онҳоро барои якҷоя кор кардан танзим кунед

    Калидвожаҳо: Java 11, Spring Boot, Docker, оптимизатсияи тасвир

  2. Таҳияи системаи конфигуратсия ва ҷойгиркунии Kubernetes дар Google Kubernetes Engine

    Калидвожаҳо: Kubernetes, GKE, идоракунии захираҳо, autoscaling, секретҳо

  3. Барои идоракунии самараноки кластер бо истифода аз Helm 3 диаграмма эҷод кунед

    Калидвожаҳо: Helm 3, ҷойгиркунии диаграмма

  4. Насб кардани Ҷенкинс ва қубур барои интиқоли автоматии код ба кластер

    Калидвожаҳо: Конфигуратсияи Ҷенкинс, плагинҳо, анбори конфигуратсияҳои алоҳида

Ман нақша дорам, ки ба ҳар як қадам як мақолаи алоҳида ҷудо кунам.

Мақсади ин силсила мақолаҳо нест, ки чӣ тавр навиштани хидматҳои хурд, балки чӣ гуна кор кардани онҳо дар як система аст. Гарчанде ки ҳамаи ин чизҳо одатан берун аз масъулияти таҳиякунанда ҳастанд, ман фикр мекунам, ки ҳадди аққал 20% бо онҳо шинос шудан муфид аст (ки маълум аст, ки 80% натиҷаро ташкил медиҳад). Баъзе мавзӯъҳои комилан муҳим, аз қабили амният, аз ин лоиҳа берун хоҳанд монд, зеро муаллиф дар ин бора каме дарк мекунад; система танҳо барои истифодаи шахсӣ сохта шудааст. Ман ҳама гуна андешаҳо ва танқиди созандаро истиқбол мекунам.

Эҷоди хидматҳои микро

Хидматҳо дар Java 11 бо истифода аз Spring Boot навишта шудаанд. Муоширати байнихизматрасонӣ бо истифода аз REST ташкил карда мешавад. Лоиҳа шумораи ҳадди ақали санҷишҳоро дар бар мегирад (то он ки баъдтар дар Ҷенкинс чизе санҷида шавад). Рамзи сарчашмаи хидматҳо дар GitHub дастрас аст: пушти сар и Дарвоза.

Барои санҷидани ҳолати ҳар як хидмат, ба вобастагии онҳо як Actuator Spring илова карда шуд. Он нуқтаи ниҳоӣ / фаъолкунанда / саломатиро эҷод мекунад ва ҳолати 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). Барои ислоҳ кардани ин, хидматҳо бояд дар як шабака муттаҳид карда шаванд ва танҳо шлюз дар берун "барояд".
Инчунин, ҳарду хидматҳо як системаи файлиро мубодила мекунанд, риштаҳо тавлид мекунанд ва дар як лаҳза метавонанд ба ҳамдигар халал расонанд. Хуб мебуд, ки микросервисҳои моро ҷудо кунем. Инро тавассути паҳн кардани барномаҳо дар байни мошинҳои гуногун (пули зиёд, душвор), бо истифода аз мошинҳои виртуалӣ (захираҳои пуршиддат, оғози дарозмуддат) ё бо истифода аз контейнерсозӣ ба даст овардан мумкин аст. Тавре ки интизор мерафт, мо варианти сеюмро интихоб мекунем ва Доктор ҳамчун воситаи контейнерсозӣ.

Доктор

Хулоса, Docker контейнерҳои ҷудогона эҷод мекунад, ки якто барои як барнома. Барои истифодаи Docker, шумо бояд Dockerfile нависед - дастурҳо оид ба сохтан ва иҷро кардани барнома. Баъдан, шумо метавонед тасвирро созед, онро ба феҳристи тасвирҳо бор кунед (№. Dockerhub) ва микросервиси худро дар ҳама гуна муҳити докеризатсияшуда дар як фармон ҷойгир кунед.

файли докер

Яке аз хусусиятҳои муҳимтарини тасвир андозаи он аст. Тасвири паймон аз анбори дурдаст зудтар зеркашӣ карда, ҷои камро ишғол мекунад ва хидмати шумо зудтар оғоз мешавад. Ҳар гуна тасвир дар асоси тасвири асосӣ сохта мешавад ва тавсия дода мешавад, ки варианти минималистиро интихоб кунед. Варианти хуб Alpine аст, тақсимоти мукаммали Linux бо ҳадди ақали бастаҳо.

Аввалан, биёед кӯшиш кунем, ки 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 аллакай насбшуда истифода мебарем. Бо истифода аз фармони ADD, мо директорияи ҷории src-ро ба тасвир илова мекунем, онро ҳамчун кор (WORKDIR) қайд мекунем ва сохтани онро оғоз мекунем. Фармони EXPOSE 8080 ба докер сигнал медиҳад, ки барнома дар контейнер порти 8080-и худро истифода хоҳад кард (ин барномаро аз берун дастрас намекунад, балки имкон медиҳад, ки ба барнома, масалан, аз як контейнери дигар дар як шабакаи докер дастрас шавад. ).

Барои бастабандии хидматҳо ба тасвирҳо, шумо бояд фармонҳоро аз решаи ҳар як лоиҳа иҷро кунед:

docker image build . -t msvc-backend:1.0.0

Дар натиҷа, мо тасвири андозаи 456 МБ ба даст меорем (аз он тасвири асосии JDK 340 МБ гирифтааст). Ва ҳама сарфи назар аз он, ки дарсҳоро дар лоиҳаи мо метавон бо як ангушт ҳисоб кард. Барои кам кардани андозаи тасвири мо:

  • Мо монтажи бисёрқадамро истифода мебарем. Дар қадами аввал мо лоиҳаро ҷамъ мекунем, дар дуюм мо JRE-ро насб мекунем ва дар қадами сеюм мо ҳамаи инро ба тасвири нави тозаи кӯҳӣ нусхабардорӣ мекунем. Дар маҷмӯъ, тасвири ниҳоӣ танҳо ҷузъҳои заруриро дар бар мегирад.
  • Биёед модулизатсияи Java-ро истифода барем. Аз Java 9 сар карда, шумо метавонед асбоби jlink-ро барои сохтани JRE танҳо аз модулҳои лозима истифода баред

Барои кунҷкоб, дар ин ҷо як мақолаи хуб дар бораи равишҳои кам кардани андозаи тасвир аст https://habr.com/ru/company/ruvds/blog/485650/.

Файли ниҳоии Docker:

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 МБ-ро ташкил дод. Бад не. Пас аз он, тасвирҳои тайёрро ба феҳристи тасвирҳо бор кардан мумкин аст, то тасвирҳои шумо барои зеркашӣ аз Интернет дастрас бошанд.

Якҷоя иҷро кардани хидматҳо дар Docker

Барои оғоз, хидматҳои мо бояд дар як шабака бошанд. Дар Docker якчанд намуди шабакаҳо мавҷуданд ва мо ибтидоии онҳо - bridge -ро истифода мебарем, ки ба шумо имкон медиҳад контейнерҳои дар як ҳост коркунандаро шабака кунед. Биёед бо фармони зерин шабака эҷод кунем:

docker network create msvc-network

Минбаъд, биёед як контейнери пуштибониро бо номи 'backend' бо тасвири microservices-backend:1.0.0 оғоз кунем:

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-ро барои муқаррар кардани тағирёбандаҳои муҳити зист истифода мебарем, ки онҳо то баҳор ба таври худкор хонда мешаванд ва хосиятҳои application.properties-ро бекор мекунанд.

Пас аз оғоз, занг занед http://localhost/ ва боварӣ ҳосил кунед, ки ҳама чиз кор мекунад, чунон ки дар ҳолати қаблӣ.

хулоса

Дар натиҷа, мо ду микросервиси оддиро офаридем, онҳоро дар контейнерҳои докер бастабандӣ кардем ва онҳоро дар як мошин якҷоя оғоз кардем. Бо вуҷуди ин, системаи натиҷавӣ як қатор камбудиҳо дорад:

  • Таҳаммулпазирии камбизоат - ҳама чиз дар як сервер барои мо кор мекунад
  • Миқёспазирии суст - вақте ки сарборӣ афзоиш меёбад, хуб мебуд, ки ба таври худкор намунаҳои хидматрасониро ҷойгир кунед ва сарбориро байни онҳо мувозинат кунед
  • Мушкилии оғоз - ба мо лозим буд, ки ҳадди аққал 3 фармонро бо параметрҳои муайян ворид кунем (ин танҳо барои 2 хидмат аст)

Барои ҳалли мушкилоти дар боло зикршуда, як қатор роҳҳои ҳалли мушкилот мавҷуданд, ба монанди Docker Swarm, Nomad, Kubernetes ё OpenShift. Агар тамоми система дар Java навишта шуда бошад, шумо метавонед ба сӯи Spring Cloud (мақолаи хуб).

В қисми оянда Ман ба шумо дар бораи он мегӯям, ки чӣ гуна ман Kubernetes-ро насб кардам ва лоиҳаро дар Google Kubernetes Engine ҷойгир кардам.

Манбаъ: will.com

Илова Эзоҳ