Skip to content

Design Concept

padlocal edited this page May 7, 2021 · 1 revision

为什么这个 puppet 叫 “PadLocal” ?这就要谈到我们 puppet 的整体设计,以及相比其他 puppet 有什么不同之处。PadLocal 最大的特点是:

  • 账号状态的托管方式
  • 与 WServer 的通信方式

在设计 puppet 的时候,我们首先调查了社区内其他 puppet , 并研究了他们的实现原理。我们发现,其他 puppet 设计思路大多是这样:由 puppet server 进行管理和维持托管账号的状态。所有的请求都是通过 puppet -> puppet server -> WServer 这样一条链路完成。消息推送部分,puppet 和 puppet server 之间建立长连接,同时 puppet server 和 WServer 也建立对应的长连接。当有新消息推送的时候,是通过 WServer -> puppet server -> puppet 这样的链路到达 puppet 端。这样的设计中 puppet server 就充当了一种有状态的代理角色,所有流量都是由服务器完成转发。在我们看来这样的设计可能有几个潜在的劣势:

  1. 因为最终和 WServer 通信的都是 puppet server。如果一个 puppet server 上托管了多个账号,且没有对各个账号配置对应的代理策略,那么这些账号将共享 puppet server 的 IP。从风控角度来看,容易产生风险。而且一旦其中某些账号风险等级比较高,容易对同一个 IP 池的其他账号造成污染,伤及无辜。
  2. 所有流量都是通过 puppet server 转发,对其带宽产生了不小压力,特别是当托管账号中产生了大量图片、视频等多媒体资源时。
  3. 由于 puppet server 维护了托管账号状态,所以 puppet server 是有状态的。从系统架构角度来看,有状态的服务器在系统稳定性、可用性、容量规划等方面都存在不小挑战。如果集群中某些服务器宕机,而备机切换机制设计不够完善的话,容易出现部分账号处于不可用的状态。
  4. 为了保证 puppet 有更好的可用性和体验,通常 puppet server 会缓存(不一定永久保存)某些数据(比如聊天数据)。也就是说,服务端无可避免地需要触碰托管账号的业务数据。这就需要 puppet 的提供者保持极高的行业自律,而且通过充分的机制保证客户数据的安全性。

基于对以上这些问题的思考,我们将所有流量转发工作都放在了 puppet 来做,这就是 PadLocal 中 Local 的来源。我们利用了 GRPC 的双向通信机制,让 puppet 成为代理,将所有流量通过 puppet 转发给 WServer。同时由 puppet 来维持和 WServer 之间的长连接。这样的好处显而易见:

  1. 托管账号和 WServer 通信所使用的 IP 都是 puppet 端的 IP,不同账号天然就不存在共享 IP 的风险。
  2. 下载图片、视频等多媒体资源的流量不需要经过 PadLocal server。而且不经过服务器,效率也更高。
  3. 账号状态维护在 puppet 端完成,于是 PadLocal server 就可以设计为 stateless 的了,应对扩容等问题天然就会简单很多,simple is beautiful。
  4. PadLocal server 不会保存任何业务数据,没有数据安全方面风险。

整体架构的拓扑图就如下所示:

拓扑图

欢迎大家一起交流学习。