当前位置: 首页 > 软件库 > 程序开发 > 微服务框架 >

gRPC Spring Boot Starter

gRPC 框架的 Spring Boot 启动器模块
授权协议 MIT
开发语言 Java
所属分类 程序开发、 微服务框架
软件类型 开源软件
地区 国产
投 递 者 羊光辉
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

gRPC 框架的 Spring Boot 启动器模块

项目主页:grpc-spring-boot-starter

特点

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

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

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

  • 支持 Spring Sleuth 进行链路跟踪(需要单独引入 brave-instrumentation-grpc)

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

  • 支持 Spring-Security

  • 支持 metric (micrometer / actuator)

  • 可以使用 (non-shaded) grpc-netty

版本

2.x.x.RELEASE 支持 Spring Boot 2.1+ & Spring Cloud Greenwich。

最新的版本:2.5.0.RELEASE

(使用 2.4.0.RELEASE 版本可以支持 Spring Boot 2.0.X & Spring Cloud Finchley).

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

最新的版本:1.4.2.RELEASE

注意: 此项目也可以在没有 Spring-Boot 的场景下使用,但需要手动的配置相关的 bean。

使用方式

gRPC server + client

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

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

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

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

gRPC 服务端

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

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

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

dependencies {
  compile 'net.devh:grpc-server-spring-boot-starter:2.5.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 ,默认的监听的 port 是 9090。其他配置属性可以参考 settings。 所有的配置属性在 server 中使用需增加 grpc.server. 的前缀

服务端配置属性示例

grpc.server.port=9090
grpc.server.address=0.0.0.0
#grpc.server.inProcessName=test

对 Server 进行自定义

当前项目同样支持对 ServerBuilder 的自定义修改,需要在创建的过程中使用 GrpcServerConfigurer beans。

@Bean
public GrpcServerConfigurer keepAliveServerConfigurer() {
  return serverBuilder -> {
    if (serverBuilder instanceof NettyServerBuilder) {
      ((NettyServerBuilder) serverBuilder)
          .keepAliveTime(30, TimeUnit.SECONDS)
          .keepAliveTimeout(5, TimeUnit.SECONDS)
          .permitKeepAliveWithoutCalls(true);
    }
  };
}

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);
    }
  • Bearer Authentication (OAuth2/OpenID-Connect)

    @Bean
    AuthenticationManager authenticationManager() {
        final List<AuthenticationProvider> providers = new ArrayList<>();
        providers.add(...); // Possibly JwtAuthenticationProvider
        return new ProviderManager(providers);
    }
    
    @Bean
    GrpcAuthenticationReader authenticationReader() {
        final List<GrpcAuthenticationReader> readers = new ArrayList<>();
        readers.add(new BearerAuthenticationReader(accessToken -> new BearerTokenAuthenticationToken(accessToken)));
        return new CompositeGrpcAuthenticationReader(readers);
    }

    你可能还想定义自己的 GrantedAuthoritiesConverter ,将权限和角色的信息映射到 Spring Security 的 GrantedAuthority 中

  • 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.certificateChain=file:certificates/server.crt
    grpc.server.security.privateKey=file:certificates/server.key
    grpc.server.security.trustCertCollection=file: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.5.0.RELEASE</version>
</dependency>

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

dependencies {
  compile 'net.devh:grpc-client-spring-boot-starter:2.5.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.Factory beans 去自定义默认的 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

同时,你也可以使用如下方式直接进程内访问

  • in-process:test

它会通过DNS将域名解析出所有真实的 IP 地址,通过使用这些真实的IP地址去做负载均衡。 需要注意的是 grpc-java 出于性能的考虑对 DNS 返回的结果做缓存。 有关这些和其他原生支持的 NameResolverProviders 参考官方文档 grpc-java sources

客户端配置属性示例

grpc.client.GLOBAL.enableKeepAlive=true

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

GLOBAL 是一个特殊的常量,它可以用于对所有 Client 统一的设置属性。 属性覆盖的顺序:Client单独的属性 > GLOBAL的属性 > 默认的属性

自定义 Client

This library also supports custom changes to the ManagedChannelBuilder and gRPC client stubs during creation by creating GrpcChannelConfigurer and StubTransformer beans. 当前项目支持对 ManagedChannelBuilder 的自定义,在 gRPC client stub创建的过程中,通过使用 GrpcChannelConfigurer 或 StubTransformer bean 来完成自定义操作

@Bean
public GrpcChannelConfigurer keepAliveClientConfigurer() {
  return (channelBuilder, name) -> {
    if (channelBuilder instanceof NettyChannelBuilder) {
      ((NettyChannelBuilder) channelBuilder)
          .keepAliveTime(15, TimeUnit.SECONDS)
          .keepAliveTimeout(5, TimeUnit.SECONDS);
    }
  };
}

@Bean
public StubTransformer authenticationStubTransformer() {
  return (clientName, stub) -> stub.withCallCredentials(grpcCredentials(clientName));
}

客户端认证

注意: 以下列出的一些方法仅仅适用于通过注入得到的 stubs,如果你通过注入 Channel,手动的在去创建 stubs,这就需要你自己手动的 去配置凭证。然而你同样能从目前所提供的一些辅助类方法中收益。

客户端有许多不同的认证方式,我们只需定义一个类型为 CallCredentials 的 bean,它会自动作用于身份验证。目前通过一些辅助方法可以支持 下列的认证方式:

  • BasicAuth

    @Bean
    CallCredentials grpcCredentials() {
      return CallCredentialsHelper.basicAuth(username, password);
    }
  • Bearer Authentication (OAuth2, OpenID-Connect)

    @Bean
    CallCredentials grpcCredentials() {
      return CallCredentialsHelper.bearerAuth(token);
    }
  • Certificate Authentication

    需要一些配置属性:

    #grpc.client.test.security.authorityOverride=localhost
    #grpc.client.test.security.trustCertCollection=file:certificates/trusted-servers-collection
    grpc.client.test.security.clientAuthEnabled=true
    grpc.client.test.security.certificateChain=file:certificates/client.crt
    grpc.client.test.security.privateKey=file:certificates/client.key
  • 为每个 client 使用不同的认证

    通过定义一个 StubTransformer bean 来代替原有的 CallCredentials bean

    @Bean
    StubTransformer grpcCredentialsStubTransformer() {
      return CallCredentialsHelper.mappedCredentialsStubTransformer(
          Map.of(
              clientA, callCredentialsAC,
              clientB, callCredentialsB,
              clientC, callCredentialsAC));
    }

    注意: 如果你配置了 CallCredentials bean,然后再使用 StubTransformer 的话可能会造成冲突。

使用 (non-shaded)grpc-netty

当前项目目前支持 grpc-netty 和 grpc-netty-shaded。 使用 grpc-netty-shaded 可以防止 grpc 跟 netty 版本的兼容性问题。

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

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

<dependency>
    <groupId>io.grpc</groupId>
    <artifactId>grpc-netty</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-shaded</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- For the server (only) -->
<dependency>
    <groupId>net.devh</groupId>
    <artifactId>grpc-server-spring-boot-starter</artifactId>
    <version>...</version>
    <exclusions>
        <exclusion>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- For the client (only) -->
<dependency>
    <groupId>net.devh</groupId>
    <artifactId>grpc-client-spring-boot-starter</artifactId>
    <version>...</version>
    <exclusions>
        <exclusion>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
        </exclusion>
    </exclusions>
</dependency>

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

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

compile 'net.devh:grpc-spring-boot-starter:...' exclude group: 'io.grpc', module: 'grpc-netty-shaded' // For both
compile 'net.devh:grpc-client-spring-boot-starter:...' exclude group: 'io.grpc', module: 'grpc-netty-shaded' // For the client (only)
compile 'net.devh:grpc-server-spring-boot-starter:...' exclude group: 'io.grpc', module: 'grpc-netty-shaded' // For the server (only)
  • Spring boot+grpc demo Grpc服务端 Maven支持: <parent>     <groupId>net.devh</groupId>     <artifactId>grpc-server-spring-boot-starter</artifactId>     <version>1.2.0.RELEASE</version>     <relativePath>./</

  • 简介 gRPC Spring Boot Starter 项目是一个 gRPC 的 Spring Boot 模块。通过在 Spring Boot 中内嵌一个 gRPC Server 对外提供服务,并支持 Spring Cloud 的服务发现、注册、链路跟踪等等。 更新内容 在 2.2.0.RELEASE 版本中包含了以下重大更新 支持 Java 11 支持使用 Spring Security 进行认

  • gRPC Spring Boot Starter 2.4.0 正式发布 新增特性: 1. 支持有序的拦截器 2. 服务之间通信同时支持进程间通信和进程内通信 3. TLS 模式中增加 ciphers 和 protocols 属性的支持 4. 支持关闭进程间的通信 5. 服务发现支持 Spring Cloud Alibaba Nacos 更多信息访问 GitHub 地址: https://githu

  • spring-boot-starter-grpc 的实现原理 https://www.jianshu.com/p/260a1ac847b6?utm_source=oschina-app   源码: https://github.com/ChinaSilence/spring-boot-starter-grpc 说明: https://github.com/ChinaSilence/spring-b

 相关资料
  • 我正在学习《行动中的Spring》第四版第5章,但是我被第一个例子困住了。 以下是我的Eclipse Luna项目结构: 如果我将此项目作为Spring Boot应用程序运行,则会引发异常: 我怎样才能解决这个问题? 所有文件的内容: 随地吐痰。爪哇: SpittrWebAppInitializer.java: 网络配置。爪哇: RootConfig。爪哇: HomeController.java

  • 随着互联网的飞速发展,前端开发越来越复杂,导致开发经常出现两个问题: 恼人的命名冲突 烦琐的文件依赖 针对这两个问题,可以使用js模块化技术来解决。当前主流的js模块化有两大规范CMD(Seajs)和AMD规范(RequireJS)。WeX5采用RequireJS(AMD规范)来实现,关于RequireJS的详细说明参考:http://www.requirejs.org/ 接下来我们介绍在WeX5

  • 本文向大家介绍SpringBoot多模块项目框架搭建过程解析,包括了SpringBoot多模块项目框架搭建过程解析的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了SpringBoot多模块项目框架搭建过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 创建根项目,New Project 创建一个名为 sms-bomber 的 Sp

  • 本文向大家介绍说明模块化自动化框架。,包括了说明模块化自动化框架。的使用技巧和注意事项,需要的朋友参考一下 在模块化自动化框架中,通过将整个应用程序划分为几个小的自给自足的模块,在模块或集群的基础上开发测试脚本。因此,创建了属于特定模块或集群的各个测试脚本。 属于这些隔离模块的这些脚本可以集成,并且可以由主驱动程序脚本驱动,以在模块之间执行集成测试。所有这些都是在开发模块脚本时使用的通用功能库(包

  • 本文向大家介绍Springboot中集成Swagger2框架的方法,包括了Springboot中集成Swagger2框架的方法的使用技巧和注意事项,需要的朋友参考一下 摘要:在项目开发中,往往期望做到前后端分离,也就是后端开发人员往往需要输出大量的服务接口,接口的提供方无论是是Java还是PHP等语言,往往会要花费一定的精力去写接口文档,比如A接口的地址、需要传递参数情况、返回值的JSON数据格式

  • 我正在使用Play框架1.2.5和Hibernate3.25来开发我的Web应用程序。我遇到应用程序启动问题,速度很慢:( 对于任何JavaEE servlet驱动的应用程序,我们使用来初始化会话工厂(这确实是一项耗时的工作),一旦部署了应用程序,会话工厂就会被初始化,并且所有这一切都必须在应用程序准备好为最终用户使用之前完成。这样,当用户触发第一个请求时,第一个请求的响应时间更快。 但是,对于P

  • 中的任何提示都非常感谢,谢谢。

  • easySwoole 项目依赖于 Swoole 扩展,在使用 easySwoole 之前需要先安装 swoole 扩展。 快速安装 命令行快速安装: bash <(curl https://www.easyswoole.com/installer.sh) 或是: curl https://www.easyswoole.com/installer.php | php 手动安装 从 easyswool