1. بررسی اجمالی
gRPC یک چارچوب و مجموعه ابزار فراخوانی روش از راه دور از راه دور (RPC) بی طرف از نظر زبان و پلتفرم خنثی است که در گوگل توسعه یافته است. این به شما امکان می دهد یک سرویس را با استفاده از Protocol Buffers، یک مجموعه ابزار و زبان سریال سازی باینری قدرتمند تعریف کنید. سپس به شما این امکان را میدهد که از تعریف سرویس خود به زبانهای مختلف، کلاینت و سرور اصطلاحی ایجاد کنید.
در این کد لبه، شما یاد خواهید گرفت که چگونه یک سرویس مبتنی بر جاوا بسازید که یک API را با استفاده از چارچوب gRPC در معرض نمایش قرار دهد، و سپس یک کلاینت بنویسید تا از خرد سمت مشتری gRPC تولید شده استفاده کند.
چیزی که یاد خواهید گرفت
- زبان بافر پروتکل
- نحوه پیاده سازی سرویس gRPC با استفاده از جاوا
- نحوه پیاده سازی کلاینت gRPC با استفاده از جاوا
چگونه از این آموزش استفاده خواهید کرد؟
به تجربه خود از ساخت اپلیکیشن های Node.js چه امتیازی می دهید؟
به تجربه خود از ساخت اپلیکیشن های Go چگونه امتیاز می دهید؟
2. راه اندازی و الزامات
تنظیم محیط خود به خود
- به کنسول Cloud وارد شوید و یک پروژه جدید ایجاد کنید یا از یک موجود استفاده مجدد کنید. اگر قبلاً یک حساب Gmail یا Google Workspace ندارید، باید یک حساب ایجاد کنید .
شناسه پروژه را به خاطر بسپارید، یک نام منحصر به فرد در تمام پروژه های Google Cloud (نام بالا قبلاً گرفته شده است و برای شما کار نخواهد کرد، متأسفیم!). بعداً در این آزمایشگاه کد به عنوان PROJECT_ID
نامیده خواهد شد.
- در مرحله بعد، برای استفاده از منابع Google Cloud، باید صورتحساب را در Cloud Console فعال کنید .
اجرا کردن از طریق این کد لبه نباید هزینه زیادی داشته باشد، اگر اصلاً باشد. حتماً دستورالعملهای موجود در بخش «تمیز کردن» را دنبال کنید که به شما توصیه میکند چگونه منابع را خاموش کنید تا بیش از این آموزش متحمل صورتحساب نشوید. کاربران جدید Google Cloud واجد شرایط برنامه آزمایشی رایگان 300 دلاری هستند.
Google Cloud Shell
در حالی که این کد لبه را می توان از رایانه شما کار کرد، در این کد لبه از Google Cloud Shell استفاده خواهیم کرد، یک محیط خط فرمان که در Cloud اجرا می شود.
این ماشین مجازی مبتنی بر دبیان با تمام ابزارهای توسعه که شما نیاز دارید بارگذاری شده است. این دایرکتوری اصلی 5 گیگابایتی دائمی را ارائه می دهد و در Google Cloud اجرا می شود و عملکرد شبکه و احراز هویت را بسیار افزایش می دهد. این بدان معنی است که تمام چیزی که برای این کد لبه نیاز دارید یک مرورگر است (بله، روی کروم بوک کار می کند).
- برای فعال کردن Cloud Shell از Cloud Console، کافی است روی Activate 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 ایجاد کنید
یک پروژه جاوا جدید با 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 برای تعریف بارهای پیام و عملیات استفاده می کند. بیایید یک فایل پروتو برای یک سرویس خوش آمدگویی ساده با درخواست سلام و پاسخ سلام ایجاد کنیم.
ابتدا یک دایرکتوری پروتو جدید برای نگهداری فایل پروتوی جدید ایجاد کنید:
$ mkdir -p src/main/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>
Stubs را تولید کنید
هنگامی که برنامه را می سازید، افزونه تعاریف اولیه را به کد جاوا تبدیل می کند.
$ 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
در فایل پروتو به پارامتر درخواست یا پاسخ، به راحتی یک سرویس استریم بسازید.
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 با استفاده از جاوا
- نحوه پیاده سازی کلاینت gRPC با استفاده از جاوا
مراحل بعدی:
- درباره gRPC جاوا بیشتر بدانید
- نمونه های بیشتر gRPC جاوا را در GitHub ببینید
- در مورد جریان در gRPC بیاموزید
- درباره gRPC to REST Transcoding بیشتر بیاموزید
نظرات خود را با ما در میان بگذارید
- لطفا یک لحظه برای تکمیل نظرسنجی بسیار کوتاه ما وقت بگذارید