> 文档中心 > 使用grpc-server-spring-boot-starter及nacos搭建grpc服务

使用grpc-server-spring-boot-starter及nacos搭建grpc服务

在上一篇文章《java使用protobuf-maven-plugin的插件编译proto文件》中,我们使用protobuf-maven-plugin已经生成了grpc的调用的库,这篇文章我们将讲解使用SpringCloud及nacos搭建grpc服务。

具体的实现步骤:

1. 先在github下载一个nacos的release版本应用,下载​​​​​​​地址。 解压缩之后,进到nacos目录,执行如下指令启动nacos,这里我们测试,所以启动的是单机服务:

sh ./bin/startup.sh -m standalone

运行成功后在网页访问:http://localhost:8848/nacos,打开后进到nacos登录页面,使用默认账号/密码:nacos/nacos进行登录。

登录成功后,我们可以看到nacos提供了ConfigManagement和ServiceManagement,我们要看的是服务注册中心的ServiceManagement。

2. 我们在上一章lib的工程中,创建三个module,分别为cloud-grpc-provider9090和cloud-grpc-provider9091和cloud-grpc-consumer10020。 前两个提供服务的grpc的provider的服务端, 后面一个consumer为grpc的消费端。项目结构如下:

3. 在父工程的POM文件中添加如下包依赖

  8 8 1.8 2.11.1 0.6.1 2.3.9.RELEASE Hoxton.SR9 2.1.0.RELEASE 3.14.0 1.35.0  2.13.1.RELEASE         <!--       org.springframework.boot  spring-boot-dependencies  ${spring.boot.version}  pom  import     -->       org.springframework.boot  spring-boot-dependencies  ${spring.boot.version}  pom  import            org.springframework.cloud  spring-cloud-dependencies  ${springcloud.version}  pom  import            com.alibaba.cloud  spring-cloud-alibaba-dependencies  ${springcloud.alibaba.version}  pom  import                 com.fasterxml.jackson.dataformat  jackson-dataformat-xml  ${jackson.version}                 net.devh  grpc-client-spring-boot-starter  ${grpc.starter.version}            net.devh  grpc-client-spring-boot-autoconfigure  ${grpc.starter.version}            net.devh  grpc-server-spring-boot-starter  ${grpc.starter.version}            net.devh  grpc-server-spring-boot-autoconfigure  ${grpc.starter.version}                 io.grpc  grpc-protobuf  ${grpc.java.version}            io.grpc  grpc-stub  ${grpc.java.version}            io.grpc  grpc-netty-shaded  ${grpc.java.version}            io.grpc  grpc-services  ${grpc.java.version}            io.grpc  grpc-api  ${grpc.java.version}            io.grpc  grpc-context  ${grpc.java.version}            io.grpc  grpc-core  ${grpc.java.version}          

这里我们使用的spring-boot版本与grpc-client-spring-boot-starter和grpc-server-spring-boot-starter使用的版本不同,所以后面我们需要在grpc的starter排除掉默认的spring-boot版本。同时grpc的相关一些库都使用统一的版本。

这里可以看到grpc底层使用的是netty实现的消息通讯

 4. 配置application.yml文件

//provider的application.ymlserver:  port: 8081grpc:  server:    port: 9091    security:      enabled: falsespring:  application:    name: cloud-grpc-provider  cloud:    nacos:      discovery: server-addr: 127.0.0.1:8848# actuator managementmanagement:  endpoint:    health:      show-details: always  endpoints:    web:      exposure: include: '*'
//consumer的application.ymlserver:  port: 10020spring:  application:    name: cloud-grpc-comsumber  cloud:    nacos:      discovery: server-addr: 127.0.0.1:8848grpc:  client:    cloud-grpc-provider:      enableKeepAlive: true      keepAliveWithoutCalls: true      negotiationType: PLAINTEXT    GLOBAL:      security: client-auth-enabled: false

以上是provider和consumer的application.yml配置文件。 这里我们使用的同一台机器进行测试,所以要注意不同的provider和consumer应用的server的端口和grpc的端口不要相同。
同时在provider和consumer,将grpc的security的enable开关关掉。consumer端要注意的是设置negotiationType的类型为PLAINTEXT

5. provider和consumer引入相应的包

provider的maven引入:

      org.springframework.boot     spring-boot-starter-web       org.springframework.boot     spring-boot-starter-actuator       org.springframework.boot     spring-boot-starter-test       com.alibaba.cloud     spring-cloud-alibaba-nacos-discovery       net.devh     grpc-server-spring-boot-starter             org.springframework.boot      spring-boot-starter              cn.ckeen     cloud-grpc-lib     1.0-SNAPSHOT     compile     

consumer的maven引入:

       org.springframework.boot     spring-boot-starter-web       org.springframework.boot     spring-boot-starter-actuator       org.springframework.boot     spring-boot-starter-test       com.alibaba.cloud     spring-cloud-alibaba-nacos-discovery       net.devh     grpc-client-spring-boot-starter             org.springframework.boot      spring-boot-starter              cn.ckeen     cloud-grpc-lib     1.0-SNAPSHOT     

两个包都引入了lib包,作为客户端和服务端通讯协议。使用nacos作为注册中心,实现负载均衡。

6. provider的service编写

@GrpcServicepublic class GreeterService extends SimpleGrpc.SimpleImplBase {    private static Logger log = LoggerFactory.getLogger(GreeterService.class);    // 引入该参数是为了做负载均衡验证    @Value("${grpc.server.port}")    private String serverPort;    @Override    public void sayHello(HelloRequest request, StreamObserver responseObserver) { String message = "server port:" + serverPort + ",Hello " + request.getName(); final HelloReply.Builder replyBuilder = HelloReply.newBuilder().setMessage(message); responseObserver.onNext(replyBuilder.build()); responseObserver.onCompleted(); log.info("Returning " +message); responseObserver.onError(Status.INVALID_ARGUMENT.withDescription("测试出错").asException());    }}

首先使用GrpcService注解来标识服务,该服务继承自proto文件生成的grpc的SimpleGrpc.SimpleImplBase,同时实现了sayHello的方法,这里我们通过responseObserver将结果返回。

7. consumer的消费

consumer端比较简单,直接使用@GrpcClient的注解生成一个SimpleGrpc的Stub,然后进行调用即可

@Servicepublic class GreeterService {    @GrpcClient("cloud-grpc-provider")    private SimpleGrpc.SimpleBlockingStub simpleBlockingStub;    public String greet(String name) { try {     HelloReply response = simpleBlockingStub.sayHello(HelloRequest.newBuilder().setName(name).build());     return response.getMessage(); } catch (final StatusRuntimeException e) {     return "FAILED with " + e.getStatus().getCode(); }    }}

最终我们可以写一个controller来调用该服务进行测试,实现代码如下:

    @Resource    private GreeterService greeterService;    @GetMapping("greeter")    public String greet(@RequestParam("name")String name){ String result = greeterService.greet(name); return result;    }

8. 测试验证

先启动两个provider,我们可以在nacos的service list看到两个provider的注册信息:

 启动consumer访问http://localhost:10020/greeter?name=keen可以看到有返回,刷新后端口还有变化

到此我们简单的一个grpc的服务就已经实现了

demo地址: https://github.com/keenw/spring-cloud-grpc-ck

好看字体下载