1. نظرة عامة
gRPC هو إطار عمل ومجموعة أدوات لإجراءات الاتصال عن بُعد على نطاق محايد ومحايد في اللغة والنظام الأساسي تم تطويره في Google. تتيح لك هذه الأداة تعريف خدمة باستخدام Protocol Buffers، وهي مجموعة أدوات ولغة تسلسلية ثنائية فعّالة بشكل خاص. وتتيح لك هذه الأداة بعد ذلك إنشاء رموز برمجية أصلية للعميل والخادم من تعريف الخدمة الخاص بك إلى مجموعة متنوّعة من اللغات.
في هذا الدرس التطبيقي، ستتعرّف على كيفية إنشاء خدمة مستندة إلى Java تعرض واجهة برمجة تطبيقات باستخدام إطار عمل gRPC، ثم ستكتب برنامج عميل لاستخدام بروتوكول gRPC الذي تم إنشاؤه من جهة العميل.
المعلومات التي ستطّلع عليها
- لغة مخزن البروتوكول المؤقت
- كيفية تنفيذ خدمة gRPC باستخدام Java
- كيفية تنفيذ برنامج gRPC باستخدام Java
كيف ستستخدم هذا البرنامج التعليمي؟
ما هو تقييمك لتجربتك في إنشاء تطبيقات Node.js؟
ما هو تقييمك لتجربتك في إنشاء تطبيقات Go؟
2. الإعداد والمتطلبات
إعداد بيئة ذاتية
- سجِّل الدخول إلى Cloud Console وأنشِئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.
يُرجى تذكُّر رقم تعريف المشروع، وهو اسم فريد في جميع مشاريع Google Cloud (سبق أن تم استخدام الاسم أعلاه ولن يكون مناسبًا لك). ستتم الإشارة إليها لاحقًا في هذا الدرس التطبيقي حول الترميز باسم PROJECT_ID
.
- بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام موارد Google Cloud.
إنّ تنفيذ هذا الدرس التطبيقي حول الترميز لن يكون مكلفًا أو مكلفًا على الإطلاق. احرص على اتّباع أي تعليمات في قسم "الحذف سريعًا". الذي يقدم لك نصائح حول كيفية إيقاف تشغيل الموارد حتى لا تتكبّد أي فواتير خارج نطاق هذا البرنامج التعليمي. يكون مستخدمو Google Cloud الجدد مؤهَّلون للانضمام إلى برنامج فترة تجريبية مجانية بقيمة 300 دولار أمريكي.
Google Cloud Shell
مع أنّه يمكن إدارة هذا الدرس التطبيقي من الكمبيوتر، سنستخدم Google Cloud Shell، وهي بيئة سطر أوامر يتم تشغيلها في السحابة الإلكترونية في هذا الدرس التطبيقي.
هذا الجهاز الافتراضي المستند إلى نظام دبيان محمل بكل أدوات التطوير التي ستحتاج إليها. وتوفّر هذه الشبكة دليلاً رئيسيًا دائمًا بسعة 5 غيغابايت ويتم تشغيله في Google Cloud، ما يحسّن بشكل كبير من أداء الشبكة والمصادقة. وهذا يعني أنّ كل ما ستحتاجه في هذا الدرس التطبيقي حول الترميز هو متصفّح (نعم، يعمل على جهاز Chromebook).
- لتفعيل Cloud Shell من Cloud Console، ما عليك سوى النقر على تفعيل Cloud Shell (من المفترَض أن تستغرق عملية الإعداد والاتصال بالبيئة بضع دقائق فقط).
بعد الربط بتطبيق Cloud Shell، من المفترض أن يظهر لك أنّه قد تمت مصادقتك وأنّ المشروع سبق أن تم ضبطه على PROJECT_ID
.
gcloud auth list
مخرجات الأمر
Credentialed accounts: - <myaccount>@<mydomain>.com (active)
gcloud config list project
مخرجات الأمر
[core] project = <PROJECT_ID>
إذا لم يتم ضبط المشروع لسبب ما، ما عليك سوى إصدار الأمر التالي:
gcloud config set project <PROJECT_ID>
هل تبحث عن PROJECT_ID
؟ تحقَّق من المعرّف الذي استخدمته في خطوات الإعداد أو ابحث عنه في لوحة بيانات Cloud Console:
تضبط Cloud Shell أيضًا بعض متغيرات البيئة تلقائيًا، وهو ما قد يكون مفيدًا عند تشغيل الأوامر المستقبلية.
echo $GOOGLE_CLOUD_PROJECT
مخرجات الأمر
<PROJECT_ID>
- أخيرًا، قم بتعيين تهيئة المنطقة الافتراضية والمشروع.
gcloud config set compute/zone us-central1-f
يمكنك اختيار مجموعة متنوعة من المناطق المختلفة. لمزيد من المعلومات، راجع المناطق المناطق:
3- إنشاء خدمة gRPC
إنشاء مشروع Java جديد باستخدام Maven:
$ mvn archetype:generate -DgroupId=com.example.grpc \ -DartifactId=grpc-hello-server \ -DarchetypeArtifactId=maven-archetype-quickstart \ -DinteractiveMode=false $ cd grpc-hello-server
إضافة ملف تعريف gRPC
في gRPC، يجب تسجيل حمولات الخدمة (الطلب والاستجابة) وعمليات الخدمة باستخدام لغة تعريف الواجهة (IDL). تستخدم gRPC بنية Protobuffer 3 لتحديد حمولات الرسائل والعمليات. لننشئ ملفًا أوليًا لخدمة ترحيب بسيطة تتضمن طلب ترحيب ورد ترحيب.
أولاً، قم بإنشاء دليل Proto جديد للاحتفاظ بملف Proto الجديد:
$ mkdir -p src/main/proto
بعد ذلك، يمكنك إنشاء ملف Proto جديد باسم src/main/proto/GreetingService.proto
.
يمكنك استخدام vim,nano,
أو emacs
لتعديل الملف:
src/main/proto/GreetingService.proto
syntax = "proto3"; package com.example.grpc; // Request payload message HelloRequest { // Each message attribute is strongly typed. // You also must assign a "tag" number. // Each tag number is unique within the message. string name = 1; // This defines a strongly typed list of String repeated string hobbies = 2; // There are many more basics types, like Enum, Map // See https://developers.google.com/protocol-buffers/docs/proto3 // for more information. } message HelloResponse { string greeting = 1; } // Defining a Service, a Service can have multiple RPC operations service GreetingService { // Define a RPC operation rpc greeting(HelloRequest) returns (HelloResponse); }
إضافة تبعيات gRPC والمكوّن الإضافي
فور حصولك على التعريف، يمكننا إنشاء كل من بديل الخادم والتحليق من جانب العميل من هذا الملف. ستحتاج إلى إضافة تبعيات gRPC ومكوناتها الإضافية.
أولاً، أضِف تبعيات gRPC إلى pom.xml
:
pom.xml
<project> ... <dependencies> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-netty-shaded</artifactId> <version>1.24.0</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-protobuf</artifactId> <version>1.24.0</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-stub</artifactId> <version>1.24.0</version> </dependency> <dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version> </dependency> ... </dependencies> ... </project>
ثم أضف المكون الإضافي:
pom.xml
<project> ... <dependencies> ... </dependencies> <build> <extensions> <extension> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>1.6.2</version> </extension> </extensions> <plugins> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <version>0.6.1</version> <configuration> <protocArtifact>com.google.protobuf:protoc:3.9.0:exe:${os.detected.classifier}</protocArtifact> <pluginId>grpc-java</pluginId> <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.24.0:exe:${os.detected.classifier}</pluginArtifact> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
إنشاء البذور
عند إنشاء التطبيق، سيقوم المكون الإضافي بتحويل تعريفات Proto إلى رمز Java.
$ mvn -DskipTests package
للاطّلاع على الملفات التي تم إنشاؤها:
$ find target/generated-sources
تنفيذ الخدمة
أولاً، أنشئ فئة GreetingServiceImpl
جديدة لتنفيذ العملية greeting
:
src/main/java/com/example/grpc/GreetingServiceImpl.java
package com.example.grpc; import io.grpc.stub.StreamObserver; public class GreetingServiceImpl extends GreetingServiceGrpc.GreetingServiceImplBase { @Override public void greeting(GreetingServiceOuterClass.HelloRequest request, StreamObserver<GreetingServiceOuterClass.HelloResponse> responseObserver) { // HelloRequest has toString auto-generated. System.out.println(request); // You must use a builder to construct a new Protobuffer object GreetingServiceOuterClass.HelloResponse response = GreetingServiceOuterClass.HelloResponse.newBuilder() .setGreeting("Hello there, " + request.getName()) .build(); // Use responseObserver to send a single response back responseObserver.onNext(response); // When you are done, you must call onCompleted. responseObserver.onCompleted(); } }
تنفيذ الخادم
وأخيرًا، سينبغي لك بدء تشغيل خادم للاستماع على منفذ وتسجيل تنفيذ هذه الخدمة. عدِّل الفئة App
وهي الطريقة الأساسية التالية:
src/main/java/com/example/grpc/App.java
package com.example.grpc; import io.grpc.*; public class App { public static void main( String[] args ) throws Exception { // Create a new server to listen on port 8080 Server server = ServerBuilder.forPort(8080) .addService(new GreetingServiceImpl()) .build(); // Start the server server.start(); // Server threads are running in the background. System.out.println("Server started"); // Don't exit the main thread. Wait until server is terminated. server.awaitTermination(); } }
أخيرًا، شغِّل الخادم:
$ mvn -DskipTests package exec:java -Dexec.mainClass=com.example.grpc.App ... Server Started
4. استخدام الخدمة
سبق أن أنشأ المولد جميع التداخلات من جانب العميل. لتبسيط التمرين المعملي، سنستخدم مشروع Maven نفسه، ولكننا سنضيف فئة Client
جديدة بطريقة رئيسية جديدة.
أولاً، انقر على + لفتح جلسة Cloud Shell جديدة حتى لا تحتاج إلى إنهاء الخادم:
في الجلسة الجديدة، يمكنك التبديل إلى دليل grpc-hello-server
:
$ cd grpc-hello-server
بعد ذلك، أضِف فئة Client
الجديدة:
src/main/java/com/example/grpc/Client.java
package com.example.grpc; import io.grpc.*; public class Client { public static void main( String[] args ) throws Exception { // Channel is the abstraction to connect to a service endpoint // Let's use plaintext communication because we don't have certs final ManagedChannel channel = ManagedChannelBuilder.forTarget("localhost:8080") .usePlaintext(true) .build(); // It is up to the client to determine whether to block the call // Here we create a blocking stub, but an async stub, // or an async stub with Future are always possible. GreetingServiceGrpc.GreetingServiceBlockingStub stub = GreetingServiceGrpc.newBlockingStub(channel); GreetingServiceOuterClass.HelloRequest request = GreetingServiceOuterClass.HelloRequest.newBuilder() .setName("Ray") .build(); // Finally, make the call using the stub GreetingServiceOuterClass.HelloResponse response = stub.greeting(request); System.out.println(response); // A Channel should be shutdown before stopping the process. channel.shutdownNow(); } }
أخيرًا، شغِّل البرنامج:
$ mvn -DskipTests package exec:java -Dexec.mainClass=com.example.grpc.Client ... greeting: "Hello there, Ray"
هذا كل شيء! الأمر بسيط للغاية، أليس كذلك؟
5- خدمة البث
ثمة طرق أخرى كثيرة يمكنك تجربتها. على سبيل المثال، يمكنك إنشاء خدمة بث بسهولة عن طريق إضافة الكلمة الرئيسية stream
في ملف proto إلى الطلب أو معلَمة الاستجابة، مثل
src/main/proto/GreetingService.proto
syntax = "proto3"; package com.example.grpc; ... // Defining a Service, a Service can have multiple RPC operations service GreetingService { // MODIFY HERE: Update the return to streaming return. rpc greeting(HelloRequest) returns (stream HelloResponse); }
عدِّل الخادم لإرسال عدة ردود بدلاً من إرسال رد واحد فقط. يمكنك إجراء ذلك عن طريق إجراء عدة مكالمات من "responseObserver.onNext(...)
" على النحو التالي:
src/main/java/com/example/grpc/GreetingServiceImpl.java
package com.example.grpc; import io.grpc.stub.StreamObserver; public class GreetingServiceImpl extends GreetingServiceGrpc.GreetingServiceImplBase { @Override public void greeting(GreetingServiceOuterClass.HelloRequest request, StreamObserver<GreetingServiceOuterClass.HelloResponse> responseObserver) { ... // Feel free to construct different responses if you'd like. responseObserver.onNext(response); responseObserver.onNext(response); responseObserver.onNext(response); // When you are done, you must call onCompleted. responseObserver.onCompleted(); } }
يجب أن يستخدم العميل كعبًا غير متزامنًا بدلاً من كعب المنع. عدِّل رمز العميل مع الحرص على تعديل النوع stub
إلى GreetingServiceStub
:
src/main/java/com/example/grpc/Client.java
package com.example.grpc; import io.grpc.*; // New import import io.grpc.stub.*; public class Client { public static void main( String[] args ) throws Exception { final ManagedChannel channel = ManagedChannelBuilder.forTarget("localhost:8080") .usePlaintext(true) .build(); // Replace the previous synchronous code with asynchronous code. // This time use an async stub: GreetingServiceGrpc.GreetingServiceStub stub = GreetingServiceGrpc.newStub(channel); // Construct a request GreetingServiceOuterClass.HelloRequest request = GreetingServiceOuterClass.HelloRequest.newBuilder() .setName("Ray") .build(); // Make an Asynchronous call. Listen to responses w/ StreamObserver stub.greeting(request, new StreamObserver<GreetingServiceOuterClass.HelloResponse>() { public void onNext(GreetingServiceOuterClass.HelloResponse response) { System.out.println(response); } public void onError(Throwable t) { } public void onCompleted() { // Typically you'll shutdown the channel somewhere else. // But for the purpose of the lab, we are only making a single // request. We'll shutdown as soon as this request is done. channel.shutdownNow(); } }); } }
إعادة إنشاء التطبيق:
$ mvn -DskipTests package
أعِد تشغيل كل من الخادم والعميل في جلسة Cloud Shell الخاصة به.
لبدء تشغيل الخادم:
$ mvn exec:java -Dexec.mainClass=com.example.grpc.App ... Server Started
لبدء تشغيل البرنامج:
$ mvn exec:java -Dexec.mainClass=com.example.grpc.Client ... greeting: "Hello there, Ray" greeting: "Hello there, Ray" greeting: "Hello there, Ray"
6- تهانينا!
المواضيع التي تناولناها:
- لغة مخزن البروتوكول المؤقت
- كيفية تنفيذ خادم gRPC باستخدام Java
- كيفية تنفيذ برنامج gRPC باستخدام Java
الخطوات التالية:
- تعرَّف على المزيد من المعلومات عن gRPC Java.
- الاطّلاع على المزيد من أمثلة Java لـ gRPC على GitHub
- مزيد من المعلومات حول البث في gRPC
- مزيد من المعلومات حول تحويل الترميز باستخدام gRPC إلى REST
يُرجى إرسال ملاحظاتك إلينا
- يُرجى تخصيص بعض الوقت لإكمال الاستطلاع القصير جدًا.