سکو ته ڪيئن لڳايو وڃي microservices. حصو 1. اسپرنگ بوٽ ۽ ڊڪر

سکو ته ڪيئن لڳايو وڃي microservices. حصو 1. اسپرنگ بوٽ ۽ ڊڪر

هي حبر.

هن آرٽيڪل ۾، مان مائڪرو سروسز سان تجربو ڪرڻ لاءِ سکيا وارو ماحول پيدا ڪرڻ ۾ منهنجي تجربي بابت ڳالهائڻ چاهيان ٿو. جڏهن مون هر نئين اوزار کي سکيو، مون هميشه ان کي نه رڳو مقامي مشين تي، پر وڌيڪ حقيقي حالتن ۾ پڻ ڪوشش ڪرڻ چاهيو. تنهن ڪري، مون هڪ آسان مائڪرو سروس ايپليڪيشن ٺاهڻ جو فيصلو ڪيو، جيڪو بعد ۾ سڀني قسمن جي دلچسپ ٽيڪنالاجيز سان "ڪور" ڪري سگهجي ٿو. پروجيڪٽ جي بنيادي ضرورت ان جي وڌ ۾ وڌ فنڪشنل ويجهڙائي حقيقي نظام جي ويجهو آهي.

شروعات ۾، مون منصوبي جي تخليق کي ڪيترن ئي مرحلن ۾ ٽوڙيو:

  1. ٻه خدمتون ٺاھيو - 'backend' (backend) ۽ 'gateway' (gateway)، انھن کي ڊاکر تصويرن ۾ پيڪ ڪريو ۽ انھن کي گڏ ڪرڻ لاء سيٽ ڪريو

    Keywords: Java 11, Spring Boot, Docker, Image Optimization

  2. Google Kubernetes Engine ۾ Kubernetes ترتيب ۽ سسٽم جي جوڙجڪ جي ترقي

    Keywords: Kubernetes, GKE, وسيلن جو انتظام, خودڪار اسڪيلنگ, راز

  3. بهتر ڪلستر مينيجمينٽ لاءِ هيلم 3 سان چارٽ ٺاهڻ

    ٽيگ: هيلم 3، چارٽ جي ترتيب

  4. ڪلستر تائين ڪوڊ جي خودڪار ترسيل لاءِ جينڪنز ۽ پائپ لائن کي ترتيب ڏيڻ

    Keywords: Jenkins configuration, plugins, fraud configs repository

مان هر قدم تي هڪ الڳ مضمون وقف ڪرڻ جو ارادو ڪريان ٿو.

مضمونن جي هن سلسلي جو مرڪز اهو ناهي ته مائڪرو سروسز ڪيئن لکجي، پر انهن کي هڪ سسٽم ۾ ڪيئن ڪم ڪجي. جيتوڻيڪ اهي سڀ شيون عام طور تي ڊولپر جي ذميواري کان ٻاهر آهن، مان سمجهان ٿو ته اهو اڃا تائين انهن سان واقف ٿيڻ لاء مفيد آهي گهٽ ۾ گهٽ 20٪ (جيڪو، توهان ڄاڻو ٿا، نتيجو جو 80٪ ڏيو). ڪجهه غير مشروط طور تي اهم موضوع، جهڙوڪ سيڪيورٽي، هن پروجيڪٽ مان رهجي ويندا، ڇاڪاڻ ته ليکڪ هن سسٽم بابت ٿورو سمجهي ٿو، صرف ذاتي استعمال لاءِ ٺاهيو ويو آهي. مان ڪنهن به رايا ۽ تعميري تنقيد کي ڀليڪار ڪريان ٿو.

مائڪرو سروسز ٺاهڻ

خدمتون جاوا 11 ۾ اسپرنگ بوٽ استعمال ڪندي لکيون ويون. Interservice رابطي منظم ڪيو ويو آهي REST استعمال ڪندي. پروجيڪٽ ۾ گهٽ ۾ گهٽ ٽيسٽن جو تعداد شامل هوندو (انهي ڪري ته بعد ۾ جينڪنز ۾ ٽيسٽ ڪرڻ لاءِ ڪجهه آهي). خدمتن جو ذريعو ڪوڊ GitHub تي موجود آهي: پس منظر и گيٽ وي.

