问题描述
给出以下代码(使用Spring Webflux和RSocket):
@MessageMapping("hello.{name}")
public Mono<String> greet(@DestinationVariable String name) {
return Mono.just("Hello " + name); // or assume this is making a slow http call
}
问题是:
-
当服务器负载沉重时,客户端是否仍将请求直接发送给服务器,服务器将缓冲该请求?还是实际上有某种机制使客户端等待服务器将信号发送给客户端?
-
如果客户端仍然发送请求,则服务器有时会内存不足以缓冲所有多余的请求。我们通常如何处理?可以上网 经纪人在这种情况下有帮助吗? (假设它是突发流量,我们无法及时扩展或扩展服务器)
解决方法
RSocket具有真正的弹性
RSocket作为一种网络协议,具有作为一流公民的弹性。在RSocket中,可以通过两种方式公开Resilience属性:
通过流量控制(也称为反压)实现弹性
如果您进行流传输,则订户可以控制要交付的元素数,因此服务器不会使您的订户不知所措。下面的动画显示了如何在RSocket协议级别上实现反应流规范:
可能会注意到,如在反应式流中,Subscriber
(左侧)request
的数据通过其Subscription
一样,此请求被转换为二进制帧,然后发送通过网络,接收者一旦接收到该帧,便对其进行解码,然后传递到远程站点上的相应订阅,以便远程发布者可以产生准确数量的消息。
通过租赁的弹性
另一方面,与流传输一起,通常管理多个连接的服务器必须承受负载,并且在发生故障的情况下,它应该能够防止任何进一步的交互。为此,RSocket带来了一个内置的协议功能,称为Leasing
。简而言之,Leasing
是协议速率限制的内置功能,其中请求限制是动态的,并且完全由响应方控制。
在此过程中可能会区别一些短语:
- 设置阶段 -该阶段在客户端连接到服务器时发生,并且双方都必须提供特定的标志以同意双方都准备好尊重租赁。
- 沉默阶段 -在该阶段,请求者无能为力。有一个严格的关系-除非响应者允许,否则请求不能做任何事情。 如果请求者尝试发送任何请求,则此类请求将立即失败,而不会将任何帧发送到远程 。
- 租赁供应阶段 -响应者就其容量达成协议并准备好接收来自请求者的请求后,就会发送一个名为
Lease
的特定帧。该框架包含2个关键值:Number of Requests
和Time to Live
。第一个值告诉请求者可以发送给响应者的请求数量。第二个值表示这种津贴的有效期。因此,如果请求者到那时还没有使用所有这些津贴,则该津贴将被视为无效,并且任何进一步的请求将在请求者的请求上被拒绝。
以下动画描述了这种相互作用:
注意
租赁策略在per connection
的基础上起作用,这意味着如果您发布租约,则将其发布给单个特定的远程请求者,而不是连接到服务器的所有请求者。另一方面,取决于某些指标等,可以应用数学方法在所有连接的请求者之间共享整个服务器的容量。
在哪里找到两者的示例
有两个很好的示例,它们演示了如何将流量控制和租赁与RSocket一起使用。所有这些都可以在RSocket-Java项目here
的官方git repo中找到。