<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>分布式 on </title>
    <link>/tags/%E5%88%86%E5%B8%83%E5%BC%8F/</link>
    <description>Recent content in 分布式 on </description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Wed, 30 Sep 2026 11:30:00 +0800</lastBuildDate><atom:link href="/tags/%E5%88%86%E5%B8%83%E5%BC%8F/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>SSE 多实例部署的跨节点路由与断线补发</title>
      <link>/posts/sse-scalability-relay-fanout-architecture/</link>
      <pubDate>Wed, 30 Sep 2026 11:30:00 +0800</pubDate>
      
      <guid>/posts/sse-scalability-relay-fanout-architecture/</guid>
      <description>上一篇《SSE 还是 WebSocket：每连接内存、单机容量上限与多实例路由》在 4 核 8 GB 的压测环境里测了单机容量。2 万条 SSE 连接时，每条连接的 RSS 在 Netty、Go、Rust 上都是 35 KB 左右，Tomcat 全调优后是 148.1 KB；单机先后受限于 maxConnections 计数器、堆和扇出耗时。那篇最后一章写到「加第二台机器后，最先出问题的是路由」。这一篇接着讲多实例怎么设计，内容来自公开资料和设计推演，没有压测。
SSE 是一条一直不结束的 HTTP 响应，连接对象只存在于接受这条连接的那台机器的内存里。浏览器端的 EventSource 断线后会自己重连：服务端结束响应或者网络出错，它都会等一个重连间隔再发起请求；之前收到过带 id 字段的事件，重连请求就在 Last-Event-ID 头里带上最后一个 ID（见 WHATWG 的 Server-sent events）。部署成多实例后，这两个特性各带出一个问题。一是触发推送的请求常常落在另一台机器上：用户连在 Node A，更新却由 Node B 触发，Node B 在本地的连接列表里找不到这个用户，消息就发不出去（见 AYA 的 Scaling Pains: Why Your SSE App Fails Under Load Balancers）。二是重连请求经过负载均衡，也可能落到另一台机器上，这台机器手里没有这条连接之前收到的事件。
推送怎么到达持有连接的节点 flowchart LR P[&#34;发布请求目标：用户 A&#34;] --&gt; N1[&#34;Node 1没有用户 A 的连接&#34;] N1 -.-&gt;|&#34;消息怎么到达？&#34;| N2[&#34;Node 2没有用户 A 的连接&#34;</description>
    </item>
    
  </channel>
</rss>
