మైక్రోసర్వీస్‌లను అమలు చేయడం నేర్చుకోవడం. పార్ట్ 1. స్ప్రింగ్ బూట్ మరియు డాకర్

మైక్రోసర్వీస్‌లను అమలు చేయడం నేర్చుకోవడం. పార్ట్ 1. స్ప్రింగ్ బూట్ మరియు డాకర్

హలో, హబ్ర్.

ఈ కథనంలో, మైక్రోసర్వీస్‌తో ప్రయోగాలు చేయడం కోసం అభ్యాస వాతావరణాన్ని సృష్టించడం గురించి నా అనుభవం గురించి మాట్లాడాలనుకుంటున్నాను. ప్రతి కొత్త సాధనాన్ని నేర్చుకునేటప్పుడు, నేను ఎల్లప్పుడూ నా స్థానిక మెషీన్‌లో మాత్రమే కాకుండా మరింత వాస్తవిక పరిస్థితుల్లో కూడా ప్రయత్నించాలనుకుంటున్నాను. అందువల్ల, నేను సరళీకృత మైక్రోసర్వీస్ అప్లికేషన్‌ను రూపొందించాలని నిర్ణయించుకున్నాను, ఇది అన్ని రకాల ఆసక్తికరమైన సాంకేతికతలతో "హంగ్" చేయబడవచ్చు. ప్రాజెక్ట్ కోసం ప్రధాన అవసరం నిజమైన వ్యవస్థకు దాని గరిష్ట కార్యాచరణ సామీప్యత.

ప్రారంభంలో, నేను ప్రాజెక్ట్ యొక్క సృష్టిని అనేక దశలుగా విభజించాను:

  1. రెండు సేవలను సృష్టించండి - 'బ్యాకెండ్' మరియు 'గేట్‌వే', వాటిని డాకర్ చిత్రాలలో ప్యాక్ చేయండి మరియు కలిసి పని చేయడానికి వాటిని కాన్ఫిగర్ చేయండి

    కీవర్డ్‌లు: జావా 11, స్ప్రింగ్ బూట్, డాకర్, ఇమేజ్ ఆప్టిమైజేషన్

  2. Google Kubernetes ఇంజిన్‌లో Kubernetes కాన్ఫిగరేషన్ మరియు డిప్లాయ్‌మెంట్ సిస్టమ్ అభివృద్ధి

    కీవర్డ్లు: కుబెర్నెటెస్, GKE, వనరుల నిర్వహణ, ఆటోస్కేలింగ్, రహస్యాలు

  3. మరింత సమర్థవంతమైన క్లస్టర్ నిర్వహణ కోసం హెల్మ్ 3ని ఉపయోగించి చార్ట్‌ను సృష్టించండి

    కీవర్డ్‌లు: హెల్మ్ 3, చార్ట్ విస్తరణ

  4. క్లస్టర్‌కి స్వయంచాలకంగా కోడ్‌ని బట్వాడా చేయడానికి జెంకిన్స్ మరియు పైప్‌లైన్‌ని సెటప్ చేస్తోంది

    కీవర్డ్‌లు: జెంకిన్స్ కాన్ఫిగరేషన్, ప్లగిన్‌లు, ప్రత్యేక కాన్ఫిగరేషన్ రిపోజిటరీ

నేను ప్రతి దశకు ప్రత్యేక కథనాన్ని కేటాయించాలని ప్లాన్ చేస్తున్నాను.

