新疆建设云网站办理程序淘宝标题优化网站
前言: grpc 是geogle 开源的rpc 通信框架,通过定义proto生成通信存根,像本地调用服务一样,进行远程服务的调用;
1 消费端服务提供:
1.1 引入grpc 和 protobuf
<!-- RPC -->
<!-- RPC 服务调用 -->
<dependency><groupId>net.devh</groupId><artifactId>grpc-spring-boot-starter</artifactId><version>2.10.1.RELEASE</version>
</dependency>
<!-- protobuf 协议缓冲区-->
<dependency><groupId>com.google.protobuf</groupId><artifactId>protobuf-java-util</artifactId><version>3.12.2</version>
</dependency>
1.2 要想根据proto文件生成服务的存根,这里引入对应的maven 插件:
<extensions><!-- 确定当前的操作系统和体系结构 --><extension><groupId>kr.motd.maven</groupId><artifactId>os-maven-plugin</artifactId><version>1.6.2</version></extension>
</extensions>
<plugin><groupId>org.xolstice.maven.plugins</groupId><artifactId>protobuf-maven-plugin</artifactId><version>0.6.1</version><configuration><!-- 消息体生成工具 --><protocArtifact>com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier}</protocArtifact><!-- java rpc 代码生成 --><pluginId>grpc-java</pluginId><!-- java rpc 代码生成功能 --><pluginArtifact>io.grpc:protoc-gen-grpc-java:1.32.1:exe:${os.detected.classifier}</pluginArtifact><!-- proto 的文件源 --><protoSourceRoot>src/main/proto</protoSourceRoot><!-- <outputDirectory>src/main/java</outputDirectory>--><!-- 消息体生成后不进行清除 --><clearOutputDirectory>false</clearOutputDirectory></configuration><executions><execution><goals><!-- 执行的任务 --><goal>compile</goal><goal>compile-custom</goal></goals></execution></executions>
</plugin>
插件引入后如图所示:
插件安装完成会出现protobuf 插件:
1.3 定义proto 文件 hello.proto:
// 语法使用proto3syntax = "proto3";//option java_multiple_files = false ;// java 生成的jar包类option java_package = "bl.grpc.es";// java 生成的消息类名称option java_outer_classname = "HelloWorldProto";// 该 proto 的包类名多个proto 文件package 不能相同package bl.es;// 请求参数message HelloRequest {string name = 1;}// 返回的结果message HelloResponse {string name = 1;string status = 2;}// rpc 服务service HelloService {// 定义hello 方法rpc hello(HelloRequest) returns(HelloResponse) {}}
通过maven ->compile 编译生成java 消息体及rpc 服务:
生成类所在路径为,改项目 target 目录下 \generated-sources\protobuf :
1.4 暴露要对外的接口 HelloServiceGrpcOne :
package org.lgx.bluegrass.bluegrasses.proto;import bl.grpc.es.HelloServiceGrpc;
import bl.grpc.es.HelloWorldProto;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;/*** @Description TODO* @Date 2023/2/28 11:21* @Author lgx* @Version 1.0*/
// 服务端注解标识
@GrpcService
public class HelloServiceGrpcOne extends HelloServiceGrpc.HelloServiceImplBase{@Overridepublic void hello(HelloWorldProto.HelloRequest request, StreamObserver<HelloWorldProto.HelloResponse> responseObserver) {// 数据处理并返回HelloWorldProto.HelloResponse reply = HelloWorldProto.HelloResponse.newBuilder().setName("Hello ========== " + request.getName()).setStatus("200").build();responseObserver.onNext(reply);responseObserver.onCompleted();}
}
bootstrap.yml 暴露grpc 服务端口:
grpc:server:port: 6000
至此服务端暴露完成;
2 消费端远程调用:
2.1 同服务端相同,也需要引入grpc 和 protobuf ;以及proto文件生成服务的存根,引入对应的maven 插件;
2.2 定义消费端:
1)HelloWorldClient :
package org.lgx.bluegrass.bluegrasscoree.proto;import bl.grpc.es.HelloServiceGrpc;
import bl.grpc.es.HelloWorldProto;
import io.grpc.Channel;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.stereotype.Service;/*** @Description TODO* @Date 2023/2/28 13:47* @Author lgx* @Version 1.0*/
@Service
public class HelloWorldClient {@GrpcClient("cloud-grpc-server")private Channel serverChannel;public String hello(String name) {HelloServiceGrpc.HelloServiceBlockingStub stub = HelloServiceGrpc.newBlockingStub(serverChannel);HelloWorldProto.HelloRequest.Builder builder = HelloWorldProto.HelloRequest.newBuilder().setName(name);HelloWorldProto.HelloResponse response = stub.hello(builder.build());return "{'responseStatus':'" + response.getStatus() + "','result':[]}"+response.getName();}
}
2)GrpcTestController :
package org.lgx.bluegrass.bluegrasscoree.controller.protogrpc;import lombok.extern.slf4j.Slf4j;
import org.lgx.bluegrass.bluegrasscoree.proto.HelloWorldClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/*** @Description TODO* @Date 2023/2/28 13:55* @Author lgx* @Version 1.0*/
@Slf4j
@RestController
public class GrpcTestController {@Autowiredprivate HelloWorldClient service;@GetMapping(value = "/hello")public String test(String name) {String result = "";try {result = service.hello(name);log.info("respString : {}", result);return result;} catch (Throwable e) {log.error("hello error", e);}return result;}
}
1.3 消费端bootstrap.yml定义要连接的服务端:
grpc:client:# 服务名称cloud-grpc-server:# 服务地址address: static://localhost:6000 #指定grpc服务端地址# 保持长连接enableKeepAlive: truekeepAliveWithoutCalls: truenegotiationType: plaintext
1.4 测试:
http://localhost:9082/hello?name=%E5%BC%A0%E4%B8%8912344
总结:
1 ) 需要引入proto ,java生成插件生成消息体和rpc 的服务调用代码;
2 ) 服务端通过继承rpc 类实现具体业务的实现;
3 ) 消费端通过注入rpc 的bean 完成远程方法的调用;
4)grpc 使用协议存根来替代dubbo 中定义的要外发布的接口,更加的灵活;
参考:
1 grpc 介绍;
2 grpc 协议缓冲区;