gRPC یک فریمورک متنباز برای برقراری ارتباط سریع و کارآمد میان سرویسهاست که به برنامهها اجازه میدهد متدهای سرویسهای دیگر را فراخوانی کنند و پاسخ بگیرند. این فریمورک با استفاده از Protocol Buffers برای تبادل داده، تعریف قراردادهای مشخص و پشتیبانی از ارتباط جریانی، گزینهای مناسب برای ارتباط میان میکروسرویسها بهشمار میرود.
در ادامه، با شیوهی کار، ساختار و ویژگیهای gRPC آشنا میشویم و تفاوتهای آن با REST را بررسی میکنیم. همچنین، به اهمیت زیرساختهای مقیاسپذیر و تاثیر خرید سرور ابری در میزبانی کارآمد و بهینهی این نوع سرویسها نگاهی میاندازیم تا دید جامعی برای انتخاب مناسبترین راهکار ارتباطی به دست آورید.
gRPC چیست؟
gRPC به مفهوم فراخوانی روال از راه دور (Remote Procedure Call یا RPC) اشاره دارد. در این روش، برنامه متدی را در برنامهای دیگر اجرا میکند؛ هرچند شکل فراخوانی در کد، شبیه فراخوانی یک متد محلی است. برای مثال، سرویس سفارش میتواند متد بررسی موجودی را در سرویس انبار فراخوانی کند.
گوگل این فناوری را با تکیهبر تجربهی سامانهی داخلی Stubby توسعه داد و در سال ۲۰۱۵ آن را بهشکل متنباز معرفی کرد. توسعهدهندگان از آن برای ساخت رابط برنامهنویسی کاربردی (API) و ارتباط میان برنامههایی با زبانهای مختلف استفاده میکنند.
ویژگیهای gRPC
ویژگیهای gRPC هم به انتقال پیام ارتباط دارند و هم به شیوهی توسعهی سرویس. در ادامه، مهمترین قابلیتهای آن را بررسی میکنیم.
۱. کارایی در انتقال داده
قالب باینری Protocol Buffers برای انتقال و پردازش دادههای ساختیافته طراحی شده است. پیامها اغلب در مقایسه با JSON معادل، حجم کمتری دارند.
۲. پشتیبانی از ارتباط جریانی
در استریمینگ (Streaming)، کلاینت یا سرور میتواند چند پیام را در یک فراخوانی بفرستد. این قابلیت برای جریان مستمر داده و ارتباطات بلادرنگ کاربرد دارد.
۳. کاهش کدهای تکراری
ابزارهای تولید کد، بخشهای مربوط به پیامها و ارتباط کلاینت و سرور را از قرارداد مشترک میسازند. توسعهدهنده بیشتر روی منطق سرویس کار میکند.
۴. استقلال از زبان برنامهنویسی
کلاینت و سرور لازم نیست زبان یکسانی داشته باشند. برای مثال، کلاینت Python میتواند با سرور Java ارتباط بگیرد، به شرط آنکه قرارداد پیامها را رعایت کند.
۵. امنیت ارتباط
با TLS دادههای در حال انتقال رمزنگاری میشوند و سازوکارهای احراز هویت هم هویت طرف ارتباط را بررسی میکنند. توسعهدهنده تنظیمات امنیتی و مجوزها را متناسب با سرویس پیکربندی میکند.
ساختار gRPC و شیوه کار آنها
ساختار gRPC از قرارداد سرویس، پیامها، کد کلاینت، پیادهسازی سرور و لایهی انتقال تشکیل میشود. این اجزا با هم کار میکنند تا برنامه بتواند متد سرویس دیگری را از راه شبکه فراخوانی کند.
Protocol Buffers .۱: تعریف و سریالسازی پیامها
پروتکل بافرز (Protocol Buffers یا Protobuf) ابزار تعریف و سریالسازی دادههای ساختیافته است. در فایل .proto، نوع پیام و فیلدهای آن را مشخص میکنید. برای مثال پیام درخواست میتواند شناسهی محصول و پیام پاسخ، تعداد موجودی آن را داشته باشد.
سریالسازی (Serialization) یعنی تبدیل دادههای برنامه به قالبی انتقالپذیر. Protobuf بهشکل معمول پیام را به بایتهای باینری تبدیل میکند. در مقصد، کتابخانهی مربوط، بایتها را میخواند و دوباره پیام در برنامه را میسازد.
۲. سرویسها: قرارداد میان کلاینت و سرور
تعریف سرویس (Service) نام متدها و نوع ورودی و خروجی آنها را مشخص میکند. این قرارداد به هر دو طرف میگوید چه دادهای بفرستند و چه پاسخی انتظار داشته باشند. سرور باید منطق متدهای تعریفشده را پیادهسازی کند.
کامپایلر protoc و افزونهی مربوط به زبان، از فایل .proto کد پیامها و واسطهای ارتباطی را میسازند. تعریف قرارداد به تنهایی، منطق بررسی موجودی یا ثبت سفارش را تولید نمیکند؛ توسعهدهنده این بخش را مینویسد.
۳. کلاینت: فراخوانی متد و دریافت پاسخ
کلاینت از یک واسط محلی به نام Stub استفاده میکند. هنگام فراخوانی متد، این واسط درخواست را برای ارسال آماده میکند. سرور پیام را دریافت و تفسیر کرده، متد مربوط را اجرا میکند و پاسخ را برمیگرداند. کلاینت نیز پاسخ را بهشکل پیام تعریفشده دریافت میکند.
HTTP/2 .۴: انتقال درخواستها و پاسخها
gRPC در ارتباط معمول خود از HTTP/2 استفاده میکند. این پروتکل چند جریان را روی یک اتصال انتقال میدهد، بنابراین برای هر درخواست به اتصال جدا نیاز ندارید. استفادهی مجدد از کانالهای ارتباطی، از توصیههای مهم برای حفظ کارایی است.
۵. امنیت: رمزنگاری و احراز هویت
امنیت لایهی انتقال (TLS) دادههای میان کلاینت و سرور را رمزنگاری میکند. گواهیها نیز برای بررسی هویت سرور و هنگام نیاز، کلاینت کاربرد دارند. ارسال توکن در فراداده (Metadata) یکی از روشهای احراز هویت است. مجوز اجرای متدها به سیاست دسترسی برنامه بستگی دارد.
انواع فراخوانی در gRPC
در تعریف سرویس میتوانید چهار الگوی فراخوانی داشته باشید. انتخاب الگو به تعداد پیامها و جهت انتقال آنها بستگی دارد.
استریم از سرور (Server Streaming): کلاینت یک درخواست میفرستد و سرور چند پیام را در پاسخ ارسال میکند؛ مانند دریافت پیوسته وضعیت یک فرآیند.
تکدرخواستی (Unary RPC): کلاینت یک درخواست میفرستد و یک پاسخ میگیرد؛ مانند دریافت مشخصات یک محصول.
استریم از کلاینت (Client Streaming): کلاینت چند پیام میفرستد و سرور در پایان یک پاسخ میدهد؛ مانند ارسال مجموعهای از اندازهگیریها.
استریم دوطرفه (Bidirectional Streaming): هر دو طرف میتوانند مستقل از هم پیام بفرستند و دریافت کنند. ترتیب پیامها در هر جریان حفظ میشود.
زبانهای پشتیبانیشده در gRPC
پشتیبانی از چند زبان، استفاده از این فریمورک را در تیمهایی با فناوریهای متفاوت سادهتر میکند. زبانها و محیطهای اصلی شامل سیپلاسپلاس، سیشارپ در محیط داتنت، گو، جاوا، کاتلین، پایتون، روبی و نود جیاس هستند. برای این زبانها و محیطها، کتابخانه یا راهنمای رسمی ساخت کلاینت و سرور وجود دارد. نود جیاس محیط اجرای جاوااسکریپت است.
PHP نیز پشتیبانی رسمی دارد، ولی این پشتیبانی برای ساخت کلاینت است. برای پیادهسازی سرور با ابزارهای رسمی باید از زبان دیگری استفاده کنید. پیش از انتخاب زبان، امکانات موردنیاز را در مستندات همان پیادهسازی بررسی کنید.
تفاوت gRPC و REST
تفاوت gRPC و REST از رویکرد آنها آغاز میشود. gRPC فریمورکی برای فراخوانی متدهاست و REST یک سبک معماری برای کار با منابع و نمایش آنها بهشمار میرود. برای مثال، در اولی میتوانید متد دریافت محصول را فراخوانی کنید و در یک API وب مبتنیبر REST، درخواست GET را به نشانی محصول بفرستید.
جدول زیر، پیادهسازی gRPC با Protobuf را با APIهای رایج REST مقایسه میکند:
| معیار | gRPC | REST |
| رویکرد ارتباط | فراخوانی متدهای سرویس | کار با منابع از راه رابطی یکسان |
| قالب انتقال داده | Protobuf باینری بهشکل پیشفرض | اغلب JSON؛ قالبهای دیگر هم ممکناند |
| قرارداد API | تعریف صریح پیامها و متدها در .proto | امکان تعریف قرارداد با ابزارهایی مانند OpenAPI |
| پروتکل انتقال | HTTP/2 در پیادهسازی معمول | در APIهای وب، امکان استفاده از نسخههای مختلف HTTP |
| کارایی | پیامهای کمحجم و ارتباط مناسب برای فراخوانیهای پرتکرار | وابسته به قالب پیام، پروتکل، شبکه و پیادهسازی |
| خوانایی پیام | باینری؛ نیاز به ابزار برای مشاهده محتوا | خوانایی بیشتر هنگام استفاده از JSON |
| توسعهپذیری | تکامل پیامها با رعایت قواعد سازگاری Protobuf | تکامل منابع و قرارداد مطابق طراحی و نسخهبندی API |
| سهولت استفاده | نیاز به تعریف قرارداد و ابزارهای مربوط | شروع سادهتر با ابزارهای رایج HTTP و JSON |
| ارتباط جریانی | پشتیبانی از استریم کلاینت، سرور و دوطرفه | وابسته به طراحی API و سازوکار ارتباطی انتخابی |
REST به HTTP/1.1 یا JSON محدود نیست. APIهای مبتنیبر آن میتوانند از HTTP/2 استفاده کنند. همچنین، سریعتر بودن gRPC در همهی پروژهها قطعی نیست؛ اندازهی پیامها، زبان پیادهسازی، تعداد فراخوانیها و شرایط شبکه روی نتیجه اثر دارند. برای تصمیمگیری دقیق، باید بار کاری واقعی را آزمایش کنید.
کاربردهای gRPC
این فریمورک برای تبادل پرتکرار داده و ارتباط با قرارداد مشخص کاربرد دارد. سه کاربرد اصلی آن عبارتاند از:
۱. ارتباط در معماری میکروسرویس
سرویسهای سفارش، انبار و کاربران میتوانند با قرارداد مشخص به هم درخواست بدهند. تولید کد از یک تعریف مشترک، هماهنگی نوع پیامها را سادهتر میکند، حتا اگر تیمها زبانهای متفاوتی داشته باشند.
۲. سیستمهای توزیعشده
اجزای سامانه میتوانند روی ماشینهای مختلف اجرا شوند و از راه RPC با هم کار کنند. تعیین مهلت زمانی (Deadline) برای فراخوانیها کمک میکند کلاینت بیدلیل منتظر پاسخ نماند. برنامه باید خطاهای شبکه و لغو درخواست را هم مدیریت کند.
۳. ارتباط بلادرنگ و انتقال مستمر داده
استریمینگ برای ارسال وضعیت پردازش، دادهی حسگرها یا تبادل پیوسته پیام میان دو برنامه کاربرد دارد. در این روش، هر پیام به فراخوانی تازه نیاز ندارد. با این حال، شیوهی مدیریت اتصال و بار پردازشی باید با نیاز سامانه هماهنگ باشد.
اگر میکروسرویسها را در کانتینر اجرا میکنید، با مطالعهی مطلب کوبرنتیز چیست میتوانید به شناخت بیشتر این مفهوم برسید. کوبرنتیز استقرار و مقیاسدهی کانتینرها را مدیریت میکند و gRPC ارتباط میان برنامههای داخل آنها را برقرار میسازد.
محدودیتها و ضعفهای gRPC
قابلیتهای این فریمورک، نیاز به ابزار و تنظیمات بیشتری هم ایجاد میکنند. مرورگرها کنترل لازم بر همهی قابلیتهای موردنیاز gRPC را در اختیار کد صفحه نمیگذارند. برای برخی سناریوهای وب میتوان از gRPC-Web استفاده کرد. این راهکار بهطور معمول به پشتیبانی سمت سرور یا یک پراکسی واسط نیاز دارد و همهی قابلیتهای ارتباط مستقیم را پوشش نمیدهد.
محتوای پیام Protobuf مانند JSON بهطور مستقیم خوانا نیست. برای مشاهدهی درخواست و پاسخ به ابزارهایی مانند grpcurl و اطلاعات قرارداد نیاز دارید. قابلیت بازتاب سرویس (Reflection) میتواند تعریف متدها و پیامها را در اختیار ابزارهای بررسی قرار دهد.
جمعبندی
gRPC یک فریمورک متنباز برای ارتباط میان برنامهها با فراخوانی متدهای راه دور است. قرارداد مشترک، تولید کد، Protobuf و پشتیبانی از Streaming، آن را برای میکروسرویسها و سیستمهای توزیعشده کاربردی میکنند. کلاینت و سرور هم میتوانند زبانهای متفاوتی داشته باشند.
تفاوت اصلی با REST در رویکرد ارتباط است: یکی متد سرویس را فراخوانی میکند و دیگری با منابع سروکار دارد. برای انتخاب، نوع کلاینت، نیاز به استریم، ابزارهای تیم و کارایی در بار واقعی را بررسی کنید. محدودیت مرورگر و مدیریت قرارداد نیز باید در همین تصمیم سهم داشته باشند.