ఈ కథనాల శ్రేణి దృష్టి మైక్రోసర్వీస్‌లను ఎలా వ్రాయాలి అనేదానిపై కాదు, వాటిని ఒకే సిస్టమ్‌లో ఎలా పని చేసేలా చేయాలి. ఈ విషయాలన్నీ సాధారణంగా డెవలపర్ యొక్క బాధ్యతకు వెలుపల ఉన్నప్పటికీ, కనీసం 20% వారితో పరిచయం కలిగి ఉండటం ఇప్పటికీ ఉపయోగకరంగా ఉంటుందని నేను భావిస్తున్నాను (ఇది 80% ఫలితానికి కారణమని తెలిసింది). భద్రత వంటి కొన్ని ముఖ్యమైన అంశాలు ఈ ప్రాజెక్ట్ నుండి వదిలివేయబడతాయి, ఎందుకంటే రచయిత దీని గురించి చాలా తక్కువగా అర్థం చేసుకుంటారు; సిస్టమ్ వ్యక్తిగత ఉపయోగం కోసం ప్రత్యేకంగా సృష్టించబడుతోంది. ఏదైనా అభిప్రాయాలు మరియు నిర్మాణాత్మక విమర్శలను నేను స్వాగతిస్తాను.

మైక్రోసర్వీస్‌లను సృష్టిస్తోంది

సేవలు స్ప్రింగ్ బూట్ ఉపయోగించి జావా 11లో వ్రాయబడ్డాయి. RESTని ఉపయోగించి ఇంటర్-సర్వీస్ కమ్యూనికేషన్ నిర్వహించబడుతుంది. ప్రాజెక్ట్ కనీస సంఖ్యలో పరీక్షలను కలిగి ఉంటుంది (తద్వారా జెంకిన్స్‌లో పరీక్షించడానికి ఏదైనా ఉంటుంది). సేవలకు సంబంధించిన సోర్స్ కోడ్ GitHubలో అందుబాటులో ఉంది: బ్యాకెండ్ и గేట్‌వే.

ప్రతి సేవల స్థితిని తనిఖీ చేయడానికి, వాటి డిపెండెన్సీకి స్ప్రింగ్ యాక్యుయేటర్ జోడించబడింది. ఇది ఎండ్‌పాయింట్ /యాక్చుయేటర్/హెల్త్‌ను సృష్టిస్తుంది మరియు ట్రాఫిక్‌ని అంగీకరించడానికి సేవ సిద్ధంగా ఉంటే 200 స్థితిని అందిస్తుంది, లేదా సమస్యలు ఎదురైతే 504. ఈ సందర్భంలో, ఇది చాలా కల్పిత తనిఖీ, ఎందుకంటే సేవలు చాలా సరళంగా ఉంటాయి మరియు కొన్ని రకాల ఫోర్స్ మేజర్ కింద అవి పాక్షికంగా పనిచేయడం కంటే పూర్తిగా అందుబాటులో ఉండవు. కానీ నిజమైన సిస్టమ్‌లలో, వినియోగదారులు దాన్ని కొట్టడం ప్రారంభించే ముందు సమస్యను గుర్తించడంలో యాక్యుయేటర్ సహాయపడుతుంది. ఉదాహరణకు, డేటాబేస్ యాక్సెస్‌తో సమస్యలు తలెత్తితే, సేవ యొక్క విరిగిన ఉదాహరణతో ప్రాసెసింగ్ అభ్యర్థనలను ఆపడం ద్వారా మేము స్వయంచాలకంగా దీనికి ప్రతిస్పందించగలుగుతాము.

బ్యాకెండ్ సేవ

బ్యాకెండ్ సేవ కేవలం ఆమోదించబడిన అభ్యర్థనల సంఖ్యను లెక్కించి తిరిగి అందిస్తుంది.

కంట్రోలర్ కోడ్:

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

గేట్‌వే సేవ

గేట్‌వే అభ్యర్థనను బ్యాకెండ్ సేవకు ఫార్వార్డ్ చేస్తుంది, కింది సమాచారంతో దానికి అనుబంధంగా ఉంటుంది:

  • గేట్‌వే ఐడి. సర్వర్ ప్రతిస్పందన ద్వారా గేట్‌వే యొక్క ఒక ఉదాహరణను మరొక దాని నుండి వేరు చేయడానికి ఇది అవసరం.
  • చాలా ముఖ్యమైన పాస్‌వర్డ్ (ముఖ్యమైన కుక్కీ ఎన్‌క్రిప్షన్ కోసం కీ నంబర్) పాత్రను పోషించే నిర్దిష్ట “రహస్యం”

