همه چیز درباره فریم ورک gRPC

9 دقیقه زمان مطالعه
1400/09/17
1 نظر

gRPC یک فریم‌ورک (Framework) قدرتمند متن باز (Open source) است که بر پایه Remote Procedure Call (RPC) طراحی شده و می‌تواند در تمامی محیط های توسعه قابل پیاده‌سازی باشد. این تکنولوژی امکان ارتباط و هماهنگی شفاف و راحت بین کلاینت و سرور را فراهم و همچنین ساخت سیستم‌های متصل را ساده‌تر می‌کند از ویژگی های جالب این تکنولوژی می‌توان به اتصال بین سرویس‌ها و تمامی مراکز داده (Data Center) با قابلیت ردیابی (Tracing)، لود بالانسینگ (Load Balancing)، بررسی سطح دسترسی و سلامت سرویس اشاره کرد. این فریم‌ورک همچنین قابلیت اتصال موبایل و مرورگر به سرویس‌های بک-اند (Back End) را دارد.

مزایای اصلی استفاده از فریم‌ورک gRPC

  • کاهش استفاده از شبکه با استفاده از Protobuf binary serialization
  • پشتیبانی از سرور، کلاینت و bi-directional در فرا خوانی‌های سریالی
  • دارای ابزارهای زیاد برای بسیاری از زبان‌های برنامه‌نویسی برای ساختن سرویس‌های قدرتمند
  • جدید، کارایی زیاد و کم حجم
  • پشتیبانی از چند زبان برنامه‌نویسی در یک محیط

جدول ۱ مقایسه فریم‌ورک‌ gRPC با REST

 

 عملکرد gRPC چگونه است؟

با استفاده از تکنولوژی gRPC، اپلیکیشن سمت کلاینت (Client Side) می‌تواند به طور مستقیم یک متد را از سمت سرور (Server Side) و چند دستگاه به طور همزمان فراخوانی کند. به این ترتیب ساختن اپلیکیشن و سرویس‌های توزیع‌پذیر برای توسعه‌دهنده راحت‌تر می‌شود. مانند بسیاری از سیستم‌های PRC، سیستم gRPC، در ابتدا سرویس را شناسایی می‌کند و سپس متدها به همراه پارامترهای درون آن و return typeهایی که از راه دور (Remote) فراخوانی می‌شوند را تشخیص می‌دهد.

  • سمت سرور: در ابتدا سرور یک رابط کاربری را پیاده‌سازی و سپس gRPC را برای رسیدگی به درخواست‌های  سمت کلاینت اجرا می‌کند.
  • سمت کلاینت: سمت کلاینت یک stub دارد که همانند سمت سرور عمل می‌کند.

در این تکنولوژی، کدهای سمت کلاینت و سرور می‌توانند در محیط‌های مختلف اجرا شوند و به راحتی با یکدیگر صحبت کنند (از سرورهای داخلی گوگل به دسکتاپ شخصی شما). علاوه بر این می‌توانید با تمامی زبان‌های برنامه‌نویسی که از gRPC پشتیبانی می‌کنند، این سروس‌ها را بنویسید. به طور مثال می‌توانید برای سمت سرور از زبان جاوا (Java) و برای سمت کلاینت از زبان‌های روبی (Ruby)، پایتون (Python) و گو (Go) استفاده کنید.

 عملکرد gRPC چگونه است؟

 

چه زبان‌هایی از فریم‌ورک gRPC پشتیبانی می‌کنند؟

در جدول زیر زبان‌های برنامه‌نویسی از فریم‌ورک gRPC پشتیبانی می‌کنند را مشاهده می‌کنید:

 چه زبان‌هایی از فریم‌ورک gRPC پشتیبانی می‌کنند؟

 

برای درک بهتر gRPC به workflow زیر توجه کنید:
 workflow در فریم ورک gRPC

از نظر ساختار، gRPC یک لایه فریم‌ورک است که بین لایه اپلیکیشن و انتقال (transport) قرار دارد. در حقیقت این تکنولوژی ساخت و فراخوانی سرویس‌های API که بر پایه PRC هستند را برای توسعه‌دهندگان راحت‌تر می‌کند. همانطور که اشاره شد، این تکنولوژی از پروتوکل HTTP/2 استفاده می‌کند، بنابراین نسبت به سرویس‌های بر پایه پروتوکل HTTP/1.1، بازدهی بهتری دارد.


 معماری فریم ورک gRPC

طی یک مقایسه بین gRPC و HTTP.1/JSON، این تکنولوژی توانست سه برابر کارایی بهتری نسبت به HTTP1.1/JSON نشان دهد.


کدام تکنولوژی عملکرد بهتری دارد؟

ساختار gRPC به چه شکل است؟

مانند بیشتر سیستم‌های PRC، gRPC نیز مبتنی بر تعیین سرویس‌ها و مدل‌هایی کار می‌کند که از راه دور به همراه پارامترها و نوع‌های بازگشتی آن فرا خوانی می‌شود. به صورت پیش‌فرض gRPC از پروتکل‌های بافر (Protocol Buffers) به عنوان زبان مشخص کردن کاربر (Interface Definition Language (IDL))، برای شناسایی service interfaceها و ساختار پیام‌ها استفاده می‍شود.

پروتکل بافر (Protocol Buffers) چیست؟

پروتکل بافرز، یک روش سریالیزه کردن اطلاعات است که توسط گوگل برای استفاده داخلی توسعه یافته بود که بعداً برای استفاده عموم منتشر شد. در این روش برای برقرار کردن ارتباطات بین برنامه‌ها توسط سیم (wire) یا ذخیره کردن اطلاعات استفاده می‌شود. همچنین شامل یک زبان توصیف میانی و یک کامپایلر است که کدهای مختلف برای زبان‌های برنامه‌نویسی مختلف از این زبان توصیف میانی تولید می‌کند.

 

پروتکل بافر (Protocol Buffers) چیست؟

 

ساختار پیام‌های Protocol Buffers به چه شکل است؟

این پیام‌ها شامل مجموعه‌ای از key-value pairها است. قسمت باینری پیام، شماره فیلدی را به عنوان کلید (key) استفاده می‌کند. نام و نوع اعلان شده برای هر فیلد فقط در انتهای رمزگشایی (decoding) با ارجاع به نوع پیام قابل شناسایی است. وقتی پیام کد‌گذاری شد، key و value به جریان‌های بایت متصل می‌شوند. بعد از اینکه پیام رمزگشایی شد، تجزیه‌کننده پیام (parser) باید قابلیت این را داشته باشد که اگر نتوانست فیلد را تشخیص دهد از آن عبور کند؛ از این رو، فیلدهای جدید بدون اینکه برنامه‌های قبلی را که اطلاعاتی درباره آن‌ها نداریم خراب کنند، می‌توانند به پیام اضافه شوند.

در انتها «key» به ازای هر pair در نوشتن فرمت پیام دارای دو مقدار است. شماره فیلد از فایل .proto به علاوه نوع پیام شما که نشان دهد اطلاعات کافی برای یافتن طول مقدار (value) را دارد. در اکثر پیاده‌سازی‌ها در زبان‌های مختلف این key به عنوان یک برچسب شناخته می‌شود. انواع wireهای موجود به شرح زیر است:

انواع wireهای موجود

درک بهتر ساختار بافر با مثال:

سه بیت آخر را می‌گیرید تا wire type(0) را بدست آورید، سپس سه بیت را به راست تغییر دهید تا عدد فیلد ۱ را به دست آورید. بنابراین اکنون می‌دانید که مقدار فیلد ۱ است و مقدار زیر یک نوع متغیر است. همانطور که مشاهده می‌کنید دو بایت بعدی عدد ۱۵۰ را ذخیره می‌کنند. این نکته را در نظر بگیرید که برای استفاده از پروتکل بافرها نیازی به درک ساختار این پیام‌ها ندارید.

برای استفاده از protocol bufferها نیازی به درک ساختار این پیام‌ها ندارید.

نحوه کار با پروتکل بافرها:

به طور پیشفرض gRPC از پروتکل بافرها استفاده می‌کند. به طور کلی، مکانیزم سیستم‌های متن‌باز گوگل برای ساختار دادن به داده (همینطور قابلیت سازگار بودن با فرمتهای مختلف داده مثل JSON) است.

نحوه کار با بافرها (Buffers)

اولین نکته مهمی که هنگام کار با پوتکل بافرها باید در نظر بگیرید، ساختار دادهایی است که می‌خواهید در فایل .proto مرتب (serialize) کنید. ساختار داده‌های این پروتکل بر اساس message است که هر پیام یک logical record کوچکی از اطلاعات است؛ این اطلاعات شامل مجموعه‌ای از name-value pair ها به نام fields  را تشکیل می‌دهند. به مثال ساده زیر توجه کنید:

}message Person ;string name = 1 ; int32 id = 2 ;bool has_ponycopter = 3

{

در ادامه وقتی ساختار داده خود را مشخص کردید از کامپایلر protocol buffer (protoc) برای ساختن کلاسهای اولیه سطح دسترسی داده (data access classes) در زبان برنامه نویسی مورد نظر خود استفاده کنید. اینها دسترسی‌های ساده‌ای را برای هر زمینه فراهم می‌کنند؛ به طور مثال توابع ()name() and set_name علاوه بر متد serialize/parse می‌توانند کل ساختار را به صورت byte خام داشته باشند.
برای درک بهتر این مورد اگر شما زبان برنامه نویسی C++ را برای توسعه انتخاب کرده باشید،  کامپایلر مثال بالا را برای فراخوانی کلاس person اجرا کنید؛ سپس می‌توانید از این کلاس در اپلیکیشن خود برای پر کردن (populate)، مرتب‌سازی (serialize) و بازیابی (retrieve) کلاس person  استفاده کنید.
شما می‌توانید سرویسهای gRPC را در فایلهای معمولی .proto تعریف کنید. در gRPC پارامترها و return typeها به عنوان protocol buffer message  مشخص و تعریف می‌شوند:

 

// The greeter service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

}message Person   ;string name = 1 ; int32 id = 2  ;bool has_ponycopter = 3

{


// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;

gRPC با استفاده از protoc به همراه یک gRPC plugin مخصوص برای ساختن کدهای فایل proto شما استفاده می‌کند؛ به این شکل که شما gRPC تولید شده سمت کلاینت، سرور و همچنین protocol buffer code را برای پر کردن (populate)، مرتب‌سازی و بازیابی (retrieve) نوع پیام (message types) دریافت می‌کنید.
gRPC به شما امکان  می‌دهد چهار نوع سرویس را تعریف کنید
•Unary PRCs:  clinet یک درخواست به سمت سرور ارسال می‌کند و همان سرویس ارسال شده را دریافت می‌کند،مانند یک function call معمولی 

rpc SayHello(HelloRequest) returns (HelloResponse);

•Server streaming PRCs:  clinet یک درخواست به سمت سرور ارسال می‌کند و یک جریان برای خواندن پیاپی پیام ها دریافت می‌کند. کلاینت همه پیام‌ها را تا وقتی که پیامی دیگر نمانده باشد می‌خواند. فریم‌ورک gRPC تضمین می‌کند که اولویت‌بندی پیام‌ها توسط یک PRC call معمولی بدون هیچ گونه مشکل امکان پذیر است

rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);

•Client streaming RPCs:  client پیام های پی در پی می‌نوسید و به سمت سرور ارسال می‌کند و این روند تکرار می‌شود تا وقتی که کلاینت نوشتن پیام را تمام کند، از اینجا به بعد منتظر سرور می‌شود تا پیام‌ها بخواند و آن‌ها را برگرداند. در این مورد نیز gRPC تضمین می‌کند که اولویت‌بندی پیام‌ها توسط یک PRC call معمولی بدون هیچ گونه مشکل امکان پذیر است.

rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);

•Bidirectional streaming: هر دو سمت (کلاینت و سرور) از پیام‌های پی در پی استفاده می‌کنند. هر دو سمت توانایی خواندن و نوشتن پیام بر اساس اولویت دلخواه را دارند به طور مثال، سمت سرور در ابتدا می‌تواند صبر کند تا پیام از سمت کلاینت دریافت شود و بعد از آن پیام خود را بنویسد یا می‌تواند ابتدا پیام را بخواند سپس آن را بنویسد. همچنین قابلیت این را دارد که از ترکیب این دو به طور همزمان استفاده کند. ترتیب پیام‌ها در هر جریان حفظ می‌شود.

rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
جمع بندی

با توجه به پیچیدگی نرم افزار و گستردگی زبان‌های برنامه‌نویسی دنیای API همیشه دچار چالش‌های زیادی بوده است.در این مقاله سعی کردیم توضیح مختصری از مدل gRPC  به شما بدهیم. در مقالات بعدی آسا این تکنولوژی را به صورت تخصصی‌تر مورد بررسی قرار خواهیم داد. همینطور به طور کامل نحوه استفاده و مقایسه آن با دیگر روش‌های سرویس‌های API را مورد نقد و بررسی قرار می‌دهیم.


منابع:https://grpc.io
https://devopedia.org/grpc

امتیاز شما به این مقاله:
نویسنده: توسعه‌دهنده نرم‌افزاری که توجه به جزئیات، حافظه قوی و ارتباطات خوب بارزترین ویژگی‌های شخصیتی‌اش هستند.

مطالب مرتبط