Mehrpooya Navaie Nezhad
خواندن ۹ دقیقه·۳ ماه پیش

بررسی جامع gRPC

مقدمه

در دنیای توسعه نرم‌افزار و سرویس‌های توزیع‌شده، انتخاب روش ارتباطی مناسب میان سرویس‌ها از اهمیت ویژه‌ای برخوردار است. در گذشته، روش‌های مختلفی برای برقراری ارتباط میان سرویس‌ها توسعه یافته‌اند که هر کدام سعی در ارائه‌ی مزایایی نظیر سرعت بالا، سادگی و امنیت دارند. از میان این روش‌ها می‌توان به سرویس‌های SOAP، REST و پیام‌رسانی از طریق Message Queueها اشاره کرد. اما در سال‌های اخیر، رویکردی جدید با عنوان gRPC مورد توجه قرار گرفته است که بر پایه فناوری Protocol Buffers (یا ProtoBuf) طراحی شده و بر روی پروتکل اچ تی تی پی/2 کار می‌کند.

در این مقاله قصد داریم نگاهی به تاریخچه‌ی gRPC، رویکردهای اصلی آن، مزایا، معایب و نحوه کارکردش بیندازیم و در نهایت نیز مقایسه‌ای با REST داشته باشیم.

۱. تاریخچه gRPC

۱.۱. پیدایش gRPC

سرویس های gRPC یا Google Remote Procedure Call ابتدا در گوگل به عنوان یک پروژه داخلی با هدف بهبود ارتباط سرویس‌های توزیع‌شده مطرح شد. گوگل برای میکروسرویس‌های متعددی که در سراسر زیرساخت عظیم خود داشت، نیازمند یک روش سریع، امن و کارآمد برای تبادل داده‌ها بود. این پروژه به مرور زمان تکامل یافت و در سال ۲۰۱۵ به صورت متن‌باز عرضه شد. از آن زمان جامعه توسعه‌دهندگان استقبال خوبی از gRPC کردند و امروز این فناوری به یکی از راهکارهای محبوب برای ایجاد ارتباط میان سرویس‌ها تبدیل شده است.

۱.۲. انگیزه‌های اصلی شکل‌گیری

یکی از مهم‌ترین انگیزه‌های گوگل برای توسعه gRPC، بهبود عملکرد و بهره‌وری نسبت به روش‌های سنتی (مانند REST مبتنی بر JSON) بود. در مقیاس بزرگ گوگل، مدیریت حجم عظیمی از درخواست‌ها و تعاملات میان سرویس‌های مختلف اهمیت بالایی داشت. استفاده از فناوری Protocol Buffers برای سریال‌سازی داده‌ها، در کنار استفاده از پروتکل اچ تی تی پی/2، سبب شد تا gRPC بتواند ویژگی‌هایی چون سرعت و کارایی بالا را در اختیار توسعه‌دهندگان قرار دهد.

۲. رویکردهای اصلی در gRPC

۲.۱. معماری RPC

بر پایه مفهوم RPC (Remote Procedure Call) بنا شده است. در این معماری، کلاینت (Client) عملکرد یا متدی که در سمت سرور وجود دارد را فراخوانی می‌کند و انگار در حال فراخوانی یک تابع محلی است؛ در حالی که در عمل، فراخوانی در بستر شبکه رخ می‌دهد. این رویکرد توسعه و درک ساختار کدهای سمت کلاینت و سرور را ساده‌تر می‌کند.

۲.۲. استفاده از Protocol Buffers

در gRPC برای سریال‌سازی داده‌ها از ProtoBuf استفاده می‌شود. در این مدل، پیام‌هایی که بین کلاینت و سرور رد و بدل می‌شوند در قالب فایل‌های *.proto تعریف می‌شوند. این فایل‌ها ضمن توصیف ساختار داده، امکان تولید خودکار کد برای زبان‌های مختلف را هم فراهم می‌کنند. نتیجه‌ی این کار، سریال‌سازی و دسریال‌سازی سریع و کم‌حجم است و از خطاهای احتمالی در تعریف واسط‌ها جلوگیری می‌کند.

۲.۳. استفاده از اچ تی تی پی/2

سرویس های gRPC برخلاف بسیاری از روش‌های سنتی که بر مبنای اچ تی تی پی/1.1 هستند، از اچ تی تی پی/2 استفاده می‌کند. اچ تی تی پی/2 مزیت‌هایی مانند Multiplexing (ارسال چند درخواست به صورت همزمان در یک کانکشن واحد)، Header Compression و Server Push دارد. وقتی این ویژگی‌ها را کنار عملکرد بالای ProtoBuf بگذاریم، سرعت و کارایی کل سیستم به شکل چشمگیری افزایش می‌یابد.

۳. نحوه کارکرد gRPC

۳.۱. تعریف سرویس و پیام

برای شروع کار با gRPC، پیام‌ها و سرویس‌ها را در یک فایل *.proto تعریف می‌کنید. مثلاً:

protoCopy codesyntax = &quotproto3&quot message User { int32 id = 1; string name = 2; } service UserService { rpc GetUser (UserRequest) returns (UserResponse); }

در این مثال، یک سرویس با نام UserService تعریف شده و متدی به نام GetUser دارد. پیام‌های UserRequest و UserResponse نیز باید در همین فایل یا فایل‌های مجزا تعریف شوند.

۳.۲. تولید کد و پیاده‌سازی

پس از تعریف فایل proto، ابزار کامپایلر (مثلاً protoc) بر اساس زبان مورد نظرتان، کدهای لازم را تولید می‌کند. در سمت سرور، متدهای سرویس را پیاده‌سازی می‌کنید و در سمت کلاینت هم از کلاس‌ها و توابعی که این ابزار ایجاد کرده، استفاده می‌کنید.

۳.۳. الگوهای ارتباطی

سرویس های gRPC فقط به درخواست/پاسخ ساده محدود نمی‌شوند و چهار الگوی اصلی را ارائه می‌دهد:

  1. الگوی Unary RPC: کلاینت یک درخواست ارسال می‌کند و سرور یک پاسخ می‌دهد.
  2. الگوی Server streaming RPC: کلاینت یک درخواست ارسال می‌کند اما سرور استریمی از پاسخ‌ها را می‌فرستد.
  3. الگوی Client streaming RPC: کلاینت استریمی از درخواست‌ها را ارسال می‌کند و سرور در نهایت یک پاسخ کلی می‌دهد.
  4. الگوی Bi-directional streaming RPC: کلاینت و سرور همزمان و در قالب یک کانکشن مشترک می‌توانند داده‌ها را استریم کنند.

این الگوها باعث می‌شوند gRPC برای سناریوهای بلادرنگ، استریم ویدیو، گفتگوی آنی و غیره، بسیار منعطف باشد.

۴. مزایای gRPC

۴.۱. کارایی بالا

استفاده از اچ تی تی پی/2 و ProtoBuf باعث می‌شود داده‌ها با حجم کمتر و سرعت بیشتری رد و بدل شوند. فشرده‌سازی هدرها، مولتی‌پلکس شدن درخواست‌ها و عدم وابستگی به فرمت متنی JSON، همگی در افزایش کارایی سیستم نقش دارند.

۴.۲. توصیفگر قوی واسط (IDL)

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

۴.۳. پشتیبانی از استریم

همان‌طور که دیدیم، gRPC از چهار الگوی ارتباطی پشتیبانی می‌کند و سه مورد آن مبتنی بر استریم هستند. این ویژگی برای برنامه‌هایی که نیاز به ارتباط لحظه‌ای دارند (مثل سرویس‌های چت، استریم ویدیو و داده‌های IoT) بسیار مفید است.

۴.۴. افزایش امنیت

سرویس های gRPC به صورت پیش‌فرض می‌توانند از TLS استفاده کند تا ارتباط بین کلاینت و سرور رمزگذاری شود. اچ تی تی پی/2 نیز به شکل بهینه‌تری با TLS کار می‌کند و مشکلاتی مانند Head of line blocking را کاهش می‌دهد.

۵. معایب و چالش‌های gRPC

۵.۱. عدم خوانایی انسانی پیام‌ها

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

۵.۲. پیچیدگی راه‌اندازی

در ابتدای کار، نیاز به یادگیری مفاهیم RPC، ساختار فایل‌های proto و کار با ابزارهایی مانند protoc وجود دارد. برای تیم‌هایی که به معماری REST عادت دارند، کوچ به gRPC ممکن است زمان‌بر باشد.

۵.۳. محدودیت پشتیبانی توسط مرورگرها

در حال حاضر، مرورگرها به طور مستقیم از gRPC پشتیبانی نمی‌کنند. پروژه gRPC-web گوگل تا حدی این مشکل را حل می‌کند، اما همچنان محدودیت‌هایی وجود دارد. در مقابل، REST و JSON به راحتی در مرورگر قابل استفاده‌اند (AJAX، Fetch و غیره)(برای سرویس های gRPC نمی توان از swagger استفاده کرد).

۵.۴. کمبود برخی ابزارهای جانبی

با اینکه اکوسیستم gRPC به سرعت رشد می‌کند، ممکن است در برخی زمینه‌ها ابزارهایی با سطح بلوغ مشابه REST پیدا نکنید. هرچند این فاصله در حال کمتر شدن است، اما همچنان ابزارهای مانیتورینگ و دیباگینگ REST در بسیاری از موارد گسترده‌تر هستند.

۶. مقایسه gRPC و REST

۶.۱. فرمت داده

  • در gRPC: فرمت باینری با استفاده از ProtoBuf که سرعت و حجم کمتر دارد.
  • در REST: معمولاً با JSON یا XML کار می‌کند که خوانایی بالایی برای انسان دارد.

۶.۲. پروتکل شبکه

  • در gRPC: مبتنی بر اچ تی تی پی/2 (مولتی‌پلکسینگ، فشرده‌سازی هدر و غیره).
  • در REST: معمولاً بر پایه اچ تی تی پی/1.1 (هرچند امکان استفاده از اچ تی تی پی/2 نیز وجود دارد، اما همه‌گیر نیست).

۶.۳. الگوی ارتباطی

  • در gRPC: ارائه ۴ الگوی ارتباطی (Unary، Client Streaming، Server Streaming، Bi-directional Streaming).
  • در REST: عمدتاً الگوی درخواست/پاسخ و برای استریم داده‌ها اغلب به وب‌سوکت‌ها یا تکنیک‌های دیگر متکی می‌شود.

۶.۴. سرعت و کارایی

  • در gRPC: عموماً سریع‌تر و بهینه‌تر، مخصوصاً در حجم بالای داده.
  • در REST: سرعت مناسبی دارد اما سربار JSON و اچ تی تی پی/1.1 می‌تواند مؤثر باشد.

۶.۵. استفاده در وب‌سایت‌ها

  • در gRPC: به دلیل محدودیت پشتیبانی در مرورگر، کار با آن سخت‌تر است (گرچه gRPC-web تا حدی این مشکل را حل می‌کند).
  • در REST: برای وب‌سایت‌ها و مرورگرها گزینه ساده‌تری است، ابزارها و کتابخانه‌های زیادی دارد.

۶.۶. یادگیری و فرهنگ توسعه

  • در gRPC: نیازمند یادگیری مفاهیم جدید است.
  • در REST: توسعه‌دهندگان معمولاً با آن آشنا هستند و استفاده از آن متداول‌تر است.

۷. کاربردهای متداول gRPC

۷.۱. میکروسرویس‌ها

در معماری میکروسرویس، gRPC به دلیل کارایی بالا و حجم کم پیام‌ها گزینه‌ای مناسب است. توصیف سرویس‌ها با فایل‌های proto هم به تیم‌هایی که از زبان‌های مختلف استفاده می‌کنند، کمک می‌کند.

۷.۲. ارتباط درون سازمانی (Intranet)

در زیرساخت‌های توزیع‌شده و درون‌سازمانی، بهره‌گیری از gRPC موجب کاهش سربار شبکه می‌شود. ضمن اینکه می‌توان به راحتی امنیت TLS را در محیط داخلی پیاده‌سازی کرد.

۷.۳. سامانه‌های بلادرنگ

به دلیل پشتیبانی از استریم، gRPC برای سرویس‌های چت، اعلان‌های لحظه‌ای، استریم ویدیو و پایش داده‌های بلادرنگ، بسیار کاربردی است.

۷.۴. کلاینت‌های موبایل

فرمت باینری gRPC و پیاده‌سازی بر پایه اچ تی تی پی/2، پهنای باند کمتری مصرف می‌کند و بهینه‌تر است؛ به همین دلیل در اپلیکیشن‌های موبایل هم مورد استقبال قرار گرفته است.

۸. بهترین شیوه‌ها برای استفاده از gRPC

۸.۱. تعریف دقیق ساختار proto

پیام‌ها و متدهای سرویس را با جزئیات و نام‌گذاری واضح در فایل‌های proto تعریف کنید تا در آینده در صورت نیاز، توسعه آن‌ها راحت‌تر باشد.

۸.۲. استفاده از نسخه‌بندی

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

۸.۳. مانیتورینگ و لاگ‌های پیشرفته

در معماری میکروسرویس، ابزارهای مانیتورینگ قدرتمند ضروری‌اند. با استفاده از ابزارهایی مانند Prometheus، Grafana و سرویس‌های ابری، می‌توانید متریک‌های gRPC را زیر نظر بگیرید.

۸.۴. مدیریت خطا

در gRPC ساختار استانداردی برای گزارش خطاها دارد (Status و StatusCode). حتماً در طراحی سرویس‌ها از این ساختار به جای فیلدهای سفارشی استفاده کنید.

۸.۵. امنیت و احراز هویت

فراتر از TLS، می‌توانید از روش‌هایی مثل توکن‌های JWT یا OAuth2.0 در هدر برای احراز هویت استفاده کنید تا سرویس‌هایتان ایمن‌تر شود.

۹. نتیجه‌گیری

سرویس هایgRPC با تکیه بر Protocol Buffers و اچ تی تی پی/2، سرعت و کارایی بالایی را برای ارتباط میان سرویس‌ها فراهم می‌کند. این فناوری که توسط گوگل توسعه یافت و متن‌باز شده است، اکنون در پروژه‌های مختلفی که نیاز به مقیاس‌پذیری بالا، امنیت و استریم داده دارند، کاربرد گسترده‌ای دارد. البته محدودیت‌هایی مثل عدم خوانایی باینری و عدم پشتیبانی کامل مرورگرها هم وجود دارد.

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

شاید از این پست‌ها خوشتان بیاید