gRPC 框架的 Spring Boot 启动器模块 gRPC Spring Boot Starter

MIT
Java
跨平台
2017-02-27
yidongnan

特点

  • 使用@ GrpcService自动创建并运行一个 gRPC 服务,内嵌在 spring-boot 应用中

  • 使用@ GrpcClient自动创建和管理你的channelstub

  • 支持 Spring Cloud(向Consul或Eureka注册服务并获取gRPC服务器信息)

  • 支持 Spring Sleuth 进行链路跟踪

  • 支持对于 server、client 分别设置全局拦截器或单个的拦截器

  • 支持 Spring-Security

  • 支持 metric (micrometer / actuator)

  • 可以使用 grpc-netty-shaded

版本

2.x.x.RELEASE 支持 Spring Boot 2 & Spring Cloud Finchley。

最新的版本:2.2.0.RELEASE

1.x.x.RELEASE 支持 Spring Boot 1 & Spring Cloud Edgware 、Dalston、Camden。

最新的版本:1.4.1.RELEASE

注意: 此项目也可以在没有Spring-Boot的情况下使用,但这需要一些手动bean配置。

使用方式

gRPC server + client

如果使用的是 Maven,添加如下依赖

<dependency>
  <groupId>net.devh</groupId>
  <artifactId>grpc-spring-boot-starter</artifactId>
  <version>2.2.0.RELEASE</version>
</dependency>

如果使用的 Gradle,添加如下依赖

dependencies {
  compile 'net.devh:grpc-spring-boot-starter:2.2.0.RELEASE'
}

gRPC 服务端

如果使用的是 Maven,添加如下依赖

<dependency>
  <groupId>net.devh</groupId>
  <artifactId>grpc-server-spring-boot-starter</artifactId>
  <version>2.2.0.RELEASE</version>
</dependency>

如果使用的 Gradle,添加如下依赖

dependencies {
  compile 'net.devh:grpc-server-spring-boot-starter:2.2.0.RELEASE'
}

实现 gRPC server 的业务逻辑,并使用 @GrpcService 注解

@GrpcService
public class GrpcServerService extends GreeterGrpc.GreeterImplBase {

    @Override
    public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
        HelloReply reply = HelloReply.newBuilder().setMessage("Hello ==> " + req.getName()).build();
        responseObserver.onNext(reply);
        responseObserver.onCompleted();
    }
}

设置 gRPC 的 host 跟 port ,默认的监听的 host 是 0.0.0.0,默认的 port 是 9090。其他配置属性可以参考 settings。所有的配置文件在 server 中使用需增加 grpc.server. 的前缀

Properties示例

grpc.server.port=9090
grpc.server.address=0.0.0.0

Server-Security

支持使用 Spring-Security 加密你的 gRPC 应用。你只需要添加 Spring-Security(core 或者 config)依赖,然后根据需要再增加加密的配置

首先需要选择一个认证方案

  • BasicAuth(基础认证)

    @Bean
    AuthenticationManager authenticationManager() {
        final List<AuthenticationProvider> providers = new ArrayList<>();
        providers.add(...); // Possibly DaoAuthenticationProvider
        return new ProviderManager(providers);
    }
    
    @Bean
    GrpcAuthenticationReader authenticationReader() {
        final List<GrpcAuthenticationReader> readers = new ArrayList<>();
        readers.add(new BasicGrpcAuthenticationReader());
        return new CompositeGrpcAuthenticationReader(readers);
    }
  • Certificate Authentication(证书认证)

    @Bean
    AuthenticationManager authenticationManager() {
        final List<AuthenticationProvider> providers = new ArrayList<>();
        providers.add(new X509CertificateAuthenticationProvider(userDetailsService()));
        return new ProviderManager(providers);
    }
    
    @Bean
    GrpcAuthenticationReader authenticationReader() {
        final List<GrpcAuthenticationReader> readers = new ArrayList<>();
        readers.add(new SSLContextGrpcAuthenticationReader());
        return new CompositeGrpcAuthenticationReader(readers);
    }

    相关的配置属性如下:

    grpc.server.security.enabled=true
    grpc.server.security.certificateChainPath=certificates/server.crt
    grpc.server.security.privateKeyPath=certificates/server.key
    grpc.server.security.trustCertCollectionPath=certificates/trusted-clients-collection
    grpc.server.security.clientAuth=REQUIRE
  • 使用 CompositeGrpcAuthenticationReader 类链式的调用多个认证方案

  • 自定义认证方式(继承并实现 GrpcAuthenticationReader 类)

然后决定如果去保护你的服务

  • 使用 Spring-Security 的注解

    @Configuration
    @EnableGlobalMethodSecurity(proxyTargetClass = true, ...)
    public class SecurityConfiguration {

    如果你想使用 Spring Security 相关的注解的话,proxyTargetClass 属性是必须的! 但是你会受到一条警告,提示 MyServiceImpl#bindService() 方式是用 final 进行修饰的。 这条警告目前无法避免,单他是安全的,可以忽略它。

  • 手动配置

    @Bean
    AccessDecisionManager accessDecisionManager() {
        final List<AccessDecisionVoter<?>> voters = new ArrayList<>();
        voters.add(new AccessPredicateVoter());
        return new UnanimousBased(voters);
    }
    
    @Bean
    GrpcSecurityMetadataSource grpcSecurityMetadataSource() {
        final ManualGrpcSecurityMetadataSource source = new ManualGrpcSecurityMetadataSource();
        source.set(MyServiceGrpc.getSecureMethod(), AccessPredicate.hasRole("ROLE_USER"));
        source.setDefault(AccessPredicate.permitAll());
        return source;
    }

gRPC 客户端

如果使用的是 Maven,添加如下依赖

<dependency>
  <groupId>net.devh</groupId>
  <artifactId>grpc-client-spring-boot-starter</artifactId>
  <version>2.2.0.RELEASE</version>
</dependency>

如果使用的 Gradle,添加如下依赖

dependencies {
  compile 'net.devh:grpc-client-spring-boot-starter:2.2.0.RELEASE'
}

这里有三种方式去或得一个gRPC server的连接

  • 使用 grpcChannelFactory.createChannel(serverName) 去创建一个 Channel,并创建一个自己的 gRPC stub.

    @Autowired
    private GrpcChannelFactory grpcChannelFactory;
    
    private GreeterGrpc.GreeterBlockingStub greeterStub;
    
    @PostConstruct
    public void init() {
        Channel channel = grpcChannelFactory.createChannel("gRPC server name");
        greeterStub = GreeterGrpc.newBlockingStub(channel);
    }
  • 通过在 Channel 类型的字段上加入 @GrpcClient(serverName) 注解,并创建一个自己的 gRPC stub.

    • 不需要使用 @Autowired 或者 @Inject 来进行注入
    @GrpcClient("gRPC server name")
    private Channel channel;
    
    private GreeterGrpc.GreeterBlockingStub greeterStub;
    
    @PostConstruct
    public void init() {
        greeterStub = GreeterGrpc.newBlockingStub(channel);
    }
  • 直接将 @GrpcClient(serverName) 注解加在你自己的 stub 上

    • 不需要使用 @Autowired 或者 @Inject 来进行注入
    @GrpcClient("gRPC server name")
    private GreeterGrpc.GreeterBlockingStub greeterStub;

注意: 你可以为多个 channels 和多个不同的 stubs 使用相同的 serverName (除非他们拦截器不一样).

然后你可以直接向服务端发起请求,如下:

HelloReply response = stub.sayHello(HelloRequest.newBuilder().setName(name).build());

可以单独为每一个 client 配置对应的 address 但在某些情况下,你可以调整默认的配置。 你可以通过 NameResolver.Factorybeans 去自定义默认的 url 映射,如果你没有配置这个 bean,那将会按照下面的方式进行解析:

  • 如果存在一个 DiscoveryClient 的 bean,这时会使用 client name 去注册中心上进行获取对应服务的 address
  • 否则 client 端将使用 localhost 和 9090 端口

其他的配置属性参考 settings,所有的配置文件在 client 端使用时需要增加 grpc.client.(serverName).的前缀

你也可以配置多个目标地址,请求时会自动使用负载均衡

  • static://127.0.0.1:9090,[::1]:9090

你也可以使用服务发现去获取目标地址(要求一个 DiscoveryClient bean)

  • discovery:///my-service-name

此外,你也可以使用 DNS 的方式去获取目标地址

  • dns:///example.com

Properties示例

grpc.client.(gRPC server name).address=static://localhost:9090
# Or
grpc.client.myName.address=static://localhost:9090

客户端认证

客户端认证有很多种不同的方式,但目前仅仅支持其中的一部分,支持列表如下:

  • BasicAuth

    使用 ClientInterceptor (其他认证机制可以以类似的方式实现).

    @Bean
    ClientInterceptor basicAuthInterceptor() {
        return AuthenticatingClientInterceptors.basicAuth(username, password);
    }
    • 为所有的 client 设置相同的认证

      @Bean
      public GlobalClientInterceptorConfigurer basicAuthInterceptorConfigurer() {
          return registry -> registry.addClientInterceptors(basicAuthInterceptor());
      }
    • 每个 client 使用不同的认证

      @GrpcClient(value = "myClient", interceptorNames = "basicAuthInterceptor")
      private MyServiceStub myServiceStub;
  • Certificate Authentication

    需要一些配置属性:

    #grpc.client.test.security.authorityOverride=localhost
    #grpc.client.test.security.trustCertCollectionPath=certificates/trusted-servers-collection
    grpc.client.test.security.clientAuthEnabled=true
    grpc.client.test.security.certificateChainPath=certificates/client.crt
    grpc.client.test.security.privateKeyPath=certificates/client.key

使用 grpc-netty-shaded

该库也支持 grpc-netty-shaded 库

注意: 如果 shaded netty 已经存在于 classpath 中, 那么将优先使用这个库

如果你使用的Maven,你可以使用如下的配置:

<dependency>
    <groupId>io.grpc</groupId>
    <artifactId>grpc-netty-shaded</artifactId>
    <version>${grpcVersion}</version>
</dependency>

<!-- For both -->
<dependency>
    <groupId>net.devh</groupId>
    <artifactId>grpc-spring-boot-starter</artifactId>
    <version>...</version>
    <exclusions>
        <exclusion>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- For the server -->
<dependency>
    <groupId>net.devh</groupId>
    <artifactId>grpc-server-spring-boot-starter</artifactId>
    <version>...</version>
    <exclusions>
        <exclusion>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- For the client -->
<dependency>
    <groupId>net.devh</groupId>
    <artifactId>grpc-client-spring-boot-starter</artifactId>
    <version>...</version>
    <exclusions>
        <exclusion>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty</artifactId>
        </exclusion>
    </exclusions>
</dependency>

如果你使用的 Gradle,你可以使用如下的配置:

compile "io.grpc:grpc-netty-shaded:${grpcVersion}"

compile 'net.devh:grpc-spring-boot-starter:...' exclude group: 'io.grpc', module: 'grpc-netty' // For both
compile 'net.devh:grpc-client-spring-boot-starter:...' exclude group: 'io.grpc', module: 'grpc-netty' // For the client
compile 'net.devh:grpc-server-spring-boot-starter:...' exclude group: 'io.grpc', module: 'grpc-netty' // For the server

示例项目

查看更多的示例项目 here.

 

加载中

评论(0)

暂无评论

gRPC Spring Boot Starter 2.3.0 发布,同步支持链路跟踪

gRPC Spring Boot Starter 项目是一个 gRPC 的 Spring Boot 模块。通过在 Spring Boot 中内嵌一个 gRPC Server 对外提供服务,并支持 Spring Cloud 的服务发现、注册、链路跟踪等等。 在 2....

04/08 09:41

gRPC Spring Boot Starter 2.2.0 发布,包含大量更新

gRPC Spring Boot Starter 项目是一个 gRPC 的 Spring Boot 模块。通过在 Spring Boot 中内嵌一个 gRPC Server 对外提供服务,并支持 Spring Cloud 的服务发现、注册、链路跟踪等等。 在 2....

2018/12/24 10:06

没有更多内容

加载失败,请刷新页面

没有更多内容

1
回答
【一周热点】Have a Merry Christmas or other holiday of your choice

回顾一周社区热门资讯与你的精彩留言~ 第【八】期:1222-1228 图片来自 itsfoss 站内需知 码云 Gitee 年度数据报告,总项目 500 ...

2018/12/28 16:48

没有更多内容

加载失败,请刷新页面

没有更多内容

springboot整合gprc 传输对象

一,grpc简介: GRPC是google开源的一个高性能、跨语言的RPC框架,基于HTTP2协议,基于protobuf 3.x,基于Netty 4.x +。GRPC与thrift、avro-rpc等其实在总体原理上并没有太大的区别,简而言之...

2018/04/26 10:27
329
1
gRPC基本使用(一)--java与go之间的相互调用

gRPC是一个高性能、开源、通用的RPC框架,面向移动和HTTP/2设计。gRPC 默认使用 protocol buffers,这是 Google 开源的一套成熟的结构数据序列化机制。 Protocol Buffers 是一种轻便高效的结...

2018/11/24 17:35
337
0
gRPC 小记

创建一个maven项目demo-grpc 包含三个子模块: grpc-common:公共模块定义proto及生成java代码; grpc-server:grpc 服务端; grpc-client:grpc客户端。 其中grpc-server、grpc-client 为s...

2018/09/04 11:48
74
0
从0.5到1写个rpc框架 - 2:远程服务调用(grpc)

这不是教程,只是个人总结,有兴趣的童鞋可以搭配源码看看:acuprpc gRPC是Google开源的跨语言远程服务调用(RPC)框架,通信协议用的HTTP/2,数据传输默认用的protocol buffers(一种轻便高效...

2018/11/30 15:23
13
0
从0.5到1写个rpc框架 - 0

最近在新公司开始接触微服务,在此之前并没有微服务的开发经验。对比了spring cloud和公司的rpc框架,对微服务这套东西终于有了一点粗浅的认知,为了加深理解,自己动手写个rpc框架玩玩。顺便...

2018/11/29 23:16
10
0
RPC框架实践之:Google gRPC

My Desktop 概述 gRPC是Google开源的通用高性能RPC框架,它支持的是使用Protocol Buffers来编写Service定义,支持较多语言扩平台并且拥有强大的二进制序列化工具集。与文章《RPC框架实践之:...

2018/05/21 05:51
2.8K
4
如何实现一个优质的微服务框架:Apache ServiceComb 的开放性设计

一个优质的微服务框架需要考虑的要素众多,在满足微服务设计理念的前提下,也是一个不断实践优化的过程。 本文讲述了整个 开源微服务框架 Apache ServiceComb 设计形成的前因后果,尝试从理念...

Grpc介绍 — Go-Service To PHP-Client

笔者现在公司项目大部分是PHP进行开发,要完成整体微服务化必须要考虑PHP使用上的可行性,Grpc也是支持PHP作为client端发起Grpc请求,但是依赖的扩展等都相对复杂(毕竟不是亲儿子),那么本...

03/06 11:58
38
0

没有更多内容

加载失败,请刷新页面

返回顶部
顶部