Membuat layanan gRPC dengan Java

1. Ringkasan

gRPC adalah framework dan rangkaian alat panggilan prosedur (RPC) jarak jauh yang tidak tergantung bahasa dan platform yang dikembangkan di Google. Library ini memungkinkan Anda menentukan layanan menggunakan Protocol Buffers, yakni rangkaian alat dan bahasa serialisasi biner yang sangat andal. Kemudian, Anda dapat membuat stub klien dan server idiomatis dari definisi layanan dalam berbagai bahasa.

Dalam codelab ini, Anda akan mempelajari cara membangun layanan berbasis Java yang mengekspos API menggunakan framework gRPC, lalu menulis klien untuk menggunakan stub sisi klien gRPC yang dihasilkan.

Yang akan Anda pelajari

  • {i>Protocol Buffer Language<i} (Bahasa Penyangga Protokol)
  • Cara mengimplementasikan layanan gRPC menggunakan Java
  • Cara menerapkan klien gRPC menggunakan Java

Bagaimana Anda akan menggunakan tutorial ini?

Hanya membacanya Membacanya dan menyelesaikan latihan

Bagaimana Anda menilai pengalaman Anda membangun aplikasi Node.js?

Pemula Menengah Mahir

Bagaimana Anda menilai pengalaman Anda membuat aplikasi Go?

Pemula Menengah Mahir

2. Penyiapan dan Persyaratan

Penyiapan lingkungan mandiri

  1. Login ke Cloud Console lalu buat project baru atau gunakan kembali project yang sudah ada. Jika belum memiliki akun Gmail atau Google Workspace, Anda harus membuatnya.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

Ingat project ID, nama unik di semua project Google Cloud (maaf, nama di atas telah digunakan dan tidak akan berfungsi untuk Anda!) Project ID tersebut selanjutnya akan dirujuk di codelab ini sebagai PROJECT_ID.

  1. Selanjutnya, Anda harus mengaktifkan penagihan di Cloud Console untuk menggunakan resource Google Cloud.

Menjalankan operasi dalam codelab ini seharusnya tidak memerlukan banyak biaya, bahkan mungkin tidak sama sekali. Pastikan untuk mengikuti petunjuk yang ada di bagian "Membersihkan" yang memberi tahu Anda cara menonaktifkan resource sehingga tidak menimbulkan penagihan di luar tutorial ini. Pengguna baru Google Cloud memenuhi syarat untuk mengikuti program Uji Coba Gratis senilai$300 USD.

Google Cloud Shell

Meskipun codelab ini dapat dioperasikan dari komputer Anda, dalam codelab ini kita akan menggunakan Google Cloud Shell, yaitu lingkungan command line yang berjalan di Cloud.

Mesin virtual berbasis Debian ini memuat semua alat pengembangan yang akan Anda perlukan. Layanan ini menawarkan direktori beranda tetap sebesar 5 GB dan beroperasi di Google Cloud, sehingga sangat meningkatkan performa dan autentikasi jaringan. Ini berarti bahwa semua yang Anda perlukan untuk codelab ini adalah browser (ya, ini berfungsi di Chromebook).

  1. Untuk mengaktifkan Cloud Shell dari Cloud Console, cukup klik Aktifkan Cloud Shella8460e837e9f5fda.png (hanya perlu beberapa saat untuk melakukan penyediaan dan terhubung ke lingkungan).

b532b2f19ab85dda.png

Screen Shot 2017-06-14 at 10.13.43 PM.png

Setelah terhubung ke Cloud Shell, Anda akan melihat bahwa Anda sudah diautentikasi dan project sudah ditetapkan ke PROJECT_ID.

gcloud auth list

Output perintah

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

Output perintah

[core]
project = <PROJECT_ID>

Jika, untuk beberapa alasan, project belum disetel, cukup jalankan perintah berikut:

gcloud config set project <PROJECT_ID>

Mencari PROJECT_ID Anda? Periksa ID yang Anda gunakan di langkah-langkah penyiapan atau cari di dasbor Cloud Console:

2485e00c1223af09.pngS

Cloud Shell juga menetapkan beberapa variabel lingkungan secara default, yang mungkin berguna saat Anda menjalankan perintah di masa mendatang.

echo $GOOGLE_CLOUD_PROJECT

Output perintah

<PROJECT_ID>
  1. Terakhir, tetapkan zona dan konfigurasi project default.
gcloud config set compute/zone us-central1-f

Anda dapat memilih berbagai zona yang berbeda. Untuk informasi selengkapnya, lihat Region & Zona.

3. Membuat Layanan gRPC

Buat project Java baru dengan Maven:

$ mvn archetype:generate -DgroupId=com.example.grpc \
 -DartifactId=grpc-hello-server \
 -DarchetypeArtifactId=maven-archetype-quickstart \
 -DinteractiveMode=false
$ cd grpc-hello-server

Menambahkan File Definisi gRPC

Dalam gRPC, payload layanan (permintaan dan respons) serta operasi layanan harus direkam dalam IDL (Interface Definition Language). gRPC menggunakan sintaksis Protobuffer 3 untuk menentukan payload dan operasi pesan. Mari kita buat file proto untuk Layanan Salam sederhana dengan Hello Request dan Hello Response.

Pertama, buat direktori proto baru untuk menyimpan file proto baru:

$ mkdir -p src/main/proto

Kemudian, buat file proto baru src/main/proto/GreetingService.proto.

Anda dapat menggunakan vim,nano, atau emacs untuk mengedit file:

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);
}

Menambahkan Dependensi dan Plugin gRPC

Setelah Anda memiliki definisi, kita dapat membuat stub sisi server dan stub sisi klien dari file ini. Anda harus menambahkan dependensi dan plugin gRPC.

Pertama, tambahkan dependensi gRPC ke 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>

Kemudian tambahkan plugin:

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>

Membuat Stub

Saat Anda membangun aplikasi, plugin akan mengonversi definisi proto ke dalam kode Java.

$ mvn -DskipTests package

Untuk melihat file yang dihasilkan:

$ find target/generated-sources

Mengimplementasikan Layanan

Pertama, buat class GreetingServiceImpl baru yang akan mengimplementasikan operasi 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();
  }
}

Mengimplementasikan Server

Terakhir, Anda harus memulai server untuk memantau port dan mendaftarkan implementasi layanan ini. Edit class App dan metode utamanya:

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();
    }
}

Terakhir, jalankan server:

$ mvn -DskipTests package exec:java -Dexec.mainClass=com.example.grpc.App
...
Server Started

4. Memakai Layanan

Generator telah membuat semua stub sisi klien. Untuk menyederhanakan lab, kita akan menggunakan project Maven yang sama, tetapi cukup menambahkan class Client baru dengan metode utama baru.

Pertama, klik + untuk membuka sesi Cloud Shell baru sehingga Anda tidak perlu menghentikan server:

1ff0fda960b9adfc.pngS

Pada sesi baru, beralihlah ke direktori grpc-hello-server:

$ cd grpc-hello-server

Kemudian, tambahkan class Client baru:

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();
    }
}

Terakhir, jalankan klien:

$ mvn -DskipTests package exec:java -Dexec.mainClass=com.example.grpc.Client
...
greeting: "Hello there, Ray"

Selesai. Cukup sederhana, bukan?

5. Layanan Streaming

Masih banyak lagi yang bisa Anda coba. Misalnya, Anda dapat membuat layanan streaming secara mudah, cukup dengan menambahkan kata kunci stream di file proto ke permintaan atau parameter respons, mis.

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);
}

Update server Anda untuk mengirim beberapa respons, bukan hanya satu. Anda dapat melakukannya dengan melakukan beberapa panggilan 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();
  }
}

Klien harus menggunakan stub asinkron, bukan stub pemblokiran. Perbarui kode klien dengan memastikan untuk memperbarui jenis stub ke 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();
        }
      });
    }
}

Build ulang aplikasi:

$ mvn -DskipTests package

Mulai ulang server dan klien masing-masing dalam sesi Cloud Shell-nya sendiri.

Untuk memulai server:

$ mvn exec:java -Dexec.mainClass=com.example.grpc.App
...
Server Started

Untuk memulai klien:

$ mvn exec:java -Dexec.mainClass=com.example.grpc.Client
...
greeting: "Hello there, Ray"
greeting: "Hello there, Ray"
greeting: "Hello there, Ray"

6. Selamat!

Yang telah kita bahas:

  • {i>Protocol Buffer Language<i} (Bahasa Penyangga Protokol)
  • Cara menerapkan server gRPC menggunakan Java
  • Cara menerapkan klien gRPC menggunakan Java

Langkah Berikutnya:

Kirimkan masukan Anda

  • Luangkan waktu Anda untuk menyelesaikan survei singkat kami