ویرگول
ورودثبت نام
Adnan Kamali | عدنان کمالی
Adnan Kamali | عدنان کمالیمن عدنان کمالی چاهوئی هستم و برنامه نویس و درحال تبدیل شدن به مهندس کامپیوتر
Adnan Kamali | عدنان کمالی
Adnan Kamali | عدنان کمالی
خواندن ۴ دقیقه·۴ ماه پیش

چطوری ازgRPC توی فلاتر استفاده کنیم (پارت اول)

کار با gRPC در فلاتر
کار با gRPC در فلاتر
  • در پارت اول میخوام یکم درمورد gRPC توضیح بدم و یک gRPC رو با پایتون بیارم بالا و در پارت دوم از طریق اپلیکیشن فلاتری متودی که توی پایتون ساختیم رو با فلاتر فراخوانی کنیم

اصلا RPC چی هست که gRPC چی باشه؟

RPC یا Remote Procedure Call به معنی فراخوانی تابع از راه دور هست که توسعه دهنده ها میتونن بجای ارسال پیام های json که بر پایه http ورژن یک هست بیان و متود ها یا توابع هایی رو تعریف کنند و خیلی راحت فراخوانی کنند.

حالا gRPC چیه؟

یک چارچوب یا همون framework متن باز برای سیستم های RPC با کارایی بالا که توسط گوگل توسعه یافته

این gRPC چطوری کار میکنه؟

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

مرحله دوم هم تولید کد های هر زبان هست که زبان های مختلف از جمله دارت و پایتون رو پشتیبانی میکنه که برای تولید کد هر زبان نیاز به ابزار protoc داریم که بیاد این پروتوکلی که نوشتیم رو به زبان های مقصد تبدیل کنه

این gRPC چه مزیتی داره؟

کارایی بالا که از HTTP/2 استفاده میکنه و مقادیر رو بصورت باینری جابه جا میکنه که حجم داده و سرعت انتقال نسب به json بالاتره

از زبان های مختلف استفاده میکنه، اینطوریه که شما یک proto مینویسید و برای زبان های مختلف خروجی میگرید

gRPC کجا ها استفاده میشه؟

معمولا gRPC توی میکروسرویس ها که نیاز به سرعت زیاد جهت جابه جایی انتقال و توی میکروسرویس ها یا هرجایی که از چند زبان برنامه نویسی استفاده میشه gRPC کمک کننده هست چون فقط یک پروتکل داری و استفاده میکنی

بریم یک پروتکل بافر ساده باهم بسازیم

خب من فایلی به نامه helloworld.proto رو میسازم و توش پروتکل هامو تعریف میکنم

syntax = "proto3"; package helloworld; service Greeter { rpc SayHello (HelloRequest) returns (HelloReply); } message HelloRequest { string name = 1; } message HelloReply { string message = 1; }

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

اسم پکیجم رو گفتم که این مورد توی ایمپورت کردن کد تولید شده بهمون کمک میکنه که پکیج ما helloworld هست

اومدم یک سرویس Greeter نوشتم که یک متود rpc به نام SayHello داره که ورودی این متود HelloRequest و خروجی اون HelloReply هست

یک پیام یا بهتره بگم یه ساختار داده به نام HelloRequest تعریف کردم که فقط یک فیلد داره و اون هم name هست از نوع string و ایندکس یک که برای سریالایز شدن استفاده میشه

  • این ایندکس باید یکتا باشه و بهتره از یک شروع بشه

یک پیام پاسخ به نام HelloReply تعریف کردم که message رو که string هست به عنوان پاسخ بر میگردونه

تولید کد برای پایتون از روی پروتکلی که ساختیم

برای تولید کد اول از همه باید کامپایلر پروتکل بافر یعنی ptoco رو نصب که کنیم که از لینک گیت هاب قابل دانلود هست و بعد برای پایتون پکیج های grpcio, grpcio-tools با دستور pip نصب میکنیم و بعد دستور زیر رو اجرا میکنیم توی همون پوشه ای که helloworld.proto هست

