本文转自:https://dev.moe/2564

Telegram 号称有 5 个数据中心(DC, Data Center),在 Telegram 代码与文档中被称作 DC 1~5。其中 DC1 与 DC3 位于美国的迈阿密(Miami, USA);DC2 与 DC4 位于荷兰的阿姆斯特丹(Amsterdam, NL);DC5 位于新加坡(Singapore)。

每个帐号都会在注册时关联一个 DC,此后不随用户更改手机号或地理位置迁移。用户也不能自由选用 DC——如果连接到了错误的 DC,服务端会返回错误信息,要求客户端连接到帐号所关联的正确 DC 上。

从日常宕机的 DC5 说起

在 5 个 DC 中,DC5 在 Telegram 中文圈格外知名——并不是因为它默默无闻服务了大量的中文用户,而是因为它经常宕机。

当 DC5 宕机时,身处 DC5 的用户无法使用 Telegram,此时的 Telegram 圈内的话题往往会变成 「DC5 怎么又挂啦」。DC5 用户只能等待自己不断「重连中」的客户端恢复后,再与其他 DC 的群友们一起批判 DC5。

DC2 与 DC3 之谜

为了满足群友们的好奇心,有人写了个 bot(机器人),可以查询用户所处的 DC。于是群友们开始查起了自己的 DC:

  • 用 +86 手机号注册的用户发现自己在 DC5(新加坡),即将体验下一次宕机。
  • 用 +1 手机号注册的用户则会在 DC1(美国迈阿密),可以兼顾连接速度与稳定性。
  • 用欧洲手机号注册的用户会发现自己在 DC4(荷兰阿姆斯特丹),成为了中文圈中最稀有的存在。
    咦?等等… Telegram 不是号称有 5 个 DC 吗?那 DC2 与 DC3 呢?

通过搜索 bot 的消息,用户位于 DC1 的有 360 条,DC4 有 50 条,DC5 有 390 条。DC2 与 DC3 有 0 条。

通过搜索 bot 消息的「大数据查询」,我们发现似乎真的没有来自 DC2 与 DC3 的用户。

于是,有人推测 DC2 与 DC3 皆无用户,也有人分析后推测 DC2 与 DC3 分别是 DC1 与 DC4 的附属 DC,会在其上级 DC 繁忙时接受用户注册。

真的是这样吗?

Telegram DC 的分配规则(2022-05)

  • DC1、DC2、DC4、DC5 是根据用户注册时所填写的手机号的国家代码分配的,这 4 个 DC 随时接受新用户注册,且均有大量存量用户。
  • DC3 曾经有用户,但在 2020 年左右,DC3 的存量用户可能已被转移至 DC1。DC3 目前可能已无用户,且不再接受新用户注册。

也就是说,DC2 实际上关联着大量用户,且像其他 DC 一样,只要用户注册时,手机号的国家代码落在 DC2 负责的范围内(如 +49 德国),该用户就一定会进入 DC2。而 DC3 虽然仍在正常运行,但可能已无关联用户。

既然有大量用户位于 DC2 ,为何上文的 bot 从未发现过来自 DC2 的用户呢?

这是因为 bot 获取 DC 的方式出了问题。

我到底在哪个 DC?

目前常用的 DC 获取方法有 3 种,下文将注册一个 DC2 的新帐号,实际尝试一下这 3 种方法。

方法 1(登录法)

们使用会被分配到 DC2 的手机号,通过 Telegram MTProto 协议(这也是官方客户端使用的协议)连接 DC1,调用 auth.sendCode 接口,尝试发送验证码,注册一个账号。

此时服务端会返回 PHONE_MIGRATE_2 错误,提示客户端应当要连接 DC2(如果连接 DC2 后进行同样操作,便会直接发送验证码)。

这样,我们就知道这个帐号是一个 DC2 的帐号。这种方法对于已注册的帐号同样有效,但是这种方法需要知道用户的手机号,难以用来查询群友的 DC。

方法 2(头像/文件法)

