1. ภาพรวม
gRPC เป็นเฟรมเวิร์กและชุดเครื่องมือสำหรับการเรียกกระบวนการทำงานจากระยะไกล (RPC) ที่ไม่ขึ้นกับภาษาและแพลตฟอร์ม ซึ่งพัฒนาขึ้นที่ Google ซึ่งช่วยให้คุณกำหนดบริการโดยใช้ Protocol Buffers ซึ่งเป็นชุดเครื่องมือและภาษาสำหรับการซีเรียลไลซ์แบบไบนารีที่มีประสิทธิภาพเป็นพิเศษ จากนั้นจะช่วยให้คุณสร้าง Stub ไคลเอ็นต์และเซิร์ฟเวอร์ที่เหมาะสมจากคำจำกัดความของบริการในภาษาต่างๆ ได้
ในโค้ดแล็บนี้ คุณจะได้เรียนรู้วิธีสร้างบริการที่ใช้ Java ซึ่งแสดง API โดยใช้เฟรมเวิร์ก gRPC จากนั้นเขียนไคลเอ็นต์เพื่อใช้ Stub ฝั่งไคลเอ็นต์ gRPC ที่สร้างขึ้น
สิ่งที่คุณจะได้เรียนรู้
- ภาษาบัฟเฟอร์โปรโตคอล
- วิธีติดตั้งใช้งานบริการ gRPC โดยใช้ Java
- วิธีติดตั้งใช้งานไคลเอ็นต์ gRPC โดยใช้ Java
คุณจะใช้บทแนะนำนี้อย่างไร
คุณจะให้คะแนนประสบการณ์ในการสร้างแอป Node.js เท่าใด
คุณจะให้คะแนนประสบการณ์ในการสร้างแอป Go เท่าใด
2. การตั้งค่าและข้อกำหนด
การตั้งค่าสภาพแวดล้อมแบบเรียนรู้ด้วยตนเอง
- ลงชื่อเข้าใช้ Cloud Console แล้วสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้องสร้างบัญชี



โปรดจดจำรหัสโปรเจ็กต์ ซึ่งเป็นชื่อที่ไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมด (ชื่อด้านบนมีผู้ใช้แล้วและจะใช้ไม่ได้ ขออภัย) ซึ่งจะเรียกว่า PROJECT_ID ในภายหลังใน Codelab นี้
- จากนั้นคุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร Google Cloud
การทำตาม Codelab นี้ไม่ควรมีค่าใช้จ่ายมากนัก หรืออาจไม่มีเลย โปรดทำตามวิธีการในส่วน "การล้างข้อมูล" ซึ่งจะแนะนำวิธีปิดทรัพยากรเพื่อไม่ให้มีการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ ผู้ใช้ Google Cloud รายใหม่มีสิทธิ์เข้าร่วมโปรแกรมช่วงทดลองใช้ฟรีมูลค่า$300 USD
Google Cloud Shell
แม้ว่าคุณจะใช้งาน Codelab นี้จากคอมพิวเตอร์ได้ แต่ใน Codelab นี้เราจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมบรรทัดคำสั่งที่ทำงานในระบบคลาวด์
เครื่องเสมือนที่ใช้ Debian นี้มาพร้อมเครื่องมือพัฒนาทั้งหมดที่คุณต้องการ โดยมีไดเรกทอรีหลักแบบถาวรขนาด 5 GB และทำงานใน 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 (Interface Definition Language) gRPC ใช้ไวยากรณ์ Protobuffer 3 เพื่อกำหนดเพย์โหลดของข้อความและการดำเนินการ มาสร้างไฟล์ Proto สำหรับบริการทักทายอย่างง่ายที่มีคำขอ Hello และการตอบกลับ Hello กัน
ก่อนอื่นให้สร้างไดเรกทอรี 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
เมื่อคุณมีคำจำกัดความแล้ว เราจะสร้างทั้ง Stub ฝั่งเซิร์ฟเวอร์และ Stub ฝั่งไคลเอ็นต์จากไฟล์นี้ได้ คุณจะต้องเพิ่มทรัพยากร Dependency และปลั๊กอิน 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>
สร้าง Stub
เมื่อคุณสร้างแอปพลิเคชัน ปลั๊กอินจะแปลงคำจำกัดความ 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 class และเมธอดหลักของ class ดังนี้
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. การใช้บริการ
เครื่องมือสร้างได้สร้าง Stub ฝั่งไคลเอ็นต์ทั้งหมดแล้ว เพื่อให้แล็บนี้ง่ายขึ้น เราจะใช้โปรเจ็กต์ Maven เดียวกัน แต่จะเพิ่มคลาส Client ใหม่ที่มีเมธอด main ใหม่
ก่อนอื่น ให้คลิก + เพื่อเปิดเซสชัน 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 แบบอะซิงโครนัสแทน Stub ที่บล็อก อัปเดตรหัสไคลเอ็นต์โดยตรวจสอบว่าได้อัปเดตประเภท 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
- ดูตัวอย่าง gRPC Java เพิ่มเติมใน GitHub
- ดูข้อมูลเกี่ยวกับการสตรีมใน gRPC
- ดูข้อมูลเพิ่มเติมเกี่ยวกับ gRPC ไปยัง REST Transcoding
แสดงความคิดเห็น
- โปรดสละเวลาสักครู่เพื่อทำแบบสำรวจสั้นๆ ของเรา