本篇算是我阅读完微信后台技术相关的干货文章后得到的一些启发,如果去年中那篇属于技术干货的选择问题,这篇大概就是选择之后的消化吸收问题了。

循证与决策路径

在前文中提过,循证大概是我们读技术干货文章的一个原始诉求,通过分析别人走过的路径,来拨开自己技术道路探索上的迷雾。

关于 IM 类消息应用最重要的一个技术决策就是关于消息模型,微信采用了存储转发模型,其具体描述如下(参考[1]):

消息被发出后,会先在后台临时存储;为使接收者能更快接收到消息,会推送消息通知给接收者;最后客户端主动到服务器收取消息。

简单描述这个模型就是三个步骤:

  1. 消息接收后在服务端临时存储,并通知发送端已发送成功。
  2. 通知接收端有消息,请来拉取。
  3. 接收端收到通知后,再来拉取真正的消息。

初一看这个模型多了一层通知再拉取的冗余,为什么不直接把消息推下去?对,最早期我们自己做 IM 就设计的先尝试直接推消息下去,若接收端没有确认收到,再临时存储的模型。后者减少了临时存储的量和时间,也没有一个多余的通知。

但后面这个模型增加了另一层复杂度,在早期的 PC 互联网时期,推送并确认效率还算挺高的,但在移动环境下,就不太行了。而且引入了移动端,实际就导致了另一层复杂性,多终端在线,多终端确认,多终端已读和未读,都需要在服务端记录各个端的状态。所以,之后我们也就慢慢演变成同时存储和推送消息的并行模型,存储是为了方便各终端拉取各自的离线消息,但推送因为需要考虑旧终端版本的支持,还得直接推消息本身而并不容易简化成消息通知来取消掉消息的接收确认过程。

循证,即便你看到了一个更好的方式,但也要结合自身的实际情况去思考实践的路径。所以,如今我们的模型相比微信是一个更妥协的版本,若是五年多前要改成微信这样的模型,也许只需要一两个程序员一周的时间。但如今也许需要好几个不同的开发团队(各终端和后端)配合弄上一两个季度也未必能将所有用户切换干净了。

切磋与思考方式

IM 中还有个大家特别常用和熟悉的功能 —— 群消息。关于群消息模型,微信采用的是写扩散模型,也就是说发到群里的一条消息会给群里的每个人都存一份(消息索引,参考[1])。这个模型的最大缺点就是要把消息重复很多份,通过牺牲空间来换取了每个人拉取群消息的效率。

好多年前我们刚开始做群时,也是采用了的写扩散模型,后来因为存储压力太大,一度又改成了读扩散模型。在读扩散模型下,群消息只存一份,记录每个群成员读取群消息的偏移量(消息索引号,单调增长)。之所以存储压力大在于当时公司还没有一个统一的存储组件,我们直接采用的 Redis 的内存存储,当时原生的 Redis 在横向和纵向上的扩展性上都比较受限。这在当时属于两害相权取其轻,选择了一个对我们研发团队来说成本更低的方案。

再后来公司有了扩展性和性能都比较好的统一存储组件后,实际再换回写扩散模型则更好。毕竟读扩散模型逻辑比较复杂,考虑自己不知道加了多少个群了,每次打开应用都要检查每个群是否有消息,性能开销是呈线程递增的。唯一的问题是,写好、测好、上线运行稳定几年的程序,谁也不想再去换了对吧,每一次的技术升级和架构优化其实是需要一个契机的。

另外一个是所有分布式后台系统都有的共性问题 —— 性能问题。只要你的用户量到了一定规模,比如 100 万,以后每上一个量级,对技术支撑的挑战实际上并不是呈线性的。微信春晚红包的案例(参考[2])给出了一个很好的参考和启发,因为市面上几乎很少有系统能到这个量级了。

微信 2015 年春节的红包峰值请求是 1400 万每秒,而微信后台其实也采用了微服务的架构,其拆分原则如下(参考[1]):

实现不同业务功能的 CGI 被拆到不同 Logicsrv,同一功能但是重要程度不一样的也进行拆分。例如,作为核心功能的消息收发逻辑,就被拆为 3 个服务模块:消息同步、发文本和语音消息、发图片和视频消息。

服务拆散了,在自动化基础设施的辅助下,运维效率下降不大,而开发协作效率会提升很多,但性能会下降。那么在面对微信春晚红包这样的极端性能场景下,该如何应对?在电商里,正常下单和秒杀下单多是分离的两套系统来支撑,秒杀专为性能优化,简化了很多正常流程,而且秒杀本身需要支持的 sku 不多,所以它具备简化的基础。而微信给出的方案中实际也是类似的思路,但它有个特殊点在于,能把拆散的服务为了性能又合并回去。