అప్లికేషన్.గుణాలలో కాన్ఫిగరేషన్:

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) దీన్ని పరిష్కరించడానికి, సేవలను ఒక నెట్‌వర్క్‌లో కలపాలి మరియు గేట్‌వే మాత్రమే వెలుపల "అవుట్" ఉండాలి.
అలాగే, రెండు సేవలు ఒకే ఫైల్ సిస్టమ్‌ను పంచుకుంటాయి, థ్రెడ్‌లను ఉత్పత్తి చేస్తాయి మరియు ఒక సమయంలో ఒకదానితో ఒకటి జోక్యం చేసుకోవడం ప్రారంభించవచ్చు. మా మైక్రోసర్వీస్‌లను వేరు చేయడం మంచిది. వివిధ మెషీన్‌లలో అప్లికేషన్‌లను పంపిణీ చేయడం ద్వారా (చాలా డబ్బు, కష్టం), వర్చువల్ మిషన్‌లను ఉపయోగించడం (రిసోర్స్-ఇంటెన్సివ్, లాంగ్ స్టార్టప్) లేదా కంటైనర్‌ను ఉపయోగించడం ద్వారా దీనిని సాధించవచ్చు. ఊహించిన విధంగా, మేము మూడవ ఎంపికను ఎంచుకుంటాము మరియు డాకర్ కంటైనర్ కోసం ఒక సాధనంగా.

డాకర్

సంక్షిప్తంగా, డాకర్ ఒక అప్లికేషన్‌కు ఒకటి, వివిక్త కంటైనర్‌లను సృష్టిస్తుంది. డాకర్‌ని ఉపయోగించడానికి, మీరు డాకర్‌ఫైల్‌ను వ్రాయాలి - అప్లికేషన్‌ను రూపొందించడానికి మరియు అమలు చేయడానికి సూచనలను. తరువాత, మీరు చిత్రాన్ని నిర్మించవచ్చు, దానిని ఇమేజ్ రిజిస్ట్రీకి అప్‌లోడ్ చేయవచ్చు (నం. డాకర్ హబ్) మరియు ఒక కమాండ్‌లో ఏదైనా డాకరైజ్డ్ వాతావరణంలో మీ మైక్రోసర్వీస్‌ని అమలు చేయండి.

Dockerfile

చిత్రం యొక్క అతి ముఖ్యమైన లక్షణాలలో ఒకటి దాని పరిమాణం. కాంపాక్ట్ ఇమేజ్ రిమోట్ రిపోజిటరీ నుండి వేగంగా డౌన్‌లోడ్ చేయబడుతుంది, తక్కువ స్థలాన్ని తీసుకుంటుంది మరియు మీ సేవ వేగంగా ప్రారంభమవుతుంది. ఏదైనా చిత్రం ప్రాథమిక చిత్రం ఆధారంగా నిర్మించబడింది మరియు ఇది చాలా కనీస ఎంపికను ఎంచుకోవడానికి సిఫార్సు చేయబడింది. ఒక మంచి ఎంపిక ఆల్పైన్, కనీస ప్యాకేజీలతో కూడిన పూర్తి స్థాయి Linux పంపిణీ.

ముందుగా, డాకర్‌ఫైల్ "హెడ్-ఆన్" వ్రాయడానికి ప్రయత్నిద్దాం (ఇది చెడ్డ మార్గం అని నేను వెంటనే చెబుతాను, దీన్ని చేయవద్దు):

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) మరియు బిల్డ్‌ను ప్రారంభించండి. కంటైనర్‌లోని అప్లికేషన్ దాని పోర్ట్ 8080ని ఉపయోగిస్తుందని EXPOSE 8080 కమాండ్ డాకర్‌కు సంకేతాలు ఇస్తుంది (ఇది అప్లికేషన్‌ను బయటి నుండి యాక్సెస్ చేయదు, కానీ అప్లికేషన్‌ను యాక్సెస్ చేయడానికి అనుమతిస్తుంది, ఉదాహరణకు, అదే డాకర్ నెట్‌వర్క్‌లోని మరొక కంటైనర్ నుండి )

