-
Notifications
You must be signed in to change notification settings - Fork 167
RSocket P2P
在一些性能非常关键的场景中,我们需要通过直连的服务提供方,这样性能比较高。
服务直连的优点:
- 性能非常高:不需要经过Broker,可以减少TCP两跳,性能更高一些
服务直连的缺点:
- 服务提供方需要提供对应的端口监听
- 服务提供方要对服务台消费者连接时要进行对应的权限判断,可能还需要设置TLS等
- 服务调用方的网络和服务提供方的网络是打通的,可以直接连接
- 服务提供方要维护大量的网络连接,相对比较消耗资源
通常我们不建议服务消费方到服务提供方之间的直连,只有是性能非常关键的场景,才建议开启P2P直连。
服务直连是基于服务接口级别的,而不是基于应用级别的,一个应用提供的服务列表中,并不全是高QPS的场景。
那么如何开启服务的直连?
- application.properties文件中添加
rsocket.p2p-services=com.alibaba.user.UserService2
配置项 - RSocketRemoteServiceBuilder中调用p2p()方法设置该服务接口直连
如果服务提供者未提供对应的端口监听,则会通过Broker完成对应的调用。
RSocket服务直连的背后原理:
- 服务消费方要告知UpstreamManager(连接管理器),有相关的service需要直连
- 应用启动时,并不会创建直连服务,而是和Broker创建连接,所有的服务调用此时还是通过Broker进行转发的。
- 应用和Broker创建连接后,如果Broker发现有应用有直连的服务接口信息,这时Broker会从路由表中查询直连服务对应的服务实例信息,过滤条件就是服务实例列表包含监听端口,然后就推送ServiceInstancesChangedEvent事件
- 应用接收到ServiceInstancesChangedEvent事件后,如果服务对应的UpstreamCluster(服务连接管理器)不存在,则会创建该服务接口对应的UpstreamCluster,如果对应的UpstreamCluster已存在,则进行实例列表更新
- 为了确保服务对应的列表幂等,如推送的事件丢失等,UpstreamManager会每隔120秒进行一次和Broker同步,刷新直连服务对应的列表。
- 服务消费方在调用远程服务,如果服务接口对应包含UpstreamCluster,则会走对应的UpstreamCluster方式,也就是服务直连,不然就是走Broker完成调用。
当然在实际的业务场景中,如果遇到服务提供方的地址非常多,可以考虑随机推送部分服务提供者的IP地址,这样服务连接方不用和服务提供方创建非常多的连接。 要知道这个设计中是有容错的,即便所有直连都错误,还是有Broker转发兜底的,所以不用太担心,服务总是能被调用的。
基于该服务列表推送机制,还可以完成其他一些场景,如某一应用调用某一服务接口的量特别大,这个时候,通过Metrics审计系统可以给Broker发一个推送服务地址列表事件,而应用侧收到该事件后,就会主动和服务提供方直连,这样即便应用侧没有设置直连,Metrics审计系统可以更加数据进行对应的调整。
在服务直连的情况下,服务提供者如何验证服务消费者?每一个应用在启动后都会生成一个UUID,该UUID是惟一的,所以可以服务提供方可以根据UUID向Broker查询,Broker会根据应用接入的JWT token判断服务方能否可以调用对应的服务,如果合法,然后服务提供方允许应用方进行连接和服务调用访问。 发给服务提供者时,不需要发送JWT Token,只要发送AppMetadata给服务方就可以。
注意:这种方式存在安全风险,如从控制台查询到应用列表从而获得应用的UUID,但是对于内部通讯来说,还是有一定的安全保证的,主要是应用的UUID在应用重新启动后会使用新的。
该方案目前还是草案,RSocket Broker还没有添加对应的安全限制,还是开放连接的(未进行权限),并没有进行对应的安全验证。
服务直连后,虽然请求不进过Broker啦,但是Metrics和Tracing这些数据还是都包含的,不会丢失。在RSocket Broker设计中,Broker是可以主动采集任何应用的Metrics信息的,所以这些数据都不会丢失的。。
- 指定IP调用: 也就是指定服务对应的IP地址,这个主要是用于开发阶段,如你开发一个服务接口,其他同学抱怨接口有错误返回,只需将服务接口的对应的连接IP调整为你笔记本IP就可以啦。
- Broker调用: 通过Broker转发请求,这个是RSocket Broker标准做法
- 直连调用: 也就是本文说到的场景,核心是性能要求,当然还可以支持A/B testing,智能推送等。
- Binary: byte stream
- Async message
- Multi transports
- Reactive Semantics
- request/response
- request/stream
- fire-and-forget
- channel
- TCP+TLS
- WebSocket+TLS
- UDP(Aeron)
- RDMA