在如此海量请求之下,在这个分布式系统中,任何一点网络或服务的波动都可能是灾难性的。最终我们选择把摇一摇服务去掉,把一千万每秒的请求干掉了,把这个服务挪入到接入服务。但这样做,有一个前提:不能降低接入服务的稳定性。因为不单是春晚摇一摇请求,微信消息收发等基础功能的请求也需要通过接入服务来中转,假如嵌入的摇一摇逻辑把接入服务拖垮,将得不偿失。

这里面的黑科技在于 C++ 技术栈的优势,同一台接入服务器上实际由不同的进程来处理不同的功能,达到了隔离的效果。而不同进程间又可以通过共享内存来通信,这比用 Socket 网络通信高效多了,又有效的规避了网络层带来的波动性影响,这是我们用 Java 做后台没法做到的事。

切磋,你不能看见别人的功夫套路好,破解难题手到擒来,就轻易决定改练别人的功夫。表面的招式相同,内功可能完全不同,就像金庸小说里的鸠摩智非要用小无相功催动少林七十二绝技,最后弄的自废武功的结局。切磋主要是带给你不同的思维方式,用自己的功夫寻求破解之道。

连结与有效提取

如何选择干货,我在前文《技术干货的选择性问题》中最后给出的结论是,给自己结一张网,形成知识体系。暂时离你的网太远的技术潮流性的东西,可以暂不考虑,结合功利性和兴趣原则去不断编织和扩大自己的技术之网。在编织了一些新结点入网后,就需要进一步有效提取这些结点的价值。

刚做 IM 时,曾经有个疑惑,就是 IM 的长连接接入系统,到底单机接入多少长连接算合适的?很早时运维对于长连接有个报警指标是单机 1 万,但当时我用 Java NIO 开 2G 最大堆内存,在可接受的 GC 停顿下,在一台 4 核物理机上测试极限支撑 10 万长连接是可用的。那么平时保守点,使用测试容量的一半 5 万应该是可以的。

之后一次机会去拜访了当时阿里旺旺的后端负责人,我们也讨论到了这个长连接的数量问题。当时淘宝有 600 万卖家同时在线,另外大概还有 600 万买家实时在线。所以同时大概有 1200 万用户在线,而当时他们后端的接入服务器有 400 台,也就是每台保持 3 万连接。他说,这不是一个技术限制,而是业务限制。因为单机故障率高,一旦机器挂了,上面的所有用户会短暂掉线并重连。若一次性掉线用户数太多,恢复时间会加长,这会对淘宝的订单交易成交产生明显的影响。

他还说了一次事故,整个机房故障,导致单机房 600 万用户同时掉线。整个故障和自动切换恢复时间持续了数十分钟,在此期间淘宝交易额也同比下降了约 40% 左右。因为这种旺旺在线和交易的高度相关性,所以才限制了单机长连接的数量,而当时已经有百万级的单机长连接实验证明是可行的。

在微信春晚红包的那篇文章里提到:

在上海跟深圳两地建立了十八个接入集群,每个城市有三网的接入,总共部署了 638 台接入服务器,可以支持同时 14.6 亿的在线。

简单算一下,大概就是 228.8 万单机长连接的容量规划,14.6 亿怕是以当时全国人口作为预估上限了。实际当然没有那么多,但估计单机百万长连接左右应该是有的。这是一个相当不错的数量了,而采用 Java 技术栈要实现这个单机数量,恐怕也需要多进程,不然大堆的 GC 停顿就是一个不可接受和需要单独调优的工作了。

连结,便是这样一个针对同一个问题或场景,将你已知的部分连结上新的知识和实践,形成更大的网,再去探索更多的未知。

...

如何去吸收和消化信息,这是一个智者见智的事情,但在信息爆炸的时代都在忙于过滤和收集信息,却从不分配点时间去处理和提炼信息,也许你已经忘记了收集的初心了。


最后,是有关微信后台技术的一些参考文章, 有些在本文中引用了,有些没引用,但都值得一看。

参考与文后阅读

[1] 张文瑞. 从0到1:微信后台系统的演进之路. 2016.01
[2] 张文瑞. 100亿次的挑战:如何实现一个“有把握”的春晚摇一摇系统. 2016.12
[3] 陈明. 微信朋友圈技术之道:三个人的后台团队与每日十亿的发布量. 2015.12
[4] 曾钦松. 万亿级调用系统:微信序列号生成器架构设计及演变. 2016.06

转载自:https://www.cnblogs.com/mindwind/p/6417158.html

