Telegram 号称拥有 5 个数据中心 (DC, Data Center), 在其代码和文档中被称为 DC1 ~ DC5
- DC1 与 DC3: 位于美国迈阿密 (Miami, USA)
- DC2 与 DC4: 位于荷兰阿姆斯特丹 (Amsterdam, NL)
- DC5: 位于新加坡 (Singapore)
每个账号在注册时会关联到某个 DC, 之后无论更换手机号或地理位置, 都不会迁移至其他 DC。用户也无法手动选择 DC。如果客户端误连到错误的 DC, 服务端会返回错误信息, 要求重新连接到该账号所归属的 DC
DC5: 中文圈最知名的数据中心
在这 5 个 DC 中, DC5 在 Telegram 中文圈格外知名。原因并不是因为它默默无闻服务了大量的中文用户, 而是因为它经常宕机。
当 DC5 宕机时, 属于 DC5 的用户会陷入「不断重连」的状态, 无法使用 Telegram。于是, 群友们的热门话题往往变成「DC5 怎么又挂啦」。DC5 用户只能等待「重连中」的客户端恢复后, 再与其他 DC 的群友们一起批判 DC5
为了满足群友们的好奇心, 有人开发了一个 bot (机器人), 可以查询用户所在的 DC。于是群友们开始查起了自己的 DC
- 使用 +86 手机号注册的用户, 发现自己在 DC5 (新加坡), 即将体验下一次宕机
- 使用 +1 手机号注册的用户, 则会在 DC1 (美国迈阿密), 可以兼顾连接速度与稳定性
- 使用 欧洲手机号注册的用户, 会发现自己在 DC4 (荷兰阿姆斯特丹), 成为了中文圈中最稀有的存在
咦?等等… Telegram 号称共有 5 个数据中心, 但查询结果里却始终见不到 DC2 与 DC3 的用户
Telegram DC 的分配规则 (截至 2022-05)
我们生成了上万个来自全球各地的号码, 并通过 方法 1: 登录法 测试了 Telegram 的 DC 分配规则。
在测试过程中, 我们尽量让每个号码都连接到错误的 DC, 以便通过返回的
PHONE_MIGRATE_X
错误来确定该号码实际归属的 DC。同时, 这样也能避免产生大量垃圾短信, 减少骚扰, 更不会让 Pavel Durov 因短信费用而「破产」。在测试结束后, 我们先剔除了已确认为 DC4 的号码, 再将剩余号码连接至 DC4 进行二次判断, 以确保不会遗漏可能分配到 DC3 的号码。
根据测试结果, Telegram 的 DC 分配规则如下
- DC1、DC2、DC4、DC5: 根据用户注册时填写的手机号的国家代码进行分配, 这四个数据中心都在正常接收新用户, 并且拥有大量存量用户
- DC3: 曾经有用户, 但在 2020 年左右, 其存量用户可能已被迁移至 DC1。目前 DC3 仍在运行, 目前可能没有用户, 也不再接受新用户注册
也就是说, DC2 其实并不是空的。它依然在正常运行, 并且拥有大量用户, 只是中文圈里较少遇到。和其他数据中心一样, 只要用户注册时所用手机号的国家代码落在 DC2 负责的范围内 (如 +49 德国), 该用户就会被分配到 DC2
相比之下, DC3 虽然仍在运行, 但已经没有关联用户, 可能已经「消失」了。
如果你想让账号归属到指定的 DC, 从而避开 DC5 的宕机风险, 只需参考上图, 选择对应国家代码的号码进行注册即可。
我到底在哪个 DC?
既然有大量用户位于 DC2 , 为何上文提到的 bot 从未发现过来自 DC2 的用户呢?
目前常见的 DC 获取方法有 3 种。下面我们注册一个位于 DC2 的新账号为例, 实际测试这 3 种方法。
方法 1: 登录法
使用会被分配到 DC2 的手机号, 通过 Telegram MTProto 协议 (官方客户端同样使用该协议) 连接到 DC1, 并调用 auth.sendCode 接口尝试发送验证码。
此时, 服务端会返回 PHONE_MIGRATE_2
错误, 提示客户端应当连接到 DC2。如果改为连接 DC2 再执行相同操作, 验证码就会被直接发送。
由此可以确认, 该账号属于 DC2
这种方法, 前提是必须知道用户的手机号, 因此不适合用来查询群友的 DC
方法 2: 头像/文件法
当用户上传头像或文件时, Telegram 会将数据存储在账号所属的 DC。
以刚刚注册的 DC2 账号为例, 如果直接查询, 是无法看到它的 DC 信息的;只有当新号上传头像后, 才能在头像信息中确认其归属于 DC2
这是因为在下载头像时, MTProto 协议中的 userProfilePhoto 结构体会返回 dc_id
字段, 可以通过该字段来判断用户所在的 DC
换句话说, 这种方法是 通过用户上传的头像或文件所在的 DC, 来确定账号所属的 DC
这种方法相对准确, 但需要用户主动上传头像或文件。
方法 3: Web CDN 法
有些人会疑惑: 明明这个新号属于 DC2, 为什么 bot 却说是 DC4?
这是因为 bot 是通过 Telegram Web CDN 的文件域名来判断用户的 DC, 例如当头像域名以 cdn4
开头时, 就会被误认为是 DC4
我们在访问 https://t.me/<用户名>
并查看源码时, 可以发现新号的头像链接确实是 cdn4
开头的。
造成这种情况的原因是: DC2 与 DC3 的 Web CDN, 会 借用 同地点的 DC4 与 DC1 的域名来提供服务。因此, DC2 用户的头像常常出现在 cdn4
域名下, 最终被误判为 DC4 用户, 导致长期「查无此人」
由于 Telegram 的服务端实现与部分运行机制未开源, 本文的许多结论基于推理与实测结果。如发现文中的错误或掌握新线索, 欢迎在评论中指正与分享。
原文