将Grpc添加到您的Java应用程序中
Grpc 是一个高性能的、开源的通用RPC框架。
使用gRPC有各种好处:
- 它通过提供客户/服务器代码简化了开发工作
- 它支持多种语言
这一切都始于定义一个.proto文件,.proto文件位于src/main/proto文件中。
请注意,将proto文件保存在repo上是一个很好的做法,并且有一些模式的版本控制。这样,其他团队的开发者可以通过引用这些文件来生成他们的SDK,甚至是其他语言的SDK。
我们将在 src/main/proto/Order.proto 上创建一个订单服务。
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.egkatzioura.order.v1";
service OrderService {
rpc ExecuteOrder(OrderRequest) returns (OrderResponse) {};
}
message OrderRequest {
string email = 1;
string product = 2;
int32 amount = 3;
}
message OrderResponse {
string info = 1;
}
为了与grpc一起工作,需要放置以下二进制文件
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.39.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.39.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.39.0</version>
</dependency>
<dependency> <!-- necessary for Java 9+ -->
<groupId>org.apache.tomcat</groupId>
<artifactId>annotations-api</artifactId>
<version>6.0.53</version>
<scope>provided</scope>
</dependency>
<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.17.2:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.39.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
通过执行mvn clean install,这些类将在target/classes上生成。
这些类足以启动一个服务器并运行一个客户端来与之通信。
因此,让我们尝试启动服务器。
我们将创建一个服务实现
package com.egkatzioura.order.impl;
import com.egkatzioura.order.v1.Order;
import com.egkatzioura.order.v1.OrderServiceGrpc;
import io.grpc.stub.StreamObserver;
public class OrderServiceImpl extends OrderServiceGrpc.OrderServiceImplBase {
@Override
public void executeOrder(Order.OrderRequest request, StreamObserver&lt;Order.OrderResponse&gt; responseObserver) {
Order.OrderResponse response = Order.OrderResponse.newBuilder()
.setInfo("Hi "+request.getEmail()+", you order has been executed")
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
然后我们的主类将启动服务器并为请求提供服务。
package com.egkatzioura.order;
import java.io.IOException;
import com.egkatzioura.order.impl.OrderServiceImpl;
import io.grpc.Server;
import io.grpc.ServerBuilder;
public class Application {
public static void main(String[] args) throws IOException, InterruptedException {
Server server = ServerBuilder
.forPort(8080)
.addService(new OrderServiceImpl()).build();
server.start();
server.awaitTermination();
}
}
当服务器运行时,我们可以启动另一个主类,它将与服务器通信并向服务器执行一个grpc请求。
package com.egkatzioura.order;
import com.egkatzioura.order.v1.Order;
import com.egkatzioura.order.v1.OrderServiceGrpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
public class ApplicationClient {
public static void main(String[] args) {
ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 8080)
.usePlaintext()
.build();
OrderServiceGrpc.OrderServiceBlockingStub orderServiceBlockingStub
= OrderServiceGrpc.newBlockingStub(managedChannel);
Order.OrderRequest orderRequest = Order.OrderRequest.newBuilder()
.setEmail("hello@word.com")
.setProduct("no-name")
.setAmount(3)
.build();
Order.OrderResponse orderResponse = orderServiceBlockingStub.executeOrder(orderRequest);
System.out.println("Received response: "+orderResponse.getInfo());
managedChannel.shutdown();
}
}
因此,我们只是自动生成了grpc代码,我们用一个实现支持了一个grpc服务,一个服务器启动了,一个客户端从服务器上得到了一个响应。