在刚才的 DC2 帐号注册完成后(下文称之为新号),我们利用会显示用户 DC 的第三方客户端(Plus Messenger),登录自己的另一个账号,去查看新号的 DC。然而,客户端此时并未能显示 DC,需要替新号上传头像后才显示新号在 DC2。

这是因为第三方客户端是在下载用户头像时,通过 MTProto 协议 userProfilePhoto 结构体中的 dc_id 字段,来获知用户所在的 DC。

这种方法是通过用户上传的文件所在的 DC,来判断用户所在的 DC。

如果是用新号登录第三方客户端去查看自己的 DC,则可能是通过方法 1 判断出的 DC,因为客户端知道自己在连接哪个服务器。

方法 3(Web CDN 法)

最后我们通过上文提到的 bot 查询这个新号的 DC。

bot 说,该帐号所在的数据中心为 DC4(阿姆斯特丹,荷兰)

咦?这个新号不是位于 DC2 吗,为什么 bot 会说是 DC4 呢?

其实它是通过 Telegram Web CDN 来获取用户的 DC 的。我们打开 https://t.me/dctest** 查看源码,会发现新号的头像域名是以 cdn4 开头的,导致被 bot 判断为了 DC4。

由于 DC2 与 DC3 会「借用」同地点的 DC4 与 DC1 域名来提供 Web CDN 服务,因此 bot 无法找到任何 DC2 用户——他们都被判断成了 DC4 用户。

还有另一种 bot,要求用户给 bot 发送一个图片/文件来判断其 DC。这类似方法 2,可以较为准确的判断用户 DC。

DC3 的消失

通过方法 2 正确获取用户 DC 后,我们可以发现在全球范围内(尤其是海外群组内),DC2 的用户并不算少,但 DC3 用户却屈指可数。多方查找后,我们发现了两名位于 DC3 的用户:@urie** 与 @flowinglig**。

然而,如果进一步分析,就会发现他们可能并不是真的在 DC3。例如,调用 photos.GetUserPhotos 查看头像列表,可以看到 @urie** 上传过 7 张头像,其中只有两张位于 DC3,新上传的头像都已在 DC1。

同样的,查看两位用户发言历史中的图片,也只有寥寥几张老图片是存于 DC3 的,新图片都是存在 DC1。而查看其它 DC 的用户,则发现他们发送的图片都存在各自所在的 DC 中。

此外,@urie** 也在 2021 年发送过文件给 DC 识别机器人(文件法)进行测试,返回的结果同样是 DC1。

遗憾的是,由于无法获知他们的手机号,所以并不能通过方法 1(登录法)准确测试,这里只能通过方法 2(头像/文件法)推测他们从 DC3 被转移到了 DC1。

为了进一步证实 DC3 已经不再接受新用户,我们生成了万余个全球各个地区的号码,通过方法 1(登录法)测试 Telegram 的 DC 分配规则,结果如下:

在测试过程中,我们尽可能让每个号码都连接到错误的 DC 上——这是为了通过返回的 PHONE_MIGRATE_X 错误了解号码对应的实际 DC,也是为了避免产生大量垃圾短信,造成骚扰及 Pavel Durov 因短信费破产。

在完成测试后,我们剔除了确定位于 DC4 的号码,再将剩余号码连接至 DC4 再次判断,以确保不会遗漏被分配至 DC3 的号码。

结合以上分析,我们可以认为 DC3 确实已不再接受新用户,而老用户也可能已经全部被转移至 DC1 了。

尽管我们没能找到消失的 DC3,但如果你想要成为指定 DC 的用户,回避 DC5 的宕机风险,或是测试一下测试机器人是否靠谱,现在只需参考上一张图,使用特定国家代码的号码注册即可。


由于 Telegram 服务端和部分运作机制并不开源,本文许多结论是通过推测得出。如有发现文中的错误,或有其他线索,欢迎评论提出。

本文撰写过程中参考了以下项目及内容,在此表示感谢: