为什么SSE挂在连接上?

时间:2019-04-22 17:06:58

标签: ruby-on-rails server-sent-events

我正在阅读this post,其中谈到了不阻塞服务器线程的SSE连接。作者正在描述如何解决阻塞问题。

我的困惑是,如果我要关闭服务器端(使用sse.close)和客户端(使用source.close())的流,为什么首先遇到问题?为什么服务器挂起连接?

1 个答案:

答案 0 :(得分:1)

问题不是关闭连接,而是关于何时进行连接-这种情况发生的时间比常规请求晚(数十秒,甚至数小时)即使在最重的情况下也能处理不到几秒钟。

例如,假设(非常简化和近似):

  1. 您有10个线程/工作人员,没有SSE
  2. 您可以在0.1秒内投放每个html页面
  3. 用户最多需要等待1秒钟的时间才能加载页面,然后大哭一场并离开您的网站
  4. 然后,用户将阅读该页面9秒钟,然后再请求下一页

这样,每个线程每秒可以提供10页服务,所有线程-每秒可以提供100页服务,因为每个用户每10秒最多请求一次请求-您可以同时使用您的应用处理大约1000个用户

现在,逐步将SSE更新添加到这些页面:

  1. 第一个用户连接,在0.1秒内获取html,然后一个线程被SSE请求占用9秒,然后页面重新加载,并且在重新加载后,该线程将再次被相同用户的请求锁定
  2. 您只有9个空闲线程
  3. 第二个用户连接,相同的重复

这样,同一系统最多只能处理 10个用户,这要少100倍。而且您不能仅仅将线程增加到1000,因为它们不是空闲的(内存,调度程序开销等)。

问题在于,大多数情况下,大多数此类连接在等待事件时不执行任何操作,因此它们实际上不需要为其保留的线程。因此,在不关闭连接的情况下为其他请求释放线程是合乎逻辑的,这就是劫持行为。

PS。这种方法甚至可以进一步采用-客户端实时更新连接可以由Rails服务器以外的其他进程保持打开状态(非Rub,效率更高),同时仍然在Rails中执行所有事件逻辑。例如,使用ActionCable的anycable后端,您可以轻松保持数千个并发连接