学在腾讯:简而美的微信后台架构

注:公司分享讲座的一点笔记,不保证准确性。

问题

极致的业务特性

  • 流畅的消息收发
  • 及时的通知
  • 省电
  • 省流量
  • 瘦客户端

困难的后台-终端同步

  • 同步多样数据:账户信息、通讯录、消息、朋友圈等
  • 及时通知与同步
  • 移动网络下的可靠同步
  • 省流量与电量

方案

极简的同步协议

  • 后台与终端只需要沟通一个数字,后台即可知道终端缺失的所有数据。
  • 变更序列号/版本号:
    • 后台对用户数据的每项变更,都赋予一个单调递增的序列号,即用户的每项数据都有一个全局递增序列号。
    • 后台每次给终端发送数据都会带上所发送的所有数据的最大序列号。
    • 终端每次请求数据时都会带上已经接受到的最大序列号。

高效的通知机制

  • ios Apple Push Network Service
  • Android等-长连接
  • GPRS/EDGE信令风暴优化
  • 自适应心跳间隔调节

三层后台架构

Arch of weixin backend

统一的RPC框架

  • 根据ProtocolBuffer定义生成服务器框架和客户端
    • 服务器:开发人员填充接口实现
    • 客户端: 应用方本地调用客户端提供的接口函数
  • 屏蔽网络细节
    • 支持基于TCP/UDP的网络调用
    • 支持长短连接
  • 丰富的功能
    • 基于sharding的SET分布
    • 基于一致性哈希的无状态存储
    • 服务透明重定向
    • 丰富的自动化监控:(1)QPS;(2)响应时间;(3)排队时间;(4)各个接口的调用频率与返回状态码分布;(5)各个服务之间的调用拓扑

高并发的协程RPC

服务器同步的调用模型相较异步模型更容易学习、使用和调错。但一台服务器支撑的进程数和线程数是非常有限的。

基于用户态线程(协程)的RPC

  • 单机可以支撑数万甚至十万的用户态线程,仅受CPU和内存约束
  • 提高并发性和性能

用户态线程RPC的实现

  • 基于makecontext/getcontext/swapcontext
  • Hook Network: read/write/epoll
  • 用户态线程调度

就近访问

  • 就近访问IDC
  • 就近网络接入:覆盖各大运营商
  • CDN:上传下载图片
    • 腾讯自建CDN
    • AKAMAI

多IDC分布提升用户体验

  • 国内复杂的网络环境
  • 超过1亿的海外用户
    • 分布在全球
    • 更为多样化的网络环境
  • 每个IDC都提供完整的功能和所需访问的所有数据
  • 每个IDC有共同的数据和独立数据
    • 账户信息全球一致
    • 用户数据各自独立:(1)一个用户只属于某个IDC;(2)用户属性、关系链、消息;(3)按需共享的SNS数据-照片、评论、红心,减少网络同步带宽消耗

IDC分布数据的高可靠最终一致性保证

  • 账户数据和SNS数据主备访问模型
    • 用户所在的IDC是主IDC
    • 其他IDC相对这个用户所在IDC都是备IDC
    • 更新由主扩散到备
  • 弱实时性跨IDC更新采用基于Zookeeper仲裁的主备任务队列
    • 收拢跨IDC访问接口
    • 重做保证跨IDC更新的可靠性
    • 数据序列号在重做时保证达到最终一致性
  • 关系链跨IDC更新
    • 隐私控制要求实时性
    • 直接跨IDC网络调用
    • 后台批处理重试失败请求

容错和容灾机制

  • 单IDC
    • 用户按SET分布,各个SET之间独立
    • ...
  • 高可用的异地容灾
    • 每个服务的主IDC都有一个灾备IDC
    • 挑战:终端在主备IDC切换时的无缝连接;主备间的数据一致性。