这个演讲主要讲了朋友圈背后的技术,主要有技术栈,微信朋友圈架构,朋友圈流程举例,部署,接入和容灾机制。
技术栈
开发语言主要使用c++,使用protobuf描述接口,支持使用进程/线程/协程多种方式,支持数十万的并发协程,方便编写和调试"同步"的网络调用和服务。
开发模式采用敏捷开发方式,一月一个小版本,一季度一个大版本。
朋友圈架构
整体架构如下(图片均来自ppt),最上面为接入层,接入主要维护长连接,长连接主要为了安卓系统,一方面能够减少新建连接的性能损耗,另一方面由于谷歌的国内服务基本不可用,安卓的推送通知都是通过长连接哎完成的。
接入层后面是逻辑层,逻辑层不仅有朋友圈,也有iOS的系统的通知,因为iOS App进入后台后只有15s的存活期,所以iOS上的推送通知要用API的Push完成。
接下来是存储代理层,这一层主要负责一些关键数据的维护操作,比如用户在账号里面的动作操作和事故信息。再往下是KV存储层,这里不存在业务逻辑,只是单纯的Key-Value映射,负载均衡和容错。
朋友圈架构.png整体的服务架构是微服务的架构,每个请求之后可能会涉及几百个服务,每一个服务都会有一个QoS,会对重要的服务进行优先保证。举例来说,在除夕晚上是平时5倍流量的情况下,优先保证支付,优先保证红包的体验。红包体验保证了,再保证消息,比如点对点两人之间的消息。这两个保证的前提下,再保证群聊。如果群聊也能保证,再保证朋友圈。在性能不够的情况下,会将优先级低的服务暂时停掉,整个过程不需要人工干预。
朋友圈流程举例
这里举例说明一下,两个用户小王和Mary(如下图)。小王和Mary各自有各自的相册,可能在同一台服务器上,也可能在不同的服务器上。现在小王上传了一张图片到自己的朋友圈。上传图片不经过微信后台服务器,而是直接上传到最近的腾讯CDN节点,速度非常快。图片上传到该CDN后,小王的微信客户端会通知微信的朋友圈CDN:这里有一个新的发布(比如叫K2),这个发布的图片URL是什么,谁能看到这些图片,等等此类的元数据,来把这个发布写到发布的表里。
在发布的表写完之后,会把这个K2的发布索引到小王的相册表里。所以相册表其实是很小的,里面只有索引指针。相册表写好了之后,会触发一个批处理的动作。这个动作就是去跟小王的每个好友说,小王有一个新的发布,请把这个发布插入到每个好友的时间线里面去。
Mary上朋友圈了,而Mary是小王的一个好友。Mary拉自己的时间线的时候,时间线会告诉到有一个新的发布K2,然后Mary的微信客户端就会去根据K2的元数据去获取图片在CDN上的URL,把图片拉到本地。在这个过程中,发布是很重的,因为一方面要写一个自己的数据副本,然后还要把这个副本的指针插到所有好友的时间线里面去。如果一个用户有几百个好友的话,这个过程会比较慢一些。这是一个单数据副本写扩散的过程。但是相对应的,读取就很简单了,每一个用户只需要读取自己的时间线表,就这一个动作就行,而不需要去遍历所有好友的相册表。
使用写扩散的原因是,如果使用读是很容易失败的,一个用户如果要去读两百个好友的相册表,极端情况下可能要去两百个服务器上去问,这个失败的可能性是很大的。但是写失败了就没关系,因为写是可以等待的,写失败了就重新去拷贝,直到插入成功为止。
举例.png部署,接入和容灾机制
在同一个区域的部署,微信在上海有一个IDC,该IDC是由三个独立的园区——A、B、C三个园区构成的。每一个园区都有独立的供电、制冷,独立的带宽,带宽同时连接联通、电信,而且每个园区的容量都有富余。三个园区直接有高速连接。所以无论任何一个区,比如C区整个不可用了,那么用户的客户端会自动连接到另外两个区,这两个区有足够的容量承载所有的服务。这种切换是无损的、无感知的。
跨地域的部署,微信目前有四个数据中心,上海,深圳,香港和加拿大,上海数据中心负责服务北方用户,深圳服务南方客户,香港数据中心服务东南亚,南亚,中东和非洲,加拿大数据中心负责服务美洲和欧洲客户。
关于接入,数据中心之间设计到很多同步问题,微信消息的数据同步是通过一个idcqueue组件实现的,是一个异步的数据同步方式。这个异步的写操作可能会由于网络阻塞或者其他原因,慢个一两秒种、几分钟甚至半天,但它会一直重试,能够保持正确性。国内到国外的网络延迟很大,从大陆ping美国可能两百个毫秒,ping阿根廷或者南非可能有四百个毫秒,另外公网的丢包也比较严重,这对于数据同步的实现是很有影响的。为此,微信使用了自研的一套类似TCP的协议,这种协议对高延迟和高丢包有很高的容忍度。在国外专线也不能得到完全的保障,在专线终端时,会自动切换到公网,并使用AES加密。
在朋友圈的评论数据同步的时候,微信使用因果一致性算法来保证数据的一致。
数据中心.png
网友评论