XingtanXue

研究微信技术问题

即时通信:前端获得消息发送到服务端,服务端处理后通过推送的方式,给到接收方;Android使用长连机制,联通网络长连十几分钟,电信仅五六分钟,因此需要根据测试的芯片类型,为了保活,可能要三四分钟就要去连一次,叫心跳机制;IOS通过APN机制推送。即时通讯是在一种平等、开放情况下的互动,这点很重要。

推送:采用增量推送的方式,设置一个sequence,服务端一个客户端一个,每次同步时客户端将cur_seq发给服务端,获得增量数据同步到本地。每个seq都是long型占8byte,考虑到微信用户6亿,Qps达到千万级别,则每秒要处理100兆的IO,相对来说比较大,如何降低呢,微信有一个AllocSvr和StoreSvr两个服务,分别来处理分配和存储,设计一个max_Seq和步长,将一定数量的用户比如连续ID一万个,设计在同一个Section,加上一个max_Seq,步长设为10000,此时可以10^3个等级的数据量,相对AllocSvr处理就简单一些,所以任何一个简单的事情在海量数据下,都会变成一个复杂的问题。另外添加步长,就涉及Old AllocSvr和New AllocSvr,需要根据已知配置文件,有哪些服务器可以切换,考虑到容灾还要做备份服务器,因此做互为备份是服务器能力不浪费的优秀设计;路由的切换也是根据seq的方式,使用路由表来切换的。

红包:活动前将资源通过消息的方式同步到客户端,防止活动当天同步资源造成浪费。每十万级的红包放一个包裹,加入票据,争取更多的资金能够进来,将分配规则写入客户端,然后将红包写入用户,异步对账后同步到账户里;要避免1、不存在的红包分配给用户2、红包分配金额有误 3、红包发给不存在的人 4、红包重复发给一个人 5、红包重复发给其他人6、防止黑客攻击,每个包裹写一个公私钥,同时可以手工屏蔽某些密钥对,保证其中一对密钥被盗,其他仍然可以正常使用。以及采用qos将请求主动失败,分两种系统失败可以重试,逻辑失败则失败 ;由于对大广告主如5000万以上的做过系统配合,但也要在参与用户少的时候,保证用户抢红包的流畅性,进行降低处理。

Android:刚开始业务为主,随着业务量增大,逐渐改为功能为主,然后规划多个dex,甚至将相应服务新开进程执行;秉承用户体验的观点,复杂的逻辑一般放在服务端做,客户端仅做展示功能;安全方面,每次登录给予一个票据,用于服务端检验发送的信息是否合法;将主业务与工具和后台业务分开,分多个进程处理,可以明显降低内存和电量的消耗。

斑马广告:采用对一群人画像如1万人,而不对1个人进行画像分析,每个人加入标签,如年龄、旅游、科技等,如果需要5000万定向客户,而实际标签不足时,需要通过lookalike系统查找潜在的和之前尚未分析出的客户,准确率达到16%左右;标签标的有:朋友圈发的消息、广告的点击和互动、公众号的类型、店家wifi的登入等,对聊天记录腾讯有天然的敏感性,不进行分析。

朋友圈:自己的timeline即自己发的信息,好友的timeline即公用区域发的信息,这个都以用户为单位,将timeline分两类,自己和好友,自己的直接显示,好友的插入自己的消息,这是实现的第一步;第二位是交互,好友发一条消息,第一:哪些人可见哪些人不可见,好友这边呢,操作是直接插入到可见好友的timleline,不可见好友收到的是相反的消息即不插入,第二:哪些是共同的好友,评论和点赞彼此收的到,实际出现三个对象,你、我、其他人,三者均需要一个消息推送(实际情况更复杂,多个直接跟你互相的人即是你,你的好友中非彼此好友的人即是其他人),最终采用增量推送的方式。

后端:消息分五类,红包,文本和语音,图片和视频、群消息、朋友圈,优先保证第一项服务可用,然后保证第二项服务可用,最后再保证朋友圈可用,这是消息优先级,在信息量巨大时可以人工触发开关处理;考虑到国内外通讯,香港地区延时100-200ms,欧美约300-500ms,国外的消息即就近处理,并且放在就近的服务器上,上海保证北方区,深圳保证南方区,香港保证东亚区,加拿大保证欧美区,这样一方面保证应用的国外战略得以实施,另一方面消息分流减轻服务器的压力;值得讲的一点是不同区之间的消息通讯,比如北方区的A和东南亚区的B,A发送消息,存储在上海服务器,然后推送到香港服务器,由香港区推送给B,减少https公网的等待时间,另外一点如果此人经常全球跑,则数据会漫游到国内数据中心处理,否则经常切换数据中心和服务备份,会浪费大量资源,增加系统冗余。
接下来聊几个服务端的点
数据接入-数据处理(逻辑处理-数据读写)-数据持久化(数据存储)
Qos:quality of service 服务质量,网络请求会分发到很多数据中心进行处理,而每个路由都有一个buffer,超过后则丢弃,否则数据积压导致各方数据均不能有效处理,而各种服务瘫痪;传输顺序出错和其他出错,需要有相关协议保证重试。
Cgi:common gateway interface 大量用户发送的请求,后台会有无数个cgi程序都保证正确处理,比如消息推送和消息同步
容灾:设计3的倍数个数据中心,保证每个数据中心有2/3的数据处理峰值,这样在其中1/3个中心瘫痪时,其他2/3的中心可以接收它的处理能力。
埋点:与测试团队沟通容易出错的地方,做key-value增加策略,key为关键点的id,value为关键点数据+1的值,在后台展示和处理,达到预警则及时处理,达到早发现、早处理的目的,这也是容灾的一部分;另一部分是与产品团队,共同开发出业务的使用频率,为后面的产品设计和架构设计提供良好的数据支撑。
RPC:同步处理的消息往往是有限的,异步可以大限度的压榨服务器的处理能力,如微信开发的SvrKit,用户发出请求后,交付中间件异步处理,并提供出错重试协议,保证消息被正确处理。
数据IO:读写在大量数据交互的应用上显示尤为重要,提供memcache防止频繁访问数据库,提供多Master-Slave提供数据读写服务,如海外A的消息存储在加拿大,国内B的消息存储在上海,这就是两个Master,两者通信通过RPC推送到对方数据中心即可,Slave用在Master出问题时的备用存储方案,事后要两者要互相同步。
图片:用户发送后放到CDN处理,返回大图和缩略图链接,加到消息对象中,返回客户端。
同步:采用seq增量下发消息的方式,对邮件、漂流瓶等进行key-value的判断拉取数据。
安全:每次登录都带有票据,票据用密钥对+ID来处理,可以随时定向失效密钥。

{% raw %}

{% endraw %}