简介

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. java 链表反转_LeetCode206 实现单链表的反转
  2. [恢]hdu 2012
  3. Java 获取远程文件的大小
  4. C++ auto和decltype关键字
  5. 双11电商手机大战盘点,大神荣耀各成势力
  6. Stream将List转换为Map
  7. androidstudio4.1.1 build model卡主_在C++中加载PyTorch1.4的FasterRCNN模型
  8. “公益AI之星”挑战赛-新冠疫情相似句对判定大赛
  9. 信贷违约风险评估模型(上篇):探索性数据分析
  10. 2、Zookeeper集群搭建、命令行Client操作
  11. -[UIKBBlurredKeyView candidateList]:手写输入法APP闪退
  12. python实时语音转写_语音识别 - 实时语音转写 - 《科大讯飞REST_API开发指南》 - 书栈网 · BookStack...
  13. 小票打印机安装配置全过程 58mm热敏票据打印机驱动安装
  14. DTOJ#5208. 蓝buff一吃就起飞
  15. Dynamics CRM 客户端程序开发:常用工具介绍之Dynamics XRM Tools
  16. 页面怎么导出html文件大小,报表HTML导出时自适应页面大小
  17. 判断设备是否是 iphone5
  18. 男人凭什么三十而立——这个第一是我的
  19. Gos Log每次查询响应后自动清理临时文件,优化磁盘空间
  20. 游戏蓝牙耳机哪款好?2021商城最佳人气五款蓝牙耳机推荐

热门文章

  1. Android性能专项测试之Systrace工具
  2. Android Native内存泄露检测(针对Android7.0)
  3. 如何从wireshark 抓包中的RTP导出 H.264 PAYLOAD,变成可用暴风直接播放的H264 裸码流文件
  4. linux文件系统初识
  5. Bookshelf 2 POJ - 3628(01背包||DFS)
  6. sublime安装插件详细教程
  7. 唯一分解定理 详解(C++)
  8. python转义字符_python转义字符
  9. 最新计算机操作员高级试题,计算机操作员高级考试试题
  10. linux增加临时编译bin,Linux Rpmbuild 包制作