وبلاگ رسانگار
با ما حرفه ای باشید

سرور مجازی NVMe

Spring Boot و Flask Microservice Discovery با Netflix Eureka

0 19
زمان لازم برای مطالعه: 8 دقیقه


معرفی

در این راهنما، ما از آن استفاده خواهیم کرد نتفلیکس اورکا، یک سرویس کشف میکروسرویس برای ترکیب میکروسرویس Spring Boot با میکروسرویس Flask، خدمات پل زدنی که در زبان‌ها و چارچوب‌های برنامه‌نویسی کاملاً متفاوت نوشته شده‌اند.

ما در حال ساخت دو سرویس خواهیم بود – The سرویس کاربر نهایی، که یک سرویس Spring Boot برای کاربر نهایی است که داده ها را جمع آوری کرده و به سرویس جمع آوری داده ها – یک سرویس پایتون که از پانداها برای انجام تجمیع داده ها استفاده می کند و یک پاسخ JSON را به آن برمی گرداند سرویس کاربر نهایی.

کشف سرویس نتفلیکس Eureka

هنگامی که از یک پایگاه کد یکپارچه به یک معماری مبتنی بر میکروسرویس تغییر می‌دهید، نتفلیکس ابزارهای زیادی را ساخت که به آنها کمک کرد کل معماری خود را بازسازی کنند. یکی از راه حل های داخلی که متعاقباً در دسترس عموم قرار گرفت به نام شناخته می شود اورکا.

نتفلیکس اورکا هست یک کشف خدمات ابزار (همچنین به عنوان یک سرور جستجو یا رجیستری خدمات) به ما امکان می دهد چندین میکروسرویس را ثبت کنیم و مسیریابی درخواست را بین آنها مدیریت کنیم.

این یک هاب مرکزی است که هر سرویس در آن ثبت می شود و هر یک از آنها از طریق هاب با بقیه در ارتباط هستند. به جای ارسال تماس های REST از طریق نام هاست و پورت ها – ما این را به Eureka واگذار می کنیم و به سادگی نام از خدمات، همانطور که در هاب ثبت شده است.

برای رسیدن به این هدف، یک معماری معمولی از چند عنصر تشکیل شده است:

معماری میکروسرویس یورکا

می‌توانید سرور Eureka را به هر زبانی که دارای بسته‌بندی Eureka است، جدا کنید، هرچند، این کار به طور طبیعی در جاوا و از طریق Spring Boot انجام می‌شود، زیرا این پیاده‌سازی اصلی ابزار با پشتیبانی رسمی است.

هر سرور Eureka می تواند ثبت نام کند ن مشتریان Eureka، که هر کدام معمولاً یک پروژه جداگانه هستند. اینها همچنین می توانند در هر زبان یا فریم ورکی انجام شوند، بنابراین هر میکروسرویس از آنچه برای وظیفه خود مناسب است استفاده می کند.

ما دو مشتری خواهیم داشت:

  • سرویس کاربر نهایی (کلاینت Eureka مبتنی بر جاوا)
  • سرویس جمع آوری داده ها (کلاینت Eureka مبتنی بر پایتون)

از آنجایی که Eureka یک پروژه مبتنی بر جاوا است که در اصل برای راه‌حل‌های Spring Boot در نظر گرفته شده است – این پروژه یک پروژه ندارد. رسمی پیاده سازی برای پایتون با این حال، ما می توانیم از یک پوشش پایتون مبتنی بر جامعه برای آن استفاده کنیم:

با در نظر گرفتن آن، بیایید یک را ایجاد کنیم سرور Eureka اولین.

ایجاد سرور Eureka

ما از Spring Boot برای ایجاد و نگهداری سرور Eureka خود استفاده خواهیم کرد. بیایید با ایجاد یک دایرکتوری برای میزبانی سه پروژه خود و در داخل آن یک دایرکتوری برای سرور خود شروع کنیم:

$ mkdir eureka-microservices
$ cd eureka-microservices
$ mkdir eureka-server
$ cd eureka-server

این eureka-server دایرکتوری خواهد بود root دایرکتوری سرور Eureka ما. شما می توانید یک پروژه Spring Boot را در اینجا از طریق CLI شروع کنید:

