
一个人成熟的标志,是开始做减法——减掉无效社交、无用信息、无谓的证明。
大多数人高估自己一年能做的事,却严重低估自己十年能做的事。
种一棵树最好的时间是十年前,其次是现在。
一、跨国延迟从哪里来
二、全球多地域部署的关键设计
三、T某gram 的多数据中心设计
四、如何优化提升
北京到美西直线约 1 万公里,光在真空里跑这段要 33ms,而信号在光纤里只有真空光速的约三分之二,单程拉到约 50ms。一来一回,物理下限已是 100ms 上下——还是"假设一根笔直光纤直连两地"的理想。
而现实没有这根笔直光纤。跨太平洋的公网流量要经过若干运营商骨干网、海缆登陆站、若干跳路由器,绕路是常态。北京到美西的公网 RTT 通常落在 150ms 到 250ms、拥塞时更高,你ping 一下跨国节点就能复现,这不是估算。
延迟最伤人的不在"一个 RTT",而在握手把 RTT 翻倍。建一条加密长连接,TCP 三次握手 1 个 RTT、TLS 1.2 完整握手再 2 个 RTT,共 3 个 RTT。按单程 100ms 算,光"把管子接通"就花掉 600ms,用户还没发出第一个字节。即便 TLS 1.3 把握手压到 1 个 RTT,每条消息的来回应答仍逃不掉那个物理 RTT。
所以今天文章,我们标题那个对比是真实的:同城内网一条消息端到端 30ms 很常见,跨太平洋公网做到 300ms 已算不错——差的这 270ms 绝大部分不是代码慢,而是地球太大、公网太绕。
多地域部署要解决的是"让物理距离不再决定用户体验"。核心动作只有一个:把接入点搬到离用户足够近的地方,让那个无法压缩的物理 RTT 尽可能小。放进 IM 分层看,它影响最外两层——接入层和路由层:

图 1. 多地域部署只动接入与路由两层,存储按归属分区
接入层从"一个机房"变成"散布全球的若干接入点",但是路由层要解决一个新的问题:发送方接进亚太、接收方归属北美,这条消息怎么走。再往里的消息核心和存储逻辑本身不需为多地域改写,但要回答"数据放哪个地域"。
先诚实说明:我做过的几个 IM 项目都是单地域部署,没亲手落地过全球多地域。本文是基于业界公开资料调研和单地域经验,对"如果要做全球部署会怎么设计"的推演,落地细节我会标明是设计判断而非实战结论。但单地域里我反复遇到一件事——一旦有海外用户接进来,跨国那段 RTT 立刻成为最大的体验短板,这就是要写这篇分享的背景。
如果把全球用户都引到一个机房,会在三个场景上集中暴露问题。
场景一:海外用户发消息像拨号上网。 接入点在国内,海外用户每发一条消息、每收一次回执都要跨一次太平洋。聊天这种高频小包交互对 RTT 极其敏感——输入状态、已读回执、消息送达每个动作都是一个来回,300ms 单次延迟叠加起来,整段对话都是"卡顿感"。
场景二:长连接建立连接慢且容易断。 跨国公网抖动大、丢包率高。TCP 在高 RTT 高丢包下,重传退避会让建连从几百毫秒飙到几秒;长连接也更容易因中间链路抖动断开,断了又要重新跨国握手。海外接入的建连失败率和重连频率明显高于国内。
场景三:合规上根本走不通。 这点和延迟无关但同样致命。GDPR 及多国数据本地化法规要求某些地区用户的个人数据留在本地境内。把全球数据全塞进国内一个机房,在这些地区直接构成合规风险,可能连业务准入都过不去。

问题:用户分布在全球,怎么让每个人都连到离他最近的接入点?
这要解决两件事:在全球铺设接入点(PoP,Point of Presence),再把每个用户调度到正确的 PoP。调度主流方案:
做法一:DNS 地理调度(GSLB)。 权威 DNS 按请求来源 IP 判断地理位置,返回最近 PoP 的 IP。实现简单、改造小,是大多数项目的起点。代价是 DNS 有缓存、切换有分钟级延迟,且判断依据是 LocalDNS 出口 IP,不总等于用户真实位置。
做法二:Anycast。 同一个 IP 在全球多个 PoP 同时宣告,由路由协议把用户的包导向"路由意义上最近"的 PoP,用户无感知、切换快。
光调度到位还不够,边缘 TLS 终结才是砍掉握手延迟的关键。回到 1.1 的账,3 个 RTT 的握手就近 PoP 完成每跳几十毫秒、到核心每跳却是 200ms。让 PoP 就近终结 TCP 和 TLS——用户与 PoP 走完整握手、PoP 与核心走早已建好的复用连接——握手延迟就从"跨国 3 个 RTT"压成"就近 3 个 RTT"。
问题:用户接进就近 PoP,但消息最终要送到归属区核心。PoP 到核心这段若还走公网,跨国那一跳的抖动又回来了。把它搬到可控的加速通道,有两种典型形态。
形态一:私有骨干网。 自建或租用专线把全球 PoP 连到核心区。路由可控、丢包低、抖动小,跨区延迟比公网稳定。代价是重资产路线,只有头部体量的产品才负担得起,这是选型时要面对的现实约束。
形态二:软件定义的实时传输网。 不自己铺光纤,而是在公有云和多机房节点之上用软件做智能选路、动态避开拥塞链路。声网《Agora SD-RTN 的演进》分享过这类思路:在一张全球节点网上实时探测链路质量、为每条流选当下最优路径。阿某云全球加速(GA)是这条路线的产品化——TCP、SSL 就近卸载到边缘,再走云厂商内部骨干回源。
对中小项目,形态二更现实:不用自建骨干,直接用云厂商的全球加速产品就能拿到大部分收益,是用钱换工程量的取舍。
问题:用户可从任意 PoP 接入,但数据总得有个"家"。怎么决定一个用户、一个会话归属哪个区?
这就是单元化的思路:按某个维度把用户切分到不同归属区(home region),每个区是相对自治的单元,核心数据和写操作都收敛在自己单元里。
落到 IM 上,归属维度有两种选择。按用户归属:每个用户绑定一个主区,由注册地或合规要求决定,单聊时消息送到接收方主区——这是最常见的,因为 IM 的核心实体就是用户。按会话归属:一个会话(尤其是群)绑定一个主区,所有消息都在该区定序,好处是群消息时序天然单点保证,代价是成员可能分布多区、远端成员每次都要跨区。
所以用户有主区、会话也有归属区(通常是群主的区),路由层需要维护一张"谁归属哪个区"的映射,跨区决策都查它。
route_message(msg):
target = msg.receiver // 或群会话 id
home = home_region_of(target) // 查归属映射
if home == current_region:
deliver_local(msg) // 同区直投
else:
forward_to_region(home, msg) // 跨区转发到归属区,由归属区定序这张映射通常缓存在各区做只读表,变更(迁移主区)是低频运维操作,不能放进消息热路径实时计算。
问题:发送方在亚太接入、接收方归属北美,这条消息怎么走才能既保证时序又尽量快?拆开看:

