RSocket + Webflux请求-响应弹性 注意

问题描述

给出以下代码(使用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
}

问题是:

  1. 当服务器负载沉重时,客户端是否仍将请求直接发送给服务器,服务器将缓冲该请求?还是实际上有某种机制使客户端等待服务器将信号发送给客户端?

  2. 如果客户端仍然发送请求,则服务器有时会内存不足以缓冲所有多余的请求。我们通常如何处理?可以上网 经纪人在这种情况下有帮助吗? (假设它是突发流量,我们无法及时扩展或扩展服务器)

解决方法

RSocket具有真正的弹性

RSocket作为一种网络协议,具有作为一流公民的弹性。在RSocket中,可以通过两种方式公开Resilience属性:

通过流量控制(也称为反压)实现弹性

如果您进行流传输,则订户可以控制要交付的元素数,因此服务器不会使您的订户不知所措。下面的动画显示了如何在RSocket协议级别上实现反应流规范:

RSocket And Reactive-Streams

可能会注意到,如在反应式流中,Subscriber(左侧)request的数据通过其Subscription一样,此请求被转换为二进制帧,然后发送通过网络,接收者一旦接收到该帧,便对其进行解码,然后传递到远程站点上的相应订阅,以便远程发布者可以产生准确数量的消息。

通过租赁的弹性

另一方面,与流传输一起,通常管理多个连接的服务器必须承受负载,并且在发生故障的情况下,它应该能够防止任何进一步的交互。为此,RSocket带来了一个内置的协议功能,称为Leasing。简而言之,Leasing是协议速率限制的内置功能,其中请求限制是动态的,并且完全由响应方控制。

在此过程中可能会区别一些短语:

  1. 设置阶段 -该阶段在客户端连接到服务器时发生,并且双方都必须提供特定的标志以同意双方都准备好尊重租赁。
  2. 沉默阶段 -在该阶段,请求者无能为力。有一个严格的关系-除非响应者允许,否则请求不能做任何事情。 如果请求者尝试发送任何请求,则此类请求将立即失败,而不会将任何帧发送到远程
  3. 租赁供应阶段 -响应者就其容量达成协议并准备好接收来自请求者的请求后,就会发送一个名为Lease的特定帧。该框架包含2个关键值:Number of RequestsTime to Live。第一个值告诉请求者可以发送给响应者的请求数量。第二个值表示这种津贴的有效期。因此,如果请求者到那时还没有使用所有这些津贴,则该津贴将被视为无效,并且任何进一步的请求将在请求者的请求上被拒绝。

以下动画描述了这种相互作用:

RSocket And Leasing

注意

租赁策略在per connection的基础上起作用,这意味着如果您发布租约,则将其发布给单个特定的远程请求者,而不是连接到服务器的所有请求者。另一方面,取决于某些指标等,可以应用数学方法在所有连接的请求者之间共享整个服务器的容量。

在哪里找到两者的示例

有两个很好的示例,它们演示了如何将流量控制和租赁与RSocket一起使用。所有这些都可以在RSocket-Java项目here

的官方git repo中找到。