$ spring init -d=spring-cloud-starter-eureka-server

به طور متناوب، می توانید استفاده کنید Spring Initializr و شامل سرور Eureka وابستگی:

بهار اولیه سرور یورکا

اگر قبلاً پروژه ای دارید و فقط می خواهید وابستگی جدید را اضافه کنید، اگر از Maven استفاده می کنید، اضافه کنید:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka-server</artifactId>
    <version>${version}</version>
</dependency>

یا اگر از Gradle استفاده می کنید:

implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-eureka-server', version: ${version}

صرف نظر از نوع اولیه سازی – سرور Eureka به a نیاز دارد تنها حاشیه نویسی به عنوان یک سرور علامت گذاری شود.

در شما EndUserApplication کلاس فایل، که نقطه ورود ما با @SpringBootApplication حاشیه نویسی، ما فقط یک را اضافه می کنیم @EnableEurekaServer:

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String() args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

پورت پیش فرض برای سرورهای Eureka است 8761، و همچنین توسط تیم بهار توصیه می شود. اگرچه، برای اندازه گیری خوب، اجازه دهید آن را در application.properties فایل نیز:

server.port=8761

با انجام این کار، سرور ما آماده اجرا است. اجرای این پروژه سرور Eureka را راه اندازی می کند که در آدرس موجود است localhost:8761:

سرور eureka

توجه داشته باشید: بدون ثبت هیچ گونه خدمات، Eureka ممکن است به اشتباه ادعای یک را داشته باشد ناشناخته نمونه بالاست

ایجاد مشتری Eureka – سرویس کاربر نهایی در Spring Boot

اکنون، با چرخاندن سرور ما و آماده ثبت خدمات، بیایید جلو برویم و خود را بسازیم سرویس کاربر نهایی در چکمه بهار. این یک نقطه پایانی دارد که داده‌های JSON را در مورد a می‌پذیرد دانشجو. سپس این داده ها به صورت JSON برای ما ارسال می شود سرویس جمع آوری داده ها که آمار کلی نمرات را محاسبه می کند.

در عمل ، این عملیات با عملیات بسیار پر کار جایگزین می شود ، که منطقی است که در کتابخانه های اختصاصی پردازش داده ها انجام شود و استفاده از سرویس دیگری را توجیه می کند ، نه اینکه آنها را انجام دهند. روی همان یکی

همانطور که گفته شد، بیایید به عقب برگردیم و یک دایرکتوری برای خود ایجاد کنیم سرویس کاربر نهایی:

$ cd..
$ mkdir end-user-service
$ cd end-user-service

در اینجا، بیایید یک پروژه جدید را از طریق CLI شروع کنیم، و آن را شامل کنیم spring-cloud-starter-netflix-eureka-client وابستگی ما همچنین اضافه می کنیم web وابستگی زیرا این برنامه در واقع با کاربر روبرو خواهد شد:

$ spring init -d=web, spring-cloud-starter-netflix-eureka-client

به طور متناوب، می توانید استفاده کنید Spring Initializr و شامل مشتری اورکا دیسکاوری وابستگی:

کلاینت بهار اولیه یورکا

اگر از Maven استفاده می کنید، موارد زیر را اضافه کنید:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    <version>${version}</version>
</dependency>

یا اگر از Gradle استفاده می کنید:

implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-netflix-eureka-client', version: ${version}

صرف نظر از نوع اولیه سازی – برای علامت گذاری این برنامه به عنوان مشتری Eureka، ما به سادگی آن را اضافه می کنیم @EnableEurekaClient حاشیه نویسی برای کلاس اصلی:

@SpringBootApplication
@EnableEurekaClient
public class EndUserServiceApplication {
    public static void main(String() args) {
        SpringApplication.run(EndUserServiceApplication.class, args);
    }
    