图 3. 跨区单聊:发送就近接入、归属区定序、接收就近下推
这里关键原则是写归属、读就近、最终一致:
这里需要进一步说明与容灾的边界:跨区复制在这里只服务"读就近"和"消息时效",不服务"一个区挂掉后另一个区顶上"——后者是异地多活的容灾命题,不在本文展开。
问题:归属区不能纯按"离用户最近"选,法律先画一道线。
数据主权(数据受哪国法律管辖)和数据驻留(数据物理存在哪国)是相关但不同的概念,比如当地法规要求地区用户的个人数据必须存在境内。出海 IM 必须按地区做数据分区,这不是优化项而是准入项。
这直接影响归属决策,让它变成两层过滤——先合规圈定允许的区集合,再在集合里挑最近的:
choose_home_region(user):
legal_regions = compliant_regions(user.country) // 关键:合规先过滤,硬约束
if legal_regions is empty:
reject_or_manual_review(user)
return nearest_among(legal_regions, user.location) // 在合规集合里再挑最近顺序不能反。这也意味着某些用户拿不到理论最优延迟——常驻欧盟外但数据必须留欧盟的用户注定承受跨区延迟,这是合规换来的代价。
T某gram 把服务器分成若干数据中心(DC),分布在世界不同区域。官方文档《Data Center Assignment》写明:客户端初次认证时,服务器会检查其 IP 地址来"识别最近的 DC"(identify the closest DC)。重定向机制分两种,文档区分得很清楚:
换句话说,新用户按地理就近落 DC,老用户按账号归属回自己的 DC——这正是 (就近接入)和(用户归属)在真实系统里的合体。
官方文档还写明一句关键的话:用户"不能通过客户端被关联到另一个 DC",且"用户信息累积在用户所关联的那个 DC 里"。
这就是"用户归属唯一"在协议层的硬化:账号一旦绑定某 DC,数据就长在那 DC,客户端无权改。用户出国时可能就近接入另一个 DC 做认证握手,但涉及账号数据的操作会被 PHONE_MIGRATE 重定向回归属 DC——这正是"接入可以就近、归属必须回家"的典型实现。
文字消息要回归属 DC,但大文件(图片、视频)若也都从归属 DC 拉,跨区下载会很慢。T某gram 官方 CDN 文档的解法是:对超过 10 万订阅者的公开频道的媒体,缓存到离用户更近的 CDN DC,这样终端用户下载速度会快得多。
维度 | 详情 |
|---|---|
优势 | 协议层显式归属,路由决策简单清晰;新用户就近落 DC、老用户按账号回家,延迟与归属两头兼顾;媒体走加密 CDN 就近下载,速度与安全兼得 |
代价 | 账号死绑单一 DC,用户跨区常驻时账号数据仍跨区,延迟无法消除;CDN 仅覆盖大订阅公开频道媒体,私聊媒体不享就近;自研非标协议把就近/归属逻辑做进协议,演进和审计成本高于用标准方案 |
跨区转发 + 异步复制会同时带来乱序和重复。乱序之前说过——定序单点放在会话归属区。重复要单独处理:跨区转发链路长、重试多,同一条消息可能投递两次。
稳妥的做法是给每条消息一个全局唯一 id、接收端按 id 幂等去重,而不是依赖"恰好一次投递"——跨国链路抖动大,追求 exactly-once 的成本远高于"at-least-once + 接收端幂等"。跨区链路把重试和延迟放大后,幂等去重从单地域的"最好有"变成"必须有"。
单地域监控盯的是"服务挂没挂",多地域要多盯一维:"每条跨区链路现在快不快"。公网链路质量是动态的,某条跨太平洋路径今天 180ms、明天拥塞到 400ms 是常态。
可观测上要把"区到区的实时 RTT、丢包率、抖动"做成一等公民指标,按链路(不是按服务)采集告警——中小项目即便用云厂商的全球加速,也应自己埋一层端到端探测:别人的骨干网内部看不到,但端到端表现测得到,排障时这是唯一可信的依据。
跨国那段物理 RTT 我们是无法避免,能做的只有一件事:让它尽量短、尽量稳,并让用户察觉不到它的存在。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。