微信后台技术“干货们”带来的启发相关推荐

  1. 微信后台基于时间序的新一代海量数据存储架构的设计实践

    本文作者腾讯WXG后台开发工程师jeryyzhang,收录时有改动,感谢原作者的分享. 1.引言 大约3年前,微信技术团队分享了<微信后台基于时间序的海量数据冷热分级架构设计实践>一文,文 ...

  2. 微信团队分享:微信后台在海量并发请求下是如何做到不崩溃的

    本文引用了文章"月活 12.8 亿的微信是如何防止崩溃的?"和论文"Overload Control for Scaling WeChat Microservices&q ...

  3. 微信团队分享:Kotlin渐被认可,Android版微信的技术尝鲜之旅

    本文由微信开发团队工程是由"oneliang"原创发表于WeMobileDev公众号,内容稍有改动. 1.引言 Kotlin 是一个用于现代多平台应用的静态编程语言,由 JetBr ...

  4. 【西安电子科技大学】CSDN高校俱乐部第一次讲座——微信后台开发

    2013年11月6日晚,俱乐部在西电B楼203举办了关于微信后台开发的讲座.七点左右,各位微信技术爱好者欢聚一堂,讲座也拉开了序幕. 会议首先由俱乐部主席倪天成上台发言,他言简意赅的介绍了当今微信公共 ...

  5. 微信后台架构浅析--读写扩散技术

    首先我写这篇博客所要探讨的问题是什么,自己查询资料得出的结论或者理解记录下来,产生了这篇博客 问题背景: 我相信现在几乎我们每个人都在使用微信,那么你知道微信平台每天的信息量有多大吗?2017年微信官 ...

  6. 消息推送技术干货:美团实时消息推送服务的技术演进之路

    本文由美团技术团队分享,作者"健午.佳猛.陆凯.冯江",原题"美团终端消息投递服务Pike的演进之路",有修订. 1.引言 传统意义上来说,实时消息推送通常都是 ...

  7. 一套亿级用户的IM架构技术干货(上篇):整体架构、服务拆分等

    1.引言 经历过稍有些规模的IM系统开发的同行们都有体会,要想实现大规模并发IM(比如亿级用户和数十亿日消息量这样的规模),在架构设计上需要一些额外的考虑,尤其是要解决用户高并发.服务高可用,架构和实 ...

  8. 10年前腾讯微信后台第一天提交的代码曝光!

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:硬刚一周,3W字总结,一年的经验告诉你如何准备校招! 个人原创100W+访问量博客:点击前往,查看更多 编辑:卫 ...

  9. 【技术干货】跨境茶话会第4期丨响应式编程的应用

    大师兄说 许多场景下为了更迅速的响应客户端的请求,将问题转化为实时反映业务状态的变化,能更好地提升用户体验以及支撑更大量的用户请求,于是催生了响应式编程,本期跨境茶话会仍旧邀请了中美两地的相关专家来谈 ...

最新文章

  1. 太酷了,Python 制作足球可视化图表 | 代码干货
  2. java 泛型 get()_Java泛型,get类的泛型参数
  3. java 注解学习_java注解的学习
  4. Android编译小结(新建android项目)
  5. 熟悉常用的Linux命令操作
  6. Redis 过期键删除策略
  7. Nacos源码NacosAutoServiceRegistration
  8. 红帽7 -本地yum配置
  9. Sersync+Rsync 增量实时同步
  10. 机器学习知识总结系列- 特征工程(1-1)
  11. elinks文字浏览器
  12. 互联网短平快下,DevCloud如何支撑软件开发的“转型”?
  13. Android系统(187)---最易懂的Activity启动模式详解
  14. 【Hoxton.SR1版本】Spring Cloud Gateway之Predicate详解
  15. 微信小程序:人生重开模拟器
  16. 漫步者蓝牙只有一边有声音_为什么我蓝牙耳机只有一边有声音啊.
  17. 知识库构建前沿:自动和半自动知识提取
  18. 【笔记整理】通信原理第九章复习——线性分组码
  19. 非真实感渲染(NPR)论文理解及其复现(Unity) - 《Stylized Highlights for Cartoon Rendering and Animation》
  20. 物联网服务商店 - Nebula浅谈

热门文章

  1. 桌面终端管理软件的必要性
  2. 国产数据库40年大盘点,愿这盛世如您所愿!
  3. Oracle对空值(NULL)的5种处理
  4. python面试大全
  5. 14天阅读挑战赛(神奇的兔子数列)
  6. LoRaWAN学习心得
  7. 收藏古币 - 计蒜客
  8. 掌握这2个小技巧,让你轻松学会手机拍照计算数量
  9. JAVA多线程抽奖程序
  10. 关羽张飞的武功是怎么来的?