هر هڪ خدمتن جي حيثيت کي جانچڻ جي قابل ٿي، هڪ بهار جو عمل ڪندڙ شامل ڪيو ويو آهي انهن جي انحصار ۾. اهو هڪ ٺاهيندو / actuator/health endpoint ۽ هڪ 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"));
    }
}

سروس گيٽ وي

گيٽ وي درخواست کي اڳتي وڌائيندو پس منظر سروس ڏانهن، ان کي هيٺين معلومات سان گڏ ڪندي:

  • گيٽ وي جي سڃاڻپ. اهو ضروري آهي ته اهو ممڪن آهي ته گيٽ وي جي هڪ مثال کي ٻئي کان سرور جي جواب سان فرق ڪرڻ
  • ڪجھ ”راز“ جيڪي ادا ڪندا ھڪ اھم پاسورڊ جو ڪردار

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 - ھدايتون ٺاھڻ ۽ ايپليڪيشن هلائڻ لاءِ. اڳيون، توهان تصوير ٺاهي سگهو ٿا، ان کي اپلوڊ ڪريو تصويري رجسٽري (نمبر. ڊڪس ايڇ) ۽ توهان جي مائڪرو سروس کي ڪنهن به ڊاکر ٿيل ماحول ۾ هڪ حڪم ۾ ترتيب ڏيو.

Dockerfile

تصوير جي سڀ کان اهم خاصيتن مان هڪ آهي ان جي سائيز. هڪ ٺهيل تصوير هڪ ريموٽ مخزن مان تيزيءَ سان ڊائون لوڊ ڪندي، گهٽ جاءِ وٺي، ۽ توهان جي خدمت تيزيءَ سان شروع ٿيندي. ڪنهن به تصوير کي بنيادي تصوير جي بنياد تي ٺهيل آهي، ۽ اهو سڀ کان وڌيڪ minimalistic اختيار چونڊڻ جي صلاح ڏني وئي آهي. ھڪڙو سٺو اختيار آھي الپائن، ھڪڙي مڪمل لينڪس تقسيم گھٽ ۾ گھٽ پيڪيجز سان.

شروع ڪرڻ لاءِ، اچو ته هڪ 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 MB تصوير آهي (جنهن مان بنيادي JDK تصوير 340 MB تي قبضو ڪيو). ۽ سڀ حقيقت جي باوجود ته اسان جي منصوبي ۾ طبقن هڪ آڱر تي شمار ڪري سگهجي ٿو. اسان جي تصوير جي سائيز کي گھٽائڻ لاء:

  • اسان گھڻ-قدم اسيمبلي استعمال ڪندا آهيون. پهرين قدم ۾ اسان پروجيڪٽ ٺاهينداسين، ٻئي قدم ۾ اسان JRE کي انسٽال ڪنداسين، ۽ ٽئين قدم ۾ اسان ان کي هڪ نئين صاف الپائن تصوير ۾ نقل ڪنداسين. مجموعي طور تي، صرف ضروري اجزاء حتمي تصوير ۾ هوندا.
  • اچو ته استعمال ڪريون جاوا جي modularization. جاوا 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 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 خدمتن لاء آهي)

مٿين مسئلن کي حل ڪرڻ لاءِ، اتي ڪيترائي حل آھن جھڙوڪ Docker Swarm، Nomad، Kubernetes يا OpenShift. جيڪڏهن سڄو سسٽم جاوا ۾ لکيل آهي، توهان بهار جي بادل ڏانهن ڏسي سگهو ٿا (سٺو مضمون).

В ايندڙ حصو مان ان بابت ڳالهائيندس ته مون ڪبرنيٽس کي ڪيئن سيٽ ڪيو ۽ پروجيڪٽ کي گوگل ڪبرنيٽس انجڻ تي لڳايو.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو