gRPC ودوره في تواصل خدمات الميكروسيرفس

gRPC (gRPC Remote Procedure Calls) هو إطار عمل عالي الأداء ومفتوح المصدر حديث للاتصالات الإجرائية عن بعد (RPC) تم تطويره بواسطة Google. تم تصميمه لتيسير التواصل الفعال بين الأنظمة الموزعة، مما يجعله مناسبًا بشكل خاص لهندسة النظم المعمارية للخدمات الصغيرة. أدناه شرح لـ gRPC ودوره في التواصل بين خدمات الويب:

ما هو gRPC؟

gRPC هو بروتوكول يمكن تطبيقات العميل والخادم من التواصل بشفافية، مما يجعل بناء الأنظمة الموزعة أسهل. يستخدم HTTP/2 للنقل، وتعريف Protobuf (Protobuf) كلغة تعريف واجهة البرمجة (IDL)، ويوفر ميزات مثل المصادقة وتوازن الحمل، والمزيد. 

فيما يلي بعض خصائص gRPC:

  1. غير معتمد على اللغة. يدعم gRPC لغات برمجة متعددة، بما في ذلك Java وPython وGo وC++ وغيرها.
  2. تواصل فعال. يستخدم التسلسل الثنائي مع Protobuf، والذي يكون أسرع وأكثر كفاءة من صيغ النص مثل JSON.
  3. قائم على HTTP/2. يستفيد gRPC من HTTP/2، مما يتيح ميزات مثل التعدد، والبث، وتقليل التأخير.
  4. محددة النوع. يتم تعريف الخدمات والرسائل باستخدام Protobuf، مما يضمن سلامة النوع وتقليل الأخطاء.
  5. دعم التدفق. يدعم gRPC أربعة أنواع من التدفق: غير الثنائي، تدفق الخادم، تدفق العميل، وتدفق ثنائي الاتجاه.

كيفية عمل gRPC

1. تعريف الخدمات والرسائل

من خلال Protobuf، تعرّف واجهة الخدمة (الأساليب) وهيكل الرسائل المراد تبادلها.

ProtoBuf

 

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}

2. توليد الشفرة

يولّد مترجم Protobuf (protoc) شفرة العميل والخادم باللغة البرمجية التي تختارها.

ProtoBuf

 

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}

3. تنفيذ الخادم

نفّذ منطق الجانب الخادم للخدمة المعرفة.

4. إنشاء العميل

استخدم شفرة العميل المولّدة لاستدعاء طرق الخادم.

دور gRPC في تواصل الخدمات الصغيرة

تتضمن الهندسة المعمارية للخدمات الصغيرة تقسيم التطبيقات إلى خدمات أصغر مستقلة تتواصل عبر الشبكة. يلعب gRPC دورًا حاسمًا في هذا السياق بسبب كفاءته ومرونته.

1. أداء عالي

  • يستخدم gRPC تسلسل ثنائي مع Protobuf، والذي يكون أسرع وأكثر انضباطًا من تنسيقات النص مثل JSON أو XML.
  • يُقلل HTTP/2 من التأخير ويحسن النفاذية عن طريق تمكين التعدد وضغط الرؤوس.

2. تعريف عقد قوي

  • يفرض Protobuf عقدًا صارمًا بين الخدمات، مما يقلل من احتمالات أخطاء الاتصال.
  • يمكن إدارة التغييرات في تعريف الخدمة بالترقيم، مما يضمن التوافق مع الإصدارات السابقة.

3. إمكانيات التدفق

  • يدعم gRPC التدفق ذهابًا وإيابًا، مما يجعله مثاليًا للتواصل في الوقت الحقيقي، مثل تطبيقات الدردشة أو تغذيات البيانات الحية.
  • يتيح التدفق من الخادم والعميل التعامل الفعال مع مجموعات بيانات كبيرة أو تدفقات البيانات المستمرة.

4. التوافق

  • gRPC غير معتمد على اللغة، مما يسمح للخدمات الصغيرة المكتوبة بلغات مختلفة بالتواصل بسلاسة.
  • هذا مفيد بشكل خاص في بيئات الخدمات الصغيرة متعددة اللغات.

5. الميزات المدمجة

  • يوفر gRPC دعمًا مدمجًا لميزات مثل المصادقة، التشفير (عبر TLS)، وتوازن الحمل، مما يقلل من الحاجة إلى مكتبات أو أدوات إضافية.

6. التوسعة

  • طبيعة gRPC الخفيفة الوزن والتواصل الفعال يجعله مناسبًا لنشر الخدمات الصغيرة على نطاق واسع.
  • إنه يتكامل بشكل جيد مع منصات تنسيق الحاويات مثل Kubernetes.

حالات الاستخدام لـ gRPC في الخدمات الصغيرة

  1. التواصل بين الخدمات. gRPC مثالي للتواصل بين الخدمات الصغيرة، خاصة في السيناريوهات التي تتطلب الأداء الممتاز.
  2. الأنظمة في الوقت الحقيقي. إمكانيات التدفق تجعل gRPC مناسبًا لتطبيقات الوقت الحقيقي مثل الألعاب، وأنظمة الإنترنت من الأشياء (IoT)، أو تحليلات البيانات الحية.
  3. البيئات متعددة اللغات. عندما تكون الخدمات الصغيرة مكتوبة بلغات مختلفة، يضمن gRPC التواصل السلس.
  4. تطبيقات السحاب الأصلية. gRPC يتكامل بشكل جيد مع تقنيات السحاب الأصلية مثل Kubernetes وشبكات الخدمة (على سبيل المثال، Istio).

الفوائد من gRPC

  • الكفاءة. التسلسل الثنائي وHTTP/2 يجعلان gRPC أسرع وأكثر كفاءة في استهلاك الموارد.
  • سلامة النوع. Protobuf يضمن التحويل القوي، مما يقلل من أخطاء التشغيل.
  • دعم اللغات المتعددة. يعمل عبر لغات برمجة متعددة.
  • البث المباشر. يدعم أنماط بث متقدمة للاتصال في الوقت الحقيقي.

تحديات gRPC

  • التعقيد. إعداد gRPC يمكن أن يكون أكثر تعقيدًا من REST بسبب الحاجة إلى تعريفات Protobuf وتوليد الشفرة.
  • أدوات. يمكن أن يكون تصحيح الأخطاء واختبار خدمات gRPC أصعب مقارنة بـ REST، حيث أن الأدوات مثل Postman ليست مصممة بشكل أصلي لـ gRPC.
  • دعم المتصفح. gRPC ليس مدعومًا بشكل أصلي في المتصفحات، مما يتطلب استخدام أدوات مثل gRPC-Web لعملاء الويب.

لماذا استخدام gRPC مع Spring Boot؟

Spring Boot هو إطار عمل شهير لبناء تطبيقات جافا، ودمجه مع gRPC يسمح للمطورين بإنشاء خدمات عالية الأداء وقابلة للتوسع والتفاعلية. بفضل التكوين التلقائي وحقن الإعتماديات في Spring Boot، يصبح دمج gRPC سهلاً.

خطوات بناء التطبيق

سنقوم ببناء خدمة gRPC بسيطة تسمى Greeter تسمح للعميل بإرسال اسم إلى الخادم واستقبال رد “مرحبًا، {الاسم}!”، هكذا سنفعل:

  1. تعريف خدمة gRPC باستخدام Protocol Buffers.
  2. إنشاء فئات Java من ملف .proto.
  3. تنفيذ خادم gRPC في Spring Boot.
  4. تنفيذ عميل gRPC في Spring Boot.
  5. إضافة وحدة تحكم REST لاستدعاء عميل gRPC للاختبار.
  6. تشغيل التطبيق واختبار الاتصال.

1. تعريف خدمة gRPC (.proto File)

الخطوة الأولى هي تعريف خدمة gRPC باستخدام Protocol Buffers. قم بإنشاء ملف بالاسم greeter.proto في دليل src/main/proto:

ProtoBuf

 

syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.example.grpc";
option java_outer_classname = "GreeterProto";
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
  string name = 1;
}
message HelloResponse {
  string message = 1;
}

يعرف هذا الملف:

  • خدمة Greeter تحتوي على طريقة RPC SayHello.
  • رسالة HelloRequest تحتوي على حقل name.
  • رسالة HelloResponse تحتوي على حقل message.

2. إضافة التبعيات

لاستخدام gRPC مع Spring Boot، أضف التبعيات التالية إلى ملف pom.xml:

XML

 

<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
<!-- Spring Boot Web for REST Controller -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- gRPC dependencies -->
    <dependency>
        <groupId>net.devh</groupId>
        <artifactId>grpc-spring-boot-starter</artifactId>
        <version>2.14.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-netty-shaded</artifactId>
        <version>1.54.0</version>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-protobuf</artifactId>
        <version>1.54.0</version>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-stub</artifactId>
        <version>1.54.0</version>
    </dependency>
    <!-- Protobuf Java Format -->
    <dependency>
        <groupId>com.google.protobuf</groupId>
        <artifactId>protobuf-java</artifactId>
        <version>3.22.2</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <!-- Protobuf Compiler Plugin -->
        <plugin>
            <groupId>org.xolstice.maven.plugins</groupId>
            <artifactId>protobuf-maven-plugin</artifactId>
            <version>0.6.1</version>
            <configuration>
                <protocArtifact>com.google.protobuf:protoc:3.22.2:exe:${os.detected.classifier}</protocArtifact>
                <pluginId>grpc-java</pluginId>
                <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.54.0:exe:${os.detected.classifier}</pluginArtifact>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>compile-custom</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

تتضمن هذه التبعيات:

  • Spring Boot Starter لإعداد التطبيق الأساسي.
  • Spring Boot Web لدعم وحدة تحكم REST.
  • مكتبات gRPC لتنفيذ الخادم والعميل.
  • Protobuf للتسلسل والفك التسلسل.

3. توليد فئات Java

قم بتشغيل الأمر Maven التالي لتوليد فئات Java من ملف .proto:

Plain Text

 

mvn clean compile

سيتم إنشاء GreeterGrpc والفئات ذات الصلة في دليل target/generated-sources.

4. قم بتنفيذ خادم gRPC

ثم قم بتنفيذ خادم gRPC في Spring Boot. قم بإنشاء فئة بالاسم GreeterService:

Java

 

package com.example.grpc.server;

import com.example.grpc.GreeterGrpc;
import com.example.grpc.GreeterProto.HelloRequest;
import com.example.grpc.GreeterProto.HelloResponse;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;
@GrpcService
public class GreeterService extends GreeterGrpc.GreeterImplBase {
    @Override
    public void sayHello(HelloRequest request, StreamObserver responseObserver) {
        String name = request.getName();
        String message = "Hello, " + name + "!";
        HelloResponse response = HelloResponse.newBuilder().setMessage(message).build();
        // إرسال الاستجابة
        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }
}

تمتد هذه الفئة من GreeterGrpc.GreeterImplBase المُولَّدة وتنفذ طريقة sayHello لمعالجة الطلبات الواردة.

5. قم بتنفيذ عميل gRPC

الآن، قم بتنفيذ عميل gRPC في Spring Boot. قم بإنشاء فئة بالاسم GreeterClient:

Java

 

package com.example.grpc.client;
import com.example.grpc.GreeterGrpc;
import com.example.grpc.GreeterProto.HelloRequest;
import com.example.grpc.GreeterProto.HelloResponse;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import org.springframework.stereotype.Service;
@Service
public class GreeterClient {
    private final GreeterGrpc.GreeterBlockingStub blockingStub;
    public GreeterClient() {
        ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 9090)
                .usePlaintext()
                .build();
        this.blockingStub = GreeterGrpc.newBlockingStub(channel);
    }
    public String sayHello(String name) {
        HelloRequest request = HelloRequest.newBuilder().setName(name).build();
        HelloResponse response = blockingStub.sayHello(request);
        return response.getMessage();
    }
}

يتصل هذا العميل بخادم gRPC ويُرسل طلبًا إلى طريقة SayHello.

6. إضافة تحكم REST للاختبار

لتسهيل اختبار عميل gRPC، سنضيف تحكم REST يكشف عن نقطة النهاية لاستدعاء GreeterClient. قم بإنشاء فئة بالاسم GreeterController:

Java

 

package com.example.grpc.controller;
import com.example.grpc.client.GreeterClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreeterController {

    private final GreeterClient greeterClient;

    @Autowired
    public GreeterController(GreeterClient greeterClient) {
        this.greeterClient = greeterClient;
    }

    @GetMapping("/greet")
    public String greet(@RequestParam String name) {
        return greeterClient.sayHello(name);
    }
}

يكشف هذا التحكم عن نقطة نهاية /greet تقبل معلمة name وتُرجع الاستجابة من خادم gRPC.

7. إنشاء تطبيق Spring Boot

أخيرًا، قم بإنشاء تطبيق Spring Boot لتشغيل الخادم والعميل:

Java

 

package com.example.grpc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GrpcApplication {
    public static void main(String[] args) {
        SpringApplication.run(GrpcApplication.class, args);
    }
}

8. تكوين منفذ الخادم

أضف التكوين التالي إلى application.properties:

Plain Text

 

# منفذ خادم gRPC
grpc.server.port=9090

# منفذ خادم Spring Boot
server.port=8080

9. تشغيل التطبيق

  1. قم بتشغيل تطبيق Spring Boot.
  2. سيبدأ خادم gRPC على المنفذ 9090.
  3. سيكون تحكم REST متاحًا على المنفذ 8080.

يمكنك اختبار التطبيق عن طريق إرسال طلب GET إلى نهاية /greet:

Plain Text

 

curl http://localhost:8080/greet?name=World

سيكون الرد:

Plain Text

 

"Hello, World!"

اختيار المكتبة الصحيحة لـ gRPC مع Spring Boot

عند بناء تطبيقات Spring Boot التي تتطلب تكامل gRPC، يواجه المطورون في كثير من الأحيان اختيارًا بين عدة مكتبات. الخيارات الأكثر نقاشًا عادةً هي net.devh.grpc، org.lognet.grpc، و org.springframework.grpc.

لكل من هذه المكتبات مزاياها وعيوبها وحالات استخدامها الخاصة. دعونا نستكشف الفروقات بين هذه المكتبات، مميزاتها، والتي يجب عليك استخدامها في مشروعك.

1. net.devh.grpc (grpc-spring-boot-starter)

net.devh.grpc، المعروف أيضًا باسم grpc-spring-boot-starter، هو مكتبة مستخدمة على نطاق واسع لتكامل gRPC مع Spring Boot. يتم صيانته بانتظام ويوفر مجموعة قوية من الميزات لبناء خوادم وعملاء gRPC في تطبيق Spring Boot.

الميزات الرئيسية

  • التكوين التلقائي. يبسط إعداد خوادم وعملاء gRPC.
  • تكامل مع Spring. يدعم حقن الإعتماد وميزات Spring الأخرى.
  • أمان Spring. يتكامل بسهولة مع Spring Security للاتصال الآمن.
  • فحوصات الصحة. يوفر فحوصات الصحة عبر Spring Boot Actuator.
  • التواصل المتزامن وغير المتزامن. يدعم كلا أساليب الاتصال.

لماذا استخدامه؟

  • الصيانة النشطة. المكتبة تحظى بصيانة نشطة وتحديثات مستمرة.
  • وثائق شاملة. موثقة بشكل جيد مع وجود مجتمع كبير للدعم.
  • جاهزة للإنتاج. تستخدم على نطاق واسع في بيئات الإنتاج.

متى يجب استخدامه؟

  • إذا كنت تقوم ببناء تطبيق جديد باستخدام Spring Boot وتحتاج إلى تكامل موثوق وغني بميزات gRPC.
  • إذا كنت ترغب في التكامل السلس مع ميزات Spring Boot مثل حقن الإعتماديات والأمان وفحوص الصحة.

2. org.lognet.grpc (grpc-spring-boot-starter)

org.lognet.grpc هي مكتبة أخرى لتكامل gRPC مع Spring Boot. ومع ذلك، فإنها تحظى بصيانة أقل مقارنة بـ net.devh.grpc وتفتقر إلى بعض الميزات المتقدمة المقدمة من الأخيرة.

الميزات الرئيسية

  • إعداد gRPC الأساسي. يوفر الدعم الأساسي لخوادم وعملاء gRPC.
  • تكامل Spring Boot. يعمل مع Spring Boot ولكن بميزات أقل.

لماذا استخدامه؟

  • استخدام تاريخي. كانت واحدة من المكتبات الأولى لتكامل gRPC وSpring Boot.
  • البساطة. مناسبة لحالات الاستخدام البسيطة.

متى يجب استخدامه؟

  • إذا كنت تعمل على مشروع قديم يستخدم بالفعل هذه المكتبة.
  • غير مُوصى به للمشاريع الجديدة بسبب الصيانة المحدودة وقلة الميزات.

3. org.springframework.grpc (Spring gRPC)

org.springframework.grpc هو جهد تجريبي أو مدعوم من المجتمع لدمج gRPC مع Spring. ليس مشروعًا رسميًا من Spring وقد لا يكون بالغ النضج أو غنيًا بالميزات مثل net.devh.grpc.

الميزات الرئيسية

  • التكامل الأساسي مع gRPC. يوفر دعمًا أساسيًا لخوادم وعملاء gRPC.
  • مواءمة النظام البيئي لـ Spring. مصمم للتوافق الوثيق مع نظام النظام البيئي لـ Spring.

لماذا استخدامه؟

  • استخدام تجريبي. مناسب للتجريب أو المساهمة في المشروع.
  • مواءمة مع Spring. إذا كنت تفضل استخدام شيء يتوافق بشكل وثيق مع Spring.

متى يجب استخدامه؟

  • فقط إذا كنت تقوم باستكشاف المشروع أو المساهمة فيه.
  • غير مُوصى به للاستخدام في الإنتاج بسبب طبيعته التجريبية.

أيهما يجب عليك استخدامه؟

للمشاريع الجديدة

استخدم net.devh.grpc (grpc-spring-boot-starter). إنه الخيار الأكثر نضجًا وصيانة نشطة وغني بالميزات لدمج gRPC مع Spring Boot. التكامل السلس مع ميزات Spring Boot يجعله الخيار الأفضل للمشاريع الجديدة.

للمشاريع القائمة

إذا كنت تستخدم بالفعل org.lognet.grpc، فكر في التحول إلى net.devh.grpc للحصول على دعم وميزات أفضل. بينما قد تعمل org.lognet.grpc لمشاريع أقدم، إلا أنها تفتقر إلى الصيانة النشطة والميزات المتقدمة التي يوفرها net.devh.grpc.

للاستخدام التجريبي

إذا كنت تستكشف أو تساهم في تكامل Spring gRPC، يمكنك النظر في org.springframework.grpc. ومع ذلك، لا يُوصى باستخدامه في الإنتاج بسبب طبيعته التجريبية.

اعتبارات رئيسية

  • دعم المجتمع. تمتلك net.devh.grpc مجتمعًا أكبر وتوثيقًا أفضل، مما يجعل من السهل العثور على المساعدة والموارد.
  • جاهزية الإنتاج. يُستخدم net.devh.grpc على نطاق واسع في بيئات الإنتاج ويُعتبر مستقرًا وموثوقًا.
  • سهولة الاستخدام. يوفر net.devh.grpc تكوينًا تلقائيًا وتكاملًا سلسًا مع Spring Boot، مما يقلل من تعقيد الإعداد.

الاستنتاج

gRPC هي أداة قوية للتواصل بين خدمات المايكروسيرفس، توفر أداءً عاليًا ونوعية قوية وميزات متقدمة مثل التدفق. على الرغم من أنه يتطلب إعدادًا أوليًا أكثر مقارنة بـ REST، إلا أن كفاءته وقابليته للتوسع تجعله خيارًا ممتازًا للأنظمة الحديثة والموزعة.

مع تزايد تعقيد البنى المعمارية للخدمات الصغيرة، يلعب gRPC دورًا متزايد الأهمية في تمكين التواصل السلس بين الخدمات. في هذه المقالة، قمنا ببناء تطبيق بسيط لعميل وخادم gRPC باستخدام Spring Boot 3، حيث قمنا بتعريف خدمة gRPC بواسطة Protocol Buffers، وتوليد فئات Java، وتنفيذ الخادم والعميل، وإضافة تحكم REST للاختبار بسهولة. يُظهر هذا المثال قوة وبساطة gRPC في بناء خدمات عالية الأداء وقابلة للتوسع والتفاعلية. يمكنك توسيعه بمزيد من الخدمات المعقدة أو التدفقات أو معالجة الأخطاء. نتمنى لك تجربة تطوير سعيدة!

مستودع GitHub: grpc-client-and-server-with-spring-boot.

Source:
https://dzone.com/articles/understanding-grpc-and-its-role-in-microservices-c