از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
Spring Boot و Flask Microservice Discovery با Netflix Eureka
سرفصلهای مطلب
معرفی
در این راهنما، ما از آن استفاده خواهیم کرد نتفلیکس اورکا، یک سرویس کشف میکروسرویس برای ترکیب میکروسرویس 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 – سرویس کاربر نهایی در 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
، می توانیم ثبت آن را مشاهده کنیم روی سرور:
حالا بیایید جلو برویم و 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
، ثبت شده و آماده دریافت درخواست ها است:
فراخوانی سرویس 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