python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. helloworld.proto
  • -I. می‌گه که فایل .proto در مسیر جاری هست.

  • --python_out=. فایل‌های protobuf (ساختار پیام‌ها) را تولید می‌کنه.

  • --grpc_python_out=. کدهای لازم برای gRPC client/server را تولید می‌کنه.

  • helloworld.proto اسم فایل شماست.

بعد از اجرای دستور، دو فایل جدید کنار فایل proto تولید می‌شن:

  1. helloworld_pb2.py: تعریف پیام‌ها (HelloRequest، HelloReply)

  2. helloworld_pb2_grpc.py: تعریف سرویس gRPC (GreeterStub، GreeterServicer)

راه اندازی سرویسمون توی پایتون

این کد راه اندازی هست و خط به خط بهت میگم چیکار کردم

from concurrent import futures import grpc import helloworld_pb2, helloworld_pb2_grpc class Greeter(helloworld_pb2_grpc.GreeterServicer): def SayHello(self, request, context): return helloworld_pb2.HelloReply(message=f"Hello, {request.name}!") def serve(): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) server.add_insecure_port('[::]:50051') server.start() server.wait_for_termination() if name == '__main__': serve()

تو خط اول ماژول concurrent.futures یکی از ابزارهای استاندارد پایتون برای مدیریت thread و pool از thread‌هاست.
اینجا برای راه‌اندازی سرور gRPC با امکان پردازش چند درخواست هم‌زمان (multi-threading) استفاده می‌شه.

ماژول اصلی grpc به همراه کد های تولید شده رو ایمپورت کردم

یه کلاس ساختم به اسم Greeter و میاد از سرویسی که ساختم توی proto و تولید شده توی فایل helloworld_pb2_grpc که به نام GreeterServicer ارث بری میکنم و متودی که توی proto تعریف کردم رو برای خودم تعریف میکنم که متود SayHello بود

  • request: شی‌ای از نوع HelloRequest که کلاینت فرستاده.

  • context: اطلاعات اضافه مربوط به وضعیت فراخوانی (مثلاً deadline، metadata، status و ...).

  • در پاسخ، یک HelloReply تولید می‌کنیم و داخلش پیام Hello, {name}! رو قرار می‌دیم.

مثلاً اگر کلاینت "name = "Adnan Kamali بفرسته، پاسخ سرور می‌شه: "!Hello, Adnan Kamali"

تابعی به نام serve تعریف شده که کارش راه‌اندازی سرور gRPC هست و یک شیء سرور gRPC می‌سازیم و بهش یک thread pool با حداکثر 10 thread می‌دیم تا بتونه هم‌زمان چند درخواست رو هندل کنه.

توی خط 11 کلاس Greeter که ساختیم رو به سرور gRPC اضافه میکنیم و این خط دقیقا همون لحظه ایه که میگیم اگه کسی RPC به اسم SayHello صدا زد، تابع SayHello رو اجرا کن

خط 12 سرور میاد روی پورت 50051 روی تمامی آی پی های ماشین شنود میشه

خط 13 سرویس شروع و در خط 14 سرور تا زمانی که دستی بسته نشه با همون ctrl+c درحالت اجرا میمونه

امیدوارم تا اینجا مطلب براتون روشن شده باشه و اگر بکند کار نیستید حداقل درمورد gRPC یکم اطلاعاتتون بیشتر شده باشه و در پارت دوم درمورد چطوری فراخوانی تابع SayHello با استفاده از فلاتر رو توضیح میدم

عدنان کمالی | Adnan Kamali

grpcبرنامه نویسیگیت هابفلاتر
۰
۰
Adnan Kamali | عدنان کمالی
Adnan Kamali | عدنان کمالی
من عدنان کمالی چاهوئی هستم و برنامه نویس و درحال تبدیل شدن به مهندس کامپیوتر
شاید از این پست‌ها خوشتان بیاید