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

程序名称:gRPC Spring Boot Starter

授权协议: MIT

操作系统: 跨平台

开发语言: Java

gRPC Spring Boot Starter 介绍


gRPC 框架的 Spring Boot 启动器模块

特点

版本

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

当前项目同样支持对 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);
    }
  };
}

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

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

  • BasicAuth(基础认证)

    @Bean
    AuthenticationManager authenticationManager() {
    final Listproviders = new ArrayList<>();
    providers.add(…); // Possibly DaoAuthenticationProvider
    return new ProviderManager(providers);
    }

    @Bean
    GrpcAuthenticationReader authenticationReader() {
    final Listreaders = new ArrayList<>();
    readers.add(new BasicGrpcAuthenticationReader());
    return new CompositeGrpcAuthenticationReader(readers);
    }

  • Bearer Authentication (OAuth2/OpenID-Connect)

    @Bean
    AuthenticationManager authenticationManager() {
    final Listproviders = new ArrayList<>();
    providers.add(…); // Possibly JwtAuthenticationProvider
    return new ProviderManager(providers);
    }

    @Bean
    GrpcAuthenticationReader authenticationReader() {
    final Listreaders = new ArrayList<>();
    readers.add(new BearerAuthenticationReader(accessToken -> new BearerTokenAuthenticationToken(accessToken)));
    return new CompositeGrpcAuthenticationReader(readers);
    }

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

  • Certificate Authentication(证书认证)

    @Bean
    AuthenticationManager authenticationManager() {
    final Listproviders = new ArrayList<>();
    providers.add(new X509CertificateAuthenticationProvider(userDetailsService()));
    return new ProviderManager(providers);
    }

    @Bean
    GrpcAuthenticationReader authenticationReader() {
    final Listreaders = 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.

    @GrpcClient(“gRPC server name”)
    private Channel channel;

    private GreeterGrpc.GreeterBlockingStub greeterStub;

    @PostConstruct
    public void init() {
    greeterStub = GreeterGrpc.newBlockingStub(channel);
    }

    • 不需要使用 @Autowired 或者 @Inject 来进行注入

  • 直接将 @GrpcClient(serverName) 注解加在调用客户端的 stub 上

    @GrpcClient(“gRPC server name”)
    private GreeterGrpc.GreeterBlockingStub greeterStub;

    • 不需要使用 @Autowired 或者 @Inject 来进行注入

注意: 你可以为多个 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的属性 >
默认的属性

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)

gRPC Spring Boot Starter 官网

https://github.com/yidongnan/grpc-spring-boot-starter

相关编程语言

BlazeDS 是一个基于服务器的Java 远程控制(remoting...
OVal 是一个可扩展的Java对象数据验证框架,验证的规...
Volta 是一套开发工具,专为开发分布式、实时系统应...
OpenDDS 是一个开源的 C++ 实现的 对象管理组织 OMG...
JADE (Java Agent DEvelopment Framework) 是一个完...
FastMM ,在D2006和2007中已代替了原来的内存管理器。