Java के साथ gRPC सेवा बनाना

1. खास जानकारी

gRPC, भाषा के लिए न्यूट्रल, प्लैटफ़ॉर्म न्यूट्रल रिमोट प्रोसेस कॉल (RPC) फ़्रेमवर्क और टूलसेट है. इसे Google ने बनाया है. यह प्रोटोकॉल बफ़र का इस्तेमाल करके, किसी सेवा को तय करने में आपकी मदद करता है. यह खास तौर पर ज़्यादा कारगर बाइनरी सीरियलाइज़ेशन टूलसेट और भाषा है. इसके बाद, यह आपको कई भाषाओं में अपनी सेवा की परिभाषा से मुहावरेदार क्लाइंट और सर्वर स्टब जनरेट करने देता है.

इस कोडलैब में, आपको Java पर आधारित ऐसी सेवा बनाने का तरीका पता चलेगा जो gRPC फ़्रेमवर्क का इस्तेमाल करके, एपीआई की जानकारी देती है. इसके बाद, आपको जनरेट किए गए gRPC क्लाइंट-साइड स्टब को इस्तेमाल करने के लिए क्लाइंट लिखने की जानकारी मिलेगी.

आपको इनके बारे में जानकारी मिलेगी

  • प्रोटोकॉल बफ़र लैंग्वेज
  • Java का इस्तेमाल करके gRPC सेवा को लागू करने का तरीका
  • Java का इस्तेमाल करके gRPC क्लाइंट को कैसे लागू करें

इस ट्यूटोरियल का इस्तेमाल कैसे किया जाएगा?

इसे सिर्फ़ पढ़ें इसे पढ़ें और कसरतों को पूरा करें

Node.js ऐप्लिकेशन बनाने के अपने अनुभव को आप कितनी रेटिंग देंगे/देंगी?

शुरुआती इंटरमीडिएट कुशल

Go ऐप्लिकेशन बनाने के अपने अनुभव को आप कितनी रेटिंग देंगे?

शुरुआती इंटरमीडिएट कुशल

2. सेटअप और ज़रूरी शर्तें

अपने हिसाब से एनवायरमेंट सेटअप करना

  1. Cloud Console में साइन इन करें और नया प्रोजेक्ट बनाएं या किसी मौजूदा प्रोजेक्ट का फिर से इस्तेमाल करें. अगर आपके पास पहले से Gmail या Google Workspace खाता नहीं है, तो आपको नया खाता बनाना होगा.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

प्रोजेक्ट आईडी याद रखें. यह Google Cloud के सभी प्रोजेक्ट के लिए एक खास नाम होता है (ऊपर दिया गया नाम पहले ही ले लिया गया है और यह आपके लिए काम नहीं करेगा!). बाद में, इस कोडलैब को इस कोडलैब में PROJECT_ID के तौर पर दिखाया जाएगा.

  1. इसके बाद, आपको Google Cloud के संसाधनों का इस्तेमाल करने के लिए, Cloud Console में बिलिंग की सुविधा चालू करनी होगी.

इस कोडलैब का इस्तेमाल करने पर, आपको ज़्यादा पैसे नहीं चुकाने होंगे. "साफ़ करना" सेक्शन में दिए गए निर्देशों का पालन करना न भूलें सेक्शन में, संसाधनों को बंद करने का तरीका बताया गया है. इससे इस ट्यूटोरियल के अलावा बिलिंग की सुविधा नहीं मिलेगी. Google Cloud के नए उपयोगकर्ता, 300 डॉलर के मुफ़्त ट्रायल वाले प्रोग्राम में हिस्सा ले सकते हैं.

Google Cloud शेल

इस कोडलैब को आपके कंप्यूटर से ऑपरेट किया जा सकता है. हालांकि, इस कोडलैब में हम Google Cloud Shell का इस्तेमाल करेंगे. यह क्लाउड में चलने वाला कमांड लाइन एनवायरमेंट है.

Debian आधारित इस वर्चुअल मशीन में ऐसे सभी डेवलपमेंट टूल मौजूद हैं जिनकी आपको ज़रूरत पड़ेगी. यह पांच जीबी की स्थायी होम डायरेक्ट्री उपलब्ध कराता है और Google Cloud में चलता है. यह नेटवर्क की परफ़ॉर्मेंस और पुष्टि करने की प्रोसेस को बेहतर बनाता है. इसका मतलब है कि इस कोडलैब के लिए आपको सिर्फ़ एक ब्राउज़र की ज़रूरत होगी. हां, यह Chromebook पर काम करता है.

  1. Cloud Console से Cloud Shell को चालू करने के लिए, Cloud Shell को चालू करें a8460e837e9f5fda.png पर क्लिक करें. प्रावधान करने और एनवायरमेंट से कनेक्ट होने में कुछ ही समय लगेगा.

b532b2f19ab85dda.png

14-06-2017 को 10.13.43 PM.png पर स्क्रीन शॉट लिया गया

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 के डैशबोर्ड में देखें:

2485e00c1223af09.png

Cloud Shell, डिफ़ॉल्ट रूप से कुछ एनवायरमेंट वैरिएबल सेट करता है. ये वैरिएबल, आने वाले समय में कमांड चलाने के दौरान काम आ सकते हैं.

echo $GOOGLE_CLOUD_PROJECT

कमांड आउटपुट

<PROJECT_ID>
  1. आखिर में, डिफ़ॉल्ट ज़ोन और प्रोजेक्ट कॉन्फ़िगरेशन सेट करें.
gcloud config set compute/zone us-central1-f

आपके पास कई तरह के ज़ोन चुनने का विकल्प होता है. ज़्यादा जानकारी के लिए, क्षेत्र और ज़ोन.

3. कोई gRPC सेवा बनाएं

Maven के साथ नया Java प्रोजेक्ट बनाएं:

$ 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 डिपेंडेंसी और प्लगिन जोड़ना होगा.

सबसे पहले, pom.xml में gRPC डिपेंडेंसी जोड़ें:

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>

स्टब जनरेट करें

ऐप्लिकेशन बनाने के बाद, प्लगिन प्रोटो परिभाषाओं को 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 सेशन खोलने के लिए + पर क्लिक करें, ताकि आपको सर्वर बंद करने की ज़रूरत न पड़े:

1ff0fda960b9adfc.png

नए सेशन में, 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. बधाई हो!

हमने इन विषयों के बारे में बात की:

  • प्रोटोकॉल बफ़र लैंग्वेज
  • Java का इस्तेमाल करके gRPC सर्वर को कैसे लागू करें
  • Java का इस्तेमाल करके gRPC क्लाइंट को कैसे लागू करें

अगले चरण:

हमें अपना सुझाव/राय दें या शिकायत करें

  • कृपया थोड़ा समय निकालकर, हमारे बहुत छोटे से सर्वे को पूरा करें