使用@ GrpcService
自动创建并运行一个 gRPC 服务,内嵌在 spring-boot 应用中
使用@ GrpcClient
自动创建和管理你的channel
和stub
支持 Spring Cloud(向 Consul 或 Eureka 或 Nacos 注册服务并获取gRPC服务信息)
支持 Spring Sleuth 进行链路跟踪(需要单独引入 brave-instrumentation-grpc)
支持对 server、client 分别设置全局拦截器或单个的拦截器
支持 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。
如果使用的是 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' }
如果使用的是 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 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; }
如果使用的是 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 去注册中心上进行获取对应服务的 addresslocalhost
和 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
的话可能会造成冲突。
当前项目目前支持 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