    @LoadBalanced
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

توجه داشته باشید: به طور متناوب، می توانید از @EnableDiscoveryClient حاشیه نویسی، که حاشیه نویسی گسترده تری است. می تواند به اورکا، کنسول مراجعه کند یا نگهبان باغ وحش، بسته به روی کدام ابزار مورد استفاده قرار می گیرد

ما همچنین a را تعریف کرده ایم @Bean اینجا، تا بتوانیم @Autowire را RestTemplate بعد روی در کنترلر ما این RestTemplate برای ارسال الف استفاده خواهد شد POST درخواست به سرویس جمع آوری داده ها. این @LoadBalanced حاشیه نویسی نشان می دهد که ما RestTemplate باید از الف استفاده کرد RibbonLoadBalancerClient هنگام ارسال درخواست ها

از آنجایی که این برنامه یک مشتری Eureka است، ما می خواهیم به آن پاسخ دهیم نام برای رجیستری سایر خدمات در هنگام تکیه به این نام اشاره خواهند کرد روی آی تی. نام در تعریف شده است application.properties یا application.yml فایل:

server.port = 8060
spring.application.name = end-user-service
eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka
server:
    port: 8060
spring:
    application:
        name: end-user-service
eureka:
    client:
      serviceUrl:
        defaultZone: http://localhost:8761/eureka/

در اینجا، ما پورت را برای برنامه خود تنظیم کرده ایم، که Eureka باید بداند تا درخواست ها را به آن هدایت کند. ما همچنین نام سرویس را مشخص کرده ایم که توسط سایر سرویس ها به آن ارجاع داده می شود.

اجرای این برنامه باعث ثبت سرویس در سرور Eureka می شود:

INFO 3220 --- (           main) o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started روی port(s): 8060 (http) with context path ''
INFO 3220 --- (           main) .s.c.n.e.s.EurekaAutoServiceRegistration : Updating port to 8060
INFO 3220 --- (nfoReplicator-0) com.netflix.discovery.DiscoveryClient    : DiscoveryClient_END-USER-SERVICE/DESKTOP-8HAKM3G:end-user-service:8060 - registration status: 204
INFO 3220 --- (           main) c.m.e.EndUserServiceApplication          : Started EndUserServiceApplication in 1.978 seconds (JVM running for 2.276)
INFO 3220 --- (tbeatExecutor-0) com.netflix.discovery.DiscoveryClient    : DiscoveryClient_END-USER-SERVICE/DESKTOP-8HAKM3G:end-user-service:8060 - Re-registering apps/END-USER-SERVICE
INFO 3220 --- (tbeatExecutor-0) com.netflix.discovery.DiscoveryClient    : DiscoveryClient_END-USER-SERVICE/DESKTOP-8HAKM3G:end-user-service:8060: registering service...
INFO 3220 --- (tbeatExecutor-0) com.netflix.discovery.DiscoveryClient    : DiscoveryClient_END-USER-SERVICE/DESKTOP-8HAKM3G:end-user-service:8060 - registration status: 204

حالا اگر بازدید کنیم localhost:8761، می توانیم ثبت آن را مشاهده کنیم روی سرور:

سرویس ثبت شده سرور eureka

حالا بیایید جلو برویم و a را تعریف کنیم Student مدل:

public class Student {
    private String name;
    private double mathGrade;
    private double englishGrade;
    private double historyGrade;
    private double scienceGrade;
    
    
}

برای یک دانش آموز، ما می خواهیم مقداری را محاسبه کنیم آمار خلاصه عملکرد آنها، مانند میانگین، حداقل و حداکثر از نمرات آنها از آنجایی که ما از پانداها برای این کار استفاده خواهیم کرد – از موارد بسیار مفید استفاده خواهیم کرد DataFrame.describe() تابع. بیایید یک GradesResult مدل نیز، که داده های ما را پس از بازگشت از آن نگه می دارد سرویس جمع آوری داده ها:

public class GradesResult {
    private Map<String, Double> mathGrade;
    private Map<String, Double> englishGrade;
    private Map<String, Double> historyGrade;
    private Map<String, Double> scienceGrade;
    
    
}

با انجام مدل‌ها، بیایید یک واقعا ساده بسازیم @RestController که الف را می پذیرد POST درخواست، آن را به صورت a Student و آن را برای تجمیع داده ها خدماتی که هنوز آن را انجام نداده ایم:

@Autowired
private RestTemplate restTemplate;

@RestController
public class HomeController {
    @PostMapping("/student")
    public ResponseEntity<String> student(@RequestBody Student student) {
        GradesResult grades = restTemplate.getForObject("http://data-aggregation-service/calculateGrades", GradesResult.class);

        return ResponseEntity
            .status(HttpStatus.OK)
            .body(String.format("Sent the Student to the Data Aggregation Service: %s \nAnd got back:\n %s", student.toString(), gradesResult.toString()));
    }
}

این @RestController الف را می پذیرد POST درخواست می کند و بدنه خود را به الف تبدیل می کند Student هدف – شی. سپس، ما درخواستی را برای خود ارسال می کنیم data-aggregation-service، که هنوز اجرا نشده است، زیرا ثبت خواهد شد روی Eureka، و ما نتایج JSON آن تماس را در خود بسته بندی می کنیم GradesResult هدف – شی.

توجه داشته باشید: اگر سریال ساز با ساختن مشکل داشته باشد GradesResult شی از نتیجه داده شده، می خواهید آن را با استفاده از جکسون به صورت دستی تبدیل کنید ObjectMapper:

String result = restTemplate.postForObject("http://data-aggregation-service/calculateGrades", student, String.class);
ObjectMapper objectMapper = new ObjectMapper();
GradesResult gradesResult = objectMapper.readValue(result, GradesResult.class);

بالاخره ما print را student به عنوان مثال ما ارسال کرده ایم و همچنین grades به عنوان مثال ما از نتیجه ساختیم.

حالا، بیایید جلو برویم و ایجاد کنیم سرویس جمع آوری داده ها.

ایجاد مشتری Eureka – سرویس جمع آوری داده ها در Flask

تنها جزء گم شده است سرویس جمع آوری داده ها، که الف را می پذیرد دانشجو، در قالب JSON و یک پاندا را پر می کند DataFrame، عملیات خاصی را انجام می دهد و نتیجه را برمی گرداند.

بیایید یک دایرکتوری برای پروژه خود ایجاد کنیم و یک محیط مجازی برای آن راه اندازی کنیم:

$ cd..
$ mkdir data-aggregation-service
$ python3 -m venv flask-microservice

حال برای فعال سازی محیط مجازی، آن را اجرا کنید activate فایل. در ویندوز:

$ flask-microservice/Scripts/activate.bat

در لینوکس/مک:

$ source flask-microservice/bin/activate

ما یک برنامه ساده Flask را برای این کار می‌چرخانیم، بنابراین اجازه دهید وابستگی‌ها را برای Flask و Eureka از طریق نصب کنیم. pip در محیط فعال ما:

(flask-microservice) $ pip install flask pandas py-eureka-client

و اکنون، می توانیم برنامه Flask خود را ایجاد کنیم:

$ touch flask_app.py

حالا، را باز کنید flask_app.py فایل و import کتابخانه های Flask، Pandas و Py-Eureka Client:

from flask import Flask, request
import pandas as pd
import py_eureka_client.eureka_client as eureka_client

ما از Flask و استفاده خواهیم کرد request برای رسیدگی به درخواست های دریافتی و بازگرداندن پاسخ، و همچنین چرخش سرور. ما از پانداها برای جمع آوری داده ها استفاده خواهیم کرد و از آن استفاده خواهیم کرد py_eureka_client برای ثبت برنامه Flask ما در سرور Eureka روی localhost:8761.

بیایید پیش برویم و این برنامه را به عنوان مشتری Eureka تنظیم کنیم و a را پیاده سازی کنیم POST کنترل کننده درخواست برای داده های دانش آموز:

rest_port = 8050
eureka_client.init(eureka_server="http://localhost:8761/eureka",
                   app_name="data-aggregation-service",
                   instance_port=rest_port)

app = Flask(__name__)

@app.route("/calculateGrades", methods=('POST'))
def hello():
    data = request.json
    df = pd.DataFrame(data, index=(0))
    response = df.describe().to_json()
    return response

if __name__ == "__main__":
    app.run(host='0.0.0.0', port = rest_port)

توجه داشته باشید: ما باید تنظیم کنیم host به 0.0.0.0 برای باز کردن آن برای سرویس های خارجی، مبادا فلاسک از اتصال آنها امتناع کند.

این یک برنامه Flask تقریبا مینیمال با یک تک است @app.route(). ما ورودی را استخراج کرده ایم POST درخواست بدن به a data فرهنگ لغت از طریق request.json، پس از آن ما یک DataFrame با آن داده ها

از آنجایی که این دیکشنری اصلا فهرستی ندارد، ما به صورت دستی آن را تنظیم کرده ایم.

در نهایت، ما آن را برگرداندیم describe() نتایج تابع به عنوان JSON. ما استفاده نکرده ایم jsonify اینجا از آنجایی که a برمی گرداند Response شی، نه یک رشته. آ Response شی، هنگامی که به عقب فرستاده می شود حاوی اضافی است \ شخصیت ها:

{\"mathGrade\":...}
vs
{"mathGrade":...}

باید از اینها فرار کرد تا مبادا دستگاه پخش کننده را دور بیندازند.

در init() عملکرد eureka_client، ما URL را برای سرور Eureka خود تنظیم کرده ایم، همچنین نام برنامه/سرویس را برای کشف، و همچنین یک پورت ارائه کرده ایم. روی که در دسترس خواهد بود. این همان اطلاعاتی است که در برنامه Spring Boot ارائه کرده ایم.

حالا بیایید این برنامه Flask را اجرا کنیم:

(flask-microservice) $ python flask_app.py

و اگر سرور Eureka خود را بررسی کنیم روی localhost:8761، ثبت شده و آماده دریافت درخواست ها است:

سرویس ثبت شده سرور eureka

فراخوانی سرویس Flask از سرویس Spring Boot با استفاده از Eureka

با راه‌اندازی هر دو سرویس ما، ثبت‌شده در Eureka و امکان برقراری ارتباط با یکدیگر، بیایید یک POST درخواست از ما سرویس کاربر نهایی، حاوی برخی از داده های دانش آموز است که به نوبه خود a ارسال می کند POST درخواست به سرویس جمع آوری داده ها، پاسخ را بازیابی کنید و برای ما ارسال کنید:

$ curl -X POST -H "Content-type: application/json" -d "{\"name\" : \"David\", \"mathGrade\" : \"8\", \"englishGrade\" : \"10\", \"historyGrade\" : \"7\", \"scienceGrade\" : \"10\"}" "http://localhost:8060/student"

این منجر به پاسخ از سرور به کاربر نهایی می شود:

Sent the Student to the Data Aggregation Service: Student{name='David', mathGrade=8.0, englishGrade=10.0, historyGrade=7.0, scienceGrade=10.0}
And got back:
GradesResult{mathGrade={count=1.0, mean=8.0, std=null, min=8.0, 25%=8.0, 50%=8.0, 75%=8.0, max=8.0}, englishGrade={count=1.0, mean=10.0, std=null, min=10.0, 25%=10.0, 50%=10.0, 75%=10.0, max=10.0}, historyGrade={count=1.0, mean=7.0, std=null, min=7.0, 25%=7.0, 50%=7.0, 75%=7.0, max=7.0}, scienceGrade={count=1.0, mean=10.0, std=null, min=10.0, 25%=10.0, 50%=10.0, 75%=10.0, max=10.0}}

نتیجه

در این راهنما، ما یک محیط میکروسرویس ایجاد کرده‌ایم که در آن یک سرویس متکی است روی دیگری، و آنها را با استفاده از Netflix Eureka متصل کرد.

این سرویس ها با استفاده از چارچوب های مختلف و زبانهای مختلف برنامه نویسی ساخته شده اند – هرچند ، از طریق API های REST ، برقراری ارتباط بین آنها ساده و آسان است.

کد منبع این دو سرویس از جمله سرور Eureka در دسترس است روی GitHub.

(برچسب‌ها به ترجمه)# python



منتشر شده در 1403-01-11 00:18:03

امتیاز شما به این مطلب
دیدگاه شما در خصوص مطلب چیست ؟

آدرس ایمیل شما منتشر نخواهد شد.

لطفا دیدگاه خود را با احترام به دیدگاه های دیگران و با توجه به محتوای مطلب درج کنید