微服务架构学习笔记(⼀):gRPCSpringBootStarter2.2.0发布,及使⽤步骤简介
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.2.0.RELEASE
最新的版本: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 = wBuilder().setMessage("Hello ==> " + Name()).build();
}
}
设置 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(基础认证)
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);
}
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.abled=true
grpc.ificateChainPath=
grpc.server.security.privateKeyPath=certificates/server.key
grpc.ustCertCollectionPath=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 进⾏修饰的。这条警告⽬前⽆法避免,单他是安全的,可以忽略它。
⼿动配置
voters.add(new AccessPredicateVoter());
return new UnanimousBased(voters);
}
@Bean
GrpcSecurityMetadataSource grpcSecurityMetadataSource() {
final ManualGrpcSecurityMetadataSource source = new ManualGrpcSecurityMetadataSource();
source.SecureMethod(), 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>
springboot架构图
如果使⽤的 Gradle,添加如下依赖
dependencies {
compile 'net.devh:grpc-client-spring-boot-starter:2.2.0.RELEASE'
}
这⾥有三种⽅式去或得⼀个gRPC server的连接
使⽤ ateChannel(serverName) 去创建⼀个 Channel,并创建⼀个⾃⼰的 gRPC stub.
@Autowired
private GrpcChannelFactory grpcChannelFactory;
private GreeterGrpc.GreeterBlockingStub greeterStub;
@PostConstruct
public void init() {
Channel channel = ateChannel("gRPC server name");
greeterStub = wBlockingStub(channel);
}
通过在 Channel 类型的字段上加⼊ @GrpcClient(serverName) 注解,并创建⼀个⾃⼰的 gRPC stub.
不需要使⽤ @Autowired 或者 @Inject 来进⾏注⼊
@GrpcClient("gRPC server name")
private Channel channel;
private GreeterGrpc.GreeterBlockingStub greeterStub;
@PostConstruct
public void init() {
greeterStub = wBlockingStub(channel);
}
直接将 @GrpcClient(serverName) 注解加在你⾃⼰的 stub 上
不需要使⽤ @Autowired 或者 @Inject 来进⾏注⼊
@GrpcClient("gRPC server name")
private GreeterGrpc.GreeterBlockingStub greeterStub;
注意: 你可以为多个 channels 和多个不同的 stubs 使⽤相同的 serverName (除⾮他们不⼀样).
然后你可以直接向服务端发起请求,如下:
HelloReply response = stub.wBuilder().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
Properties⽰例
grpc.client.(gRPC server name).address=static://localhost:9090
# Or
Name.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

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。

发表评论