简介

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 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 {@Overridepublic 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 DaoAuthenticationProviderreturn 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.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
# 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

示例项目

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

更多精彩内容可以关注“IT实战联盟”公号哦~~~

微服务架构学习笔记(一):gRPC Spring Boot Starter 2.2.0 发布,及使用步骤相关推荐

  1. SpringCloud微服务架构学习(二)常见的微服务架构

    SpringCloud微服务架构学习(二)常见的微服务架构 1.Dubbo 阿里开源微服务框架 官网地址:http://dubbo.apache.org/en-us/ 简介: Dubbo是阿里巴巴SO ...

  2. kratos mysql_kratos微服务框架学习笔记一(kratos-demo)

    本文将为您描述kratos微服务框架学习笔记一(kratos-demo),教程操作步骤: 目录 kratos微服务框架学习笔记一(kratos-demo) kratos本体 demo kratos微服 ...

  3. 基于Spring Boot和Spring Cloud实现微服务架构学习--转

    原文地址:http://blog.csdn.net/enweitech/article/details/52582918 看了几周spring相关框架的书籍和官方demo,是时候开始总结下这中间的学习 ...

  4. 基于Spring Boot和Spring Cloud实现微服务架构学习

    目录 Spring 顶级框架 Spring cloud子项目 WHAT - 什么是微服务 微服务简介 微服务的具体特征 SOA vs Microservice HOW - 怎么具体实践微服务 客户端如 ...

  5. SpringCloud微服务架构学习

    SpringCloud 1. 微服务架构理论入门 1.1. 微服务架构概述 微服务架构是一种架构模式,它提倡将单一应用程序划分为一组小的服务,服务之间互相协调,互相配合,为用户提供最终价值.每个服务运 ...

  6. 微服务架构工作笔记001---认识Service Mesh

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 Service Mesh作为下一代微服务技术的代名词,初出茅庐却深得人心一鸣惊人,大有一统微服务时 ...

  7. 《从0开始学微服务》模块一:入门微服务的学习笔记

    03丨初探微服务架构 gt3:微服务架构的模块图和一次正常的服务调用的流程 1.服务提供者按照一定格式的服务描述,向注册中心注册服务,声明自己能够提供哪些服务以及服务的地址是什么,完成服务发布 2.来 ...

  8. 微服务架构学习与思考(05):微服务架构适用场景分析

    一.简述 在实际开发中,需要考虑多种因素,来决定采取哪种架构模式才适合当前业务发展情况. 毕竟微服务也不能"包治百病",不要把它当做万能药.企业研发哪里得病了,觉得只要把" ...

  9. Spring Boot基础学习笔记18:Spring Boot整合Redis缓存实现

    文章目录 零.学习目标 一.Spring Boot支持的缓存组件 二.基于注解的Redis缓存实现 (一)安装与启动Redis (二)创建Spring Boot项目 - RedisCacheDemo0 ...

  10. 微服务架构学习 之 什么是微服务

    很长一段时间了,迷恋于Spring技术应用,执迷和执着促使我坚持不懈地带领着公司研发团队,在这条技术道路上摸爬滚打着前行,即使我心中明白,我们是一个非纯粹的IT企业,但IT新颖技术的诱惑,让我们不断紧 ...

最新文章

  1. 南华大学c语言多少分才能过_成人高考难吗?多少分可以过?
  2. python代码实现二叉树的镜像树
  3. nginx 访问控制之 认证
  4. python模块介绍-locustio:性能测试工具locustio
  5. BZOJ1858 [Scoi2010]序列操作 线段树
  6. 【机器学习算法-python实现】采样算法的简单实现
  7. python画图模块_学习python画图模块plotnine:第一步安装
  8. 清华博士回应:我为什么逃离科研,去中学当老师?
  9. 力扣1317.将整数转换为两个无零整数之和
  10. 分治之快速排序以及快速排序为何最快
  11. java撤销上一步_CAD快速入门技巧:CAD软件中撤销操作的方法汇总
  12. 任何一台计算机都可以安装win 7系统,最全面win7系统如何安装
  13. 很多人都爱玩的lol..
  14. 计算机组成原理—地址码
  15. [转]常见的软件版本编号及命名
  16. qmap按插入顺序排序_C++语言排序算法之插入排序
  17. 数据库索引原理及优化
  18. 推荐子龙山人的emacs视频教程
  19. 零雨其蒙:Practicing Test-Driven Development by Example Using Delphi
  20. 各系统查询IP地址和MAC地址的脚本或命令

热门文章

  1. 3796.凑平方-AcWing题库
  2. c++派生类构造顺序
  3. 基于sklearn 的one hot encoding
  4. python random 生成随机数
  5. hive partition 分区详解一
  6. C++小游戏——24点
  7. 题目477- A+B Problem III (陷阱题)
  8. 不提交怎么获取input中的值并存储_快速读懂innodb存储引擎
  9. 用PPT直接修改主集成模板,并保存为pps格式,即可现场展示应用.
  10. 排行榜或颁奖界面有时出现名字等项目上下错位,为什么?