సేవలను చిత్రాలకు ప్యాకేజీ చేయడానికి, మీరు ప్రతి ప్రాజెక్ట్ యొక్క రూట్ నుండి ఆదేశాలను అమలు చేయాలి:

docker image build . -t msvc-backend:1.0.0

ఫలితంగా, మేము 456 MB పరిమాణంలో చిత్రాన్ని పొందుతాము (దీనిలో బేస్ JDK 340 చిత్రం MBని తీసుకుంది). మరియు మా ప్రాజెక్ట్‌లోని తరగతులను ఒక వేలు మీద లెక్కించవచ్చు అనే వాస్తవం ఉన్నప్పటికీ. మా చిత్రం పరిమాణాన్ని తగ్గించడానికి:

  • మేము బహుళ-దశల అసెంబ్లీని ఉపయోగిస్తాము. మొదటి దశలో మేము ప్రాజెక్ట్‌ను సమీకరించాము, రెండవ దశలో మేము JRE ని ఇన్‌స్టాల్ చేస్తాము మరియు మూడవ దశలో ఇవన్నీ కొత్త క్లీన్ ఆల్పైన్ ఇమేజ్‌లోకి కాపీ చేస్తాము. మొత్తంగా, తుది చిత్రం అవసరమైన భాగాలను మాత్రమే కలిగి ఉంటుంది.
  • జావా మాడ్యులరైజేషన్ ఉపయోగిస్తాము. జావా 9తో ప్రారంభించి, మీకు అవసరమైన మాడ్యూల్స్ నుండి మాత్రమే JREని సృష్టించడానికి మీరు jlink సాధనాన్ని ఉపయోగించవచ్చు

ఆసక్తిగల వారి కోసం, చిత్ర పరిమాణాలను తగ్గించే విధానాల గురించి ఇక్కడ ఒక మంచి కథనం ఉంది https://habr.com/ru/company/ruvds/blog/485650/.

చివరి డాకర్ ఫైల్:

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 network create msvc-network

తర్వాత, మైక్రోసర్వీసెస్-బ్యాకెండ్:1.0.0 చిత్రంతో 'బ్యాకెండ్' అనే బ్యాకెండ్ కంటైనర్‌ను ప్రారంభిద్దాం:

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

బ్రిడ్జ్ నెట్‌వర్క్ వారి పేర్లతో కంటైనర్‌ల కోసం బాక్స్ వెలుపల సర్వీస్ డిస్కవరీని అందించడం గమనించదగ్గ విషయం. అంటే, డాకర్ నెట్‌వర్క్‌లో బ్యాకెండ్ సేవ అందుబాటులో ఉంటుంది 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 సేవలకు మాత్రమే)

పై సమస్యలను పరిష్కరించడానికి, డాకర్ స్వార్మ్, నోమాడ్, కుబెర్నెట్స్ లేదా ఓపెన్‌షిఫ్ట్ వంటి అనేక పరిష్కారాలు ఉన్నాయి. మొత్తం సిస్టమ్ జావాలో వ్రాయబడి ఉంటే, మీరు స్ప్రింగ్ క్లౌడ్ వైపు చూడవచ్చు (మంచి వ్యాసం).

В తదుపరి భాగం నేను Kubernetesని ఎలా సెటప్ చేసాను మరియు Google Kubernetes ఇంజిన్‌కి ప్రాజెక్ట్‌ని ఎలా అమలు చేసాను అనే దాని గురించి నేను మీకు చెప్తాను.

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి