微服务架构学习笔记:gRPC Spring Boot Starter 2.2.0 发布,及使用步骤

脱发程序员 2018-12-24 16:43:10 ⋅ 894 阅读

简介

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

更新内容

在 2.2.0.RELEASE 版本中包含了以下重大更新

  • 支持 Java 11

  • 支持使用 Spring Security 进行认证授权

  • 支持自定义的编解码

  • 支持自动收集并上报 metric 信息

  • /info 展示当前绑定的端口和对应的 gRPC service

  • 支持 shaded net

  • 支持更多的 NameResolver

gRPC使用

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

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

  • 支持 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.RELEASE1.x.x.RELEASE 支持 Spring Boot 1 & Spring Cloud EdgwareDalstonCamden。 最新的版本: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); }
@BeanGrpcAuthenticationReader 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); }
@BeanGrpcAuthenticationReader 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); }
@BeanGrpcSecurityMetadataSource 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.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

Properties示例
grpc.client.(gRPC server name).address=static:
//localhost:9090
# Orgrpc.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

示例项目

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

---------------END----------------

后续的内容同样精彩

长按关注“IT实战联盟”哦




全部评论: 0

    我有话说:

    服务架构实战篇(六):Spring boot2.x 集成阿里大鱼短信接口详解与Demo

    Spring boot2.x 集成阿里大鱼短信接口,发送短信验证码短信接口详解。

    码云推荐:一个优秀的分布式spring boot/Spring Cloud API限流框架,特别适合服务架构

    一个优秀的分布式spring boot/Spring Cloud API限流框架,特别适合服务架构.

    Spring Boot 2.4.0-RC1, 2.1.18, 2.2.11 和 2.3.5 发布

    Spring Boot 多个分支发布了新版本,分别是 2.4.0-RC1, 2.1.18, 2.2.11 和 2.3.5。 Spring Boot 2.4.0-RC1 此版本是 

    服务架构学习笔记(一):重新认识服务

    服务(Microservice)是服务化思路的一种最佳实践方向,遵循SOA的思路,各个企业在服务化治理的道路上走的时间长了,踩的坑多了,整个软件交付链路上各个环节的基础设施逐渐成熟了,服务

    Spring Boot 2.1.0新特性 ,准备好了吗?!

    Spring Boot官方在10月30号正式发布了v2.1.0.RELEASE版本,由于本人最近比较忙,直到今天才着重抽空学习和了解这次升级一共带来了9大新特性,根据官方描述,正在逐渐支持 java

    服务架构实战篇:快速入手SpringBoot 2.0,欢迎入坑哦~~~

    SpringBoot 2.0 基本要求Java最低要求8以上,不再支持Java 6 和 7等低版本。

    架构实战篇(十六):Spring Boot Assembly服务化打包

    使用assembly来打包springboot服务项目,让发布更简单

    架构实战篇(六):Spring Boot RestTemplate的使用

    RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。

    架构实战篇(十七):Spring Boot Assembly 整合 thymeleaf

    如何让服务器上的 sprig boot 项目升级变的方便快捷

    SpringBoot2.0填坑(一):使用CROS解决跨域并解决swagger 访问不了问题

    公司后台是采用SpringBoot2.0 搭建的服务架构,前端框架用的是vue 使用前后端分离的开发方式,在开发联调的时候需要进行跨域访问,那么使用CROS解决了跨域问题,但是swagger 却用

    架构实战篇(三)-Spring Boot架构搭建RESTful API案例

    之前分享了Spring Boot 整合Swagger 让API可视化和前后端分离架构 受到了大家一致好评 ,本节就接着上节的代码做了详细的查询代码的补充和完善并搭建RESTful API架构案例。

    【开源资讯】Spring Data 2020.0 RC2 发布

    Spring Data 2020.0 RC2 发布了。Spring Data 项目的目的是简化构建基于 Spring 框架应用的数据访问计数,包括非关系数据库、Map-Reduce 框架

    【开源资讯】JWCloud 专业版 v1.0.0 发布,基于 SpringCloud 研发的服务框架

    简介 JavaWeb_Cloud 服务平台是一款基于 SpringCloud 框架研发的分布式微服务框架,主要使用技术栈包括: SpringCloud、Vue、ElementUI

    MateCloud 3.2.8 版本发布,基于 Spring Cloud Alibaba 的服务平台

    软件简介 MateCloud 是一款基于Spring Cloud Alibaba的服务架构。目前已经整合 Spring Cloud Gateway、Spring Security

    Spring Boot 缓存之内嵌H2数据库

    本文手把手教你 怎么用 H2 数据库当做缓存来使用增强系统性能

    架构实战篇(十五):Spring Boot 解耦之事件驱动

    通过使用spring 事件来解决业务代码的耦合

    架构实战篇(七):Spring Boot Data JPA 快速入门

    Spring Data JPA 是Spring Data 的一个子项目,它通过提供基于JPA的Repository极大了减少了操作JPA的代码。

    【开源资讯】Spring Boot 2.4.0.M4 发布

    Spring Boot 2.4.0 的第四个里程碑版本发布了,可以从里程碑仓库获取。此版本包含 145 项更新内容,亮点如下:1、改进故障分析器(Failure Analyzer