Dubbo+Grpc+Spring Boot初体验

2020-11-11 599 0

前言

前段时间团队开始采用了grpc作为内部服务通讯技术,部份服务已按照grpc实现也陆续上线了,在实际使用过程中,发现grpc在java应用方面,很多地方还是可以优化的,比如:

  1. grpc 接口出入参实体与java pojo的数据转化和共用性方面
  2. grpc 基于spring boot 的集成方案启动框架,目前还没有官方版本,项目使用第三方net.devh下的grpc-server-spring-boot-starter框架(后续,也准备打造自己springboot-starter)

对比之下,dubbo体系,这一块做得比较完善,所以自己抽空研究了下dubbo,发现dubbo也是可以支持grpc协议,所以捣鼓了下Grpc+Dubbo+Spring Boot的整合

阅读本文建议先了解dubbo框架
http://dubbo.apache.org/zh/docs/v2.7/user/preface/architecture/

参考文章: Dubbo在跨语言和协议穿透性方向的探索:支持 HTTP/2 gRPC
https://mp.weixin.qq.com/s?__biz=MzU4NzU0MDIzOQ==&mid=2247488245&idx=2&sn=b59960420b4e7ae65bb813d4215601a2&chksm=fdeb2095ca9ca983a8da5379b29191c7cba256aaf287966d419d25a9606187805249c8988d63&scene=27#wechat_redirect

项目结构说明

├── dubbo-grpc-api(接口工程,供消费端和服务端引用)
│   ├── build(编译后grpc的接口文件)
│   ├── pom.xml(利用Protobuf Compiler工具,生成代码)
│   └── src
│       └── main
│           ├── java
│           ├── proto
│           │   └── helloworld.proto(IDL描述文件)
├── dubbo-grpc-consumer(消费端)
│   ├── pom.xml
│   └── src
├── dubbo-grpc-provider(服务端)
│   ├── pom.xml
│   └── src
└── pom.xml

项目代码
https://gitee.com/hushow/learning-demo/tree/master/grpc-dubbo-example/spring-cloud-dubbo-grpc-demo

1. 依赖版本

  • spring-boot 2.2.6.RELEASE
  • dubbo.version 2.7.7
  • dubbo-compiler 0.0.1
  • dubbo-spring-boot-starter 2.7.7
  • grpc 1.30.0
  • protobuf-java-util 3.12.0
  • protoc 3.12.0

2. 准备zookeeper实例

服务提供端和和消费端都要依赖注册中心,本例使用zookeeper做为服务注册中心

file

docker方式启动zookeeper

docker run --publish 2181:2181 --name zoo  zookeeper:latest

3. dubbo-grpc-api

将IDL文件独立出来,做成共享api工程,既单一原则又避免了每个工程都依赖IDL编译细节

3.1 定义IDL

syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.hushow.demo.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

3.2 使用dubbo定制的Maven Protobuf Compiler 插件

与grpc原生配置不同之处为Dubbo团队扩展了 Protobuf 的 Compiler 工具,以用来生成 Dubbo 特有的 RPC stub

grpc原生Protobuf Compiler配置参考文章
http://www.hushowly.com/articles/1565

<plugin>
    <groupId>org.xolstice.maven.plugins</groupId>
    <artifactId>protobuf-maven-plugin</artifactId>
    <version>0.6.1</version>
    <configuration>
        <protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
        <pluginId>grpc-java</pluginId>
        <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
        <outputDirectory>build/generated/source/proto/main/java</outputDirectory>
        <clearOutputDirectory>false</clearOutputDirectory>
        <protocPlugins>
            <protocPlugin>
                <id>dubbo-grpc</id>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-compiler</artifactId>
                <version>${dubbo.compiler.version}</version>
                <mainClass>org.apache.dubbo.gen.grpc.DubboGrpcGenerator</mainClass>
            </protocPlugin>
        </protocPlugins>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
                <goal>compile-custom</goal>
                <goal>test-compile</goal>
                <goal>test-compile-custom</goal>
            </goals>
        </execution>
    </executions>
</plugin>

3.3 编译打包

dubbo-grpc-api$ mvn clean install

4. dubbo-grpc-provider

4.1 引用以上api接口

<dependency>
    <groupId>com.hushow.demo</groupId>
    <artifactId>dubbo-grpc-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

4.2 实现业务逻辑

此处使用注解暴露的服务,dubbo也支持xml配置暴露方式

@DubboService
public class GrpcGreeterImpl extends DubboGreeterGrpc.GreeterImplBase  implements  DubboGreeterGrpc.IGreeter{

    public GrpcGreeterImpl() {
        System.out.println("GrpcGreeterImpl.GrpcGreeterImpl");
    }

    @Override
    public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {

        System.out.println("Executing thread is " + Thread.currentThread().getName());
        HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + request.getName()).build();
        responseObserver.onNext(reply);
        responseObserver.onCompleted();
    }

}

注细节:
1.必须继承DubboGreeterGrpc.GreeterImplBase
2.声明DubboService注解,对外暴露Dubbo服务
3.如果使用注解暴露服务,还需要实现DubboGreeterGrpc.IGreeter接口,否则会报ClassNotFoundMethods异常,本人已踩坑过程

4.3 dubbo配置信息

dubbo:
  #指定grpc协议
  protocol:
    id: grpc
    name: grpc
  #指定注册中心
  registry:
    address: zookeeper://127.0.0.1:2181
    #address: nacos://127.0.0.1:8848
  #服务名称
  application:
    id: dubbo-grpc-provider-web
    name: dubbo-grpc-provider-web

4.4 spring boot 启动

@EnableAutoConfiguration
@EnableDubbo(scanBasePackages="com.hushow.demo.helloworld.service.impl")
public class ProviderApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(ProviderApplication.class).run(args);
    }
}

注细节:

  1. 使用EnableDubbo启用dubbo,并指定暴露服务包范围

5. dubbo-grpc-consumer

5.1 引用以上api接口

<dependency>
    <groupId>com.hushow.demo</groupId>
    <artifactId>dubbo-grpc-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

5.2 编写消费测试Controller

@RestController
@Slf4j
@RequestMapping("grpc")
public class RpcProxyController {

    @DubboReference
    private DubboGreeterGrpc.IGreeter greeter;

    @RequestMapping("/hello")
    public String hello(@RequestParam("name") String name){

        log.info("yyyyy hRpcProxyController.hello:{}", name);

        HelloRequest request = HelloRequest.newBuilder().setName(name).build();
        HelloReply response =  greeter.sayHello(request);
        return response.getMessage();
    }
}

注意细节

  1. 通过DubboReference注解声明为服务的订阅者,且要注入的是DubboGreeterGrpc.IGreeter接口

5.3 dubbo配置信息

spring:
  application:
    name: dubbo-grpc-consumer-web
  #bean可覆盖模式,否则启动会报错
  main:
    allow-bean-definition-overriding: true
server:
  port: 8085
dubbo:
  #注册中心
  registry:
    address: zookeeper://127.0.0.1:2181
    #address: nacos://127.0.0.1:8848
  #指定dubbo协议
  protocol:
    id: grpc
    name: grpc
  #服务名
  application:
    id: dubbo-grpc-consumer-web
    name: dubbo-grpc-consumer-web

5.4 消费端启动

@EnableAutoConfiguration
@ComponentScan("com.hushow.demo")
@EnableDubbo
public class ConsumerApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(ConsumerApplication.class).run(args);
    }

5.5 测用效果

file

相关文章

快速实现通用的办公文档在线预览方案
Spring Feign大文件上传踩坑记
MinIO分布式存储方案预研
vagrant+virtualBox快速部署集群节点
Spring Boot下grpc最佳实践
Mysql Bit类型多状态位在Java中的妙用

发布评论