Jack Jiang

我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
posts - 189, comments - 13, trackbacks - 0, articles - 0

2018年10月15日

本文在编写时参考了博客作者“鹿呦呦”和在线课程“即时消息技术剖析与实战”的相关资料,一并表示感谢。

1、系列文章引言

IM系统看似简单(没错,很多土老板认为开发个qq和微信也就是几万块钱的事... ),实责是众多技术的应用合体,包括网络编程、移动开发、后端开发、高并发、高可用、高安全等技术范畴,再加上多端使用不同的编程语言,想要凑齐一个典型的IM产品技术栈那也不是个容易事。

而对于IM开发入门者来说,想要在众多的IM技术术语和概念中找到学习的方向和需要的资料,那也是件很让人抓狂的事。如果看到不该看的技术深水区文章,直接从入门到放弃——被活活吓退,那也是相当悲剧的。

本系列文章将尽量从理论概念入手,通俗易懂的梳理IM中的基础技术概念和热门技术点,希望能帮你理清看似一团乱麻的IM知识体系,助你找到清晰的IM技术学习方向,来日工资翻倍、迎娶白富美也未必不可能!

 

友情提示:本系列文章侧重于理论概念的讲述,篇幅有限,点到即止,如需系统、深入、具体地学习IM技术的方方面面,请从此文入手:《新手入门一篇就够:从零开发移动端IM》(史诗级文章,适合从入门到放弃)。

学习交流:

- 即时通讯/推送技术开发交流5群:215477170[推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

2、系列文章目录

IM开发快速入门(一):什么是IM系统?》(* 本文

《IM开发快速入门(二):什么是IM系统的实时性? (稍后发布)》

《IM开发快速入门(三):什么是IM系统的可靠性? (稍后发布)》

《IM开发快速入门(四):什么是IM系统的一致性? (稍后发布)》

《IM开发快速入门(五):什么是IM系统的安全性? (稍后发布)》

《IM开发快速入门(六):什么是IM系统的的心跳机制? (稍后发布)》

《IM开发快速入门(七):如何理解并实现IM系统消息未读数? (稍后发布)》

《IM开发快速入门(八):如何理解并实现IM系统的多端消息漫游? (稍后发布)》

3、本文内容概述

本文将带你快速了解一个主流IM系统的应用场景、典型架构、技术特点和功能组成,帮你快速建立对IM系统的主观认知。

如果你不想从技术的角度理解IM原理,可以尝试阅读此文:《知识科普:IM聊天应用是如何将消息发送给对方的?(非技术篇)》。

本文已收入即时通讯网的入门纲领性文章《新手入门一篇就够:从零开发移动端IM》。

本文已同步发布于“即时通讯技术圈”公众号,欢迎关注:

▲ 本文在公众号上的链接是:https://mp.weixin.qq.com/s/h7L4UGHRl7qI1bi8WyZ5iw,原文链接是:http://www.52im.net/thread-3065-1-1.html

4、IM的应用场景

IM其实并不局限于聊天、社交这类“典型”应用中,实际上它已经广泛运用于我们身边形形色色的软件中。

聊天、直播、在线客服、物联网等所有需要实时互动、高实时性的场景等等,都需要应用到 IM 技术。

下面这些场景是我们大家都熟悉的,都用到了IM技术:

  • 1)微信、qq、钉钉等主流IM应用:这是IM技术的典型应用场景;
  • 2)微博、知乎等社区应用:它们利用IM技术实现了用户私信等点对点聊天;
  • 3)抖音、快手等直播/短视频应用:它们利用IM技术实现了与主播的实时互动;
  • 4)米家等智能家居物联网应用:利用IM技术实现实时控制、远程监控等;
  • 5)滴滴、Uber等共享家通类应用:利用IM技术实现位置共享;
  • 6)在线教育类应用:利用IM技术实现在线白板。 

5、IM的典型架构

一个典型的IM架构类似于下图这样:

本图引用自《即时消息技术剖析与实战》学习笔记1——IM系统的架构》一文

如上图所示,IM架构中的各分层职责如下:

  • 1)客户端:作为与服务端进行消息收发通信的终端;
  • 2)接入层:也叫网关层,为客户端收发消息提供入口;
  • 3)逻辑层:负责IM系统各功能的核心逻辑实现;
  • 4)存储层:负责IM系统相关数据的持久化存储,包括消息内容、账号信息、社交关系链等;
  • 5)第三方服务:保证APP在未打开或后台运行时也能收到消息通知(这主要是第第3方消息推送服务)。

尤其对于“接入层”,它的职责最为关键,具体是:

  • 1)保持海量用户连接;
  • 2)解析协议,对传输内容进行编解码;
  • 3)维护客户端的连接(也叫“Session”);
  • 4)推送消息。

以下文章适合IM架构设计入门,有兴趣可以读一读:

6、IM技术的特点

IM技术的特点主要就是以下4点: 

▶ 1)实时性:

对于IM系统,“实时”二字是精髓,也是这项技术存在关键意义所在。它保证的是消息的实时触达。

举个例子:如果跟你的好友微信或qq聊天,我发的消息他不能即时收到,或者他发的信息你也不知道什么时候能收到,这基本上也就没法聊下去了(干吗不痛快打个电话呢)。

▶ 2)可靠性:

保证消息的不丢失和不重复,是IM系统的另一个关键技术特点。试想,当你在用qq或微信跟女朋友聊天,好不容易鼓起勇气向“她”表白,结果这消息要是丢包了,那肯定得卸载应用了,搞不好砸手机都有可能。当然,好话不说二遍,消息重复也同样恼人。

以下文章对消息的不丢/不重问题进行了深入探讨,有兴趣可以详读:

▶ 3)一致性:

对于单聊消息而言,保证同一个设备的时间顺序、不同设备的漫游同步,也是相当重要的一环。

IM系统中的消息交互,就到底就是人跟人在“说话”,前言不搭理后言、或者胡言乱语式的消息展现,那不是人疯了就是程序疯了,总之就是没法再聊下去了。

以下文章对消息时序问题进行了深入探讨,有兴趣可以详读:

▶ 4)安全性:

保证数据传输安全、数据存储安全、消息内容安全,也是IM系统必不可少的特性。尤其在私聊场景下,如果不能做到安全性,聊天的体验跟被人偷窥的感觉是没有区别的。

以下文章对IM的安全问题进行了深入探讨,有兴趣可以详读:

7、IM的功能组成

浅显的角度讲,一个典型的IM功能组成,无非就是以下5样:

  • 1)联系人列表;
  • 2)聊天界面;
  • 3)消息发送通道;
  • 4)消息接收通道;
  • 5)消息存储;
  • 6)消息未读数。

我们一样一样来说说各自的用途。

▶ 1)联系人列表:

这个很好理解,使用IM系统的第一步,就是要解决“跟谁聊”的问题。从功能表象上来说,联系人列表也就是社交关系列表,无非就是个信息列表界面,有什么特殊的地方?

联系人列表看似简单,实际上它是一系列IM系统的社交关系确立动作的结果体现。

要想建立联系人列表,你可能需要实现以下逻辑:

  • 1)怎么能找到想要聊天的人?(需要实现随机查找?精确查找?)
  • 2)怎么决定要不要跟这个人聊?(需要实现对方的个人信息查看)
  • 3)开始发出好友请求;
  • 4)被请求的一方,还可以决定是“同意”还是“拒绝”(“同意”该怎么处理?“拒绝”又该怎么处理?)。

总的来说,联系人列表的建立,是一个IM系统聊天关系确立的表现,不可或缺。

▶ 2)聊天界面: 

聊天界面看似很平常,实际它就是IM系统客户端的核心功能所在,所有主要的IM功能都是通过它展现。

它应该具备的能力有:

  • 1)各种聊天功能按钮:语音留言、图片、文字、表情、文件、实时电话、实时视频等;
  • 2)各种聊天消息显示:各种消息都有不同的UI显示元素和处理逻辑;
  • 3)流畅的使用体验:大量不同类型的消息显示时,不能卡顿;
  • 4)即时显示聊天消息:网络线程收到的消息,要马上在UI上显示出来;
  • 5)历史消息的加载:上次聊过的内容也得显示出来吧。

以上只是简单罗列,这看似简单的聊天界面,能把上面列表的事情做好,工作量也不小吧。

▶ 3)消息发送通道:

下图是一个典型的IM消息收发通道示意: 

如上图所示,消息发送通道这个比较好懂,最浅显易懂的理解就是用tcp或udp,建立socket长连接,需要发消息的时候,wirte一下就过去了,好简单!

但,事情往往不是想象的这么简单:

  • 1)如何保证这条socket长连接时一直处于可用的状态?
  • 2)当socket长连接不可用时,用户此时发送的消息该怎么处理?
  • 3)怎么保证发送的消息不丢?
  • 4)怎么保证发送的消息不复重?
  • 5)怎么保证发送的消息乱序?
  • 6)当对方不在线时,发送的消息去哪了?
  • 7)发送的消息,能保证实时送到?

这么一说,事情还挺多(那不废话吗。。。)。

▶ 4)消息接收通道:

正如上节中的消息收发通道示意图所示,消息接收通道也很好理解,对方通过消息发送通道write的消息,我得收到并显示啊。

要实现一个可靠的消息接收通道,也并非易事:

  • 1)如何保证socket长连接通道能随时处于良好的边接状态(随时接收对方write的消息);
  • 2)当socket长连接断开时,对方发送消息该怎么实现?
  • 3)当socket恢复连接时,怎么恢复之前的聊天现场?
  • 4)当我收到对方的消息时,对方怎么知道我已经收到了?
  • 5)当重复收到对方的消息时,该怎么处理?
  • 6)当收到的消息时序有错乱,该怎么处理?

▶ 5)消息存储:

消息存储这个功能好理解,聊天的消息如果存储,下次再聊的时候就不知道之前聊过什么,做不到这一点,这个IM系统的聊天体验好不起来。

那么,哪些情况下需要进行消息存储呢:

  • 1)对方不在线时:聊天消息应该存储(这叫离线消息存储);
  • 2)对方在线时:聊天消息也要存到本地存储(这叫消息缓存);
  • 3)对方在线或不在线时:聊天消息都要存到服务端(用于实现多设备的消息漫游和同步)。

具体要存储的内容和时机也就上面这几样。

但技术落到实处,要做的事情同样少不了:

  • 1)离线消息该怎么多久?
  • 2)图片、短视频、大文件这类的离线消息,多媒体文件该怎么存(有可能量会很大)?
  • 3)当本地的消息积累太多时,怎么能保证本地存储的性能?
  • 4)当应用更新、升级或异常时,怎么能保证本地存储的完整性(不被破坏)?
  • 5)怎么能保证多设备消息能不丢、不重、不乱?

这么多需要考虑的内容,也挺让人抓狂。

下图是一个IM系统的典型存储架构设计,了解一下:

本图引用自《现代IM系统中聊天消息的同步和存储方案探讨》一文

存储是IM系统的基石,以下文章可以深入阅读:

▶ 6)消息未读数:

消息未读数?看起来也就是那个所有IM应用都有的未读小红点嘛。是的,看起来也好简单!

然而,消息未读数功能的实现也一样不简单:

  • 1)未读数是客户端实现还是服务端实现?
  • 2)会话未读和总未读怎么保持一致?
  • 3)多终端情况下,怎么保证未读数的一致性(我在这台设备上读没读,那台设备怎么知道的?)?

是的,看起来就这么简简单单的3件事,但深入思考一下,还真的简单不起来。

8、本文小结

IM系统的应用场景已经不单单是IM聊天应用这一种形态,它已经融入到互联网应用的方方面面,必竟谁都想自已的应用具备“实时”交互这种能力,因为体验太好了。

IM系统典型架构无非就是网络接入层、业务逻辑层、数据存储层,除开网络接入层,其它各层其实跟普通的应用系统看起来差别并不是太大。

IM系统的技术特点来说,就是实时性、可靠性、一致性、安全性,除了实时性对于多数应用来说并不关心,其它的指标也很好理解。

IM系统的功能组成上,联系人列表用于数据模型的建立、聊天界面承载了IM系统的终端展现、消息的收发通道用于实现“实时”这个特性、存储和未读数看似不是必须但用户体验上确必不可少。

附录:更多IM开发资料汇总

[1] 有关IM架构设计的文章:

浅谈IM系统的架构设计

简述移动端IM开发的那些坑:架构设计、通信协议和客户端

一套海量在线用户的移动端IM架构设计实践分享(含详细图文)

一套原创分布式即时通讯(IM)系统理论架构方案

从零到卓越:京东客服即时通讯系统的技术架构演进历程

蘑菇街即时通讯/IM服务器开发之架构选择

腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT

微信后台基于时间序的海量数据冷热分级架构设计实践

微信技术总监谈架构:微信之道——大道至简(演讲全文)

如何解读《微信技术总监谈架构:微信之道——大道至简》

快速裂变:见证微信强大后台架构从0到1的演进历程(一)

17年的实践:腾讯海量产品的技术方法论

移动端IM中大规模群消息的推送如何保证效率、实时性?

现代IM系统中聊天消息的同步和存储方案探讨

WhatsApp技术实践分享:32人工程团队创造的技术神话

微信朋友圈千亿访问量背后的技术挑战和实践总结

王者荣耀2亿用户量的背后:产品定位、技术架构、网络方案等

IM系统的MQ消息中间件选型:Kafka还是RabbitMQ?

腾讯资深架构师干货总结:一文读懂大型分布式系统设计的方方面面

以微博类应用场景为例,总结海量社交系统的架构设计步骤

快速理解高性能HTTP服务端的负载均衡技术原理

子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践

IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列

微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)

微信技术分享:微信的海量IM聊天消息序列号生成实践(容灾方案篇)

新手入门:零基础理解大型分布式架构的演进历史、技术原理、最佳实践

一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践

社交软件红包技术解密(一):全面解密QQ红包技术方案——架构、技术实现等

社交软件红包技术解密(二):解密微信摇一摇红包从0到1的技术演进

社交软件红包技术解密(三):微信摇一摇红包雨背后的技术细节

社交软件红包技术解密(四):微信红包系统是如何应对高并发的

社交软件红包技术解密(五):微信红包系统是如何实现高可用性的

社交软件红包技术解密(六):微信红包系统的存储层架构演进实践

社交软件红包技术解密(七):支付宝红包的海量高并发技术实践

社交软件红包技术解密(八):全面解密微博红包技术方案

社交软件红包技术解密(九):谈谈手Q红包的功能逻辑、容灾、运维、架构等

社交软件红包技术解密(十):手Q客户端针对2020年春节红包的技术实践

从游击队到正规军(一):马蜂窝旅游网的IM系统架构演进之路

从游击队到正规军(二):马蜂窝旅游网的IM客户端架构演进和实践总结

IM开发基础知识补课(六):数据库用NoSQL还是SQL?读这篇就够了!

瓜子IM智能客服系统的数据架构设计(整理自现场演讲,有配套PPT)

阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处

从游击队到正规军(三):基于Go的马蜂窝旅游网分布式IM系统技术实践

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

IM开发基础知识补课(九):想开发IM集群?先搞懂什么是RPC!

>> 更多同类文章 ……

[2] IM开发热门综合文章:

新手入门一篇就够:从零开发移动端IM

移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”

移动端IM开发者必读(二):史上最全移动弱网络优化方法总结

从客户端的角度来谈谈移动端IM的消息可靠性和送达机制

IM开发基础知识补课:正确理解前置HTTP SSO单点登录接口的原理

移动端IM中大规模群消息的推送如何保证效率、实时性?

移动端IM开发需要面对的技术问题

开发IM是自己设计协议用字节流好还是字符流好?

请问有人知道语音留言聊天的主流实现方式吗?

IM消息送达保证机制实现(一):保证在线实时消息的可靠投递

IM消息送达保证机制实现(二):保证离线消息的可靠投递

如何保证IM实时消息的“时序性”与“一致性”?

一个低成本确保IM消息时序的方法探讨

IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?

IM群聊消息如此复杂,如何保证不丢不重?

谈谈移动端 IM 开发中登录请求的优化

移动端IM登录时拉取数据如何作到省流量?

浅谈移动端IM的多点登录和消息漫游原理

完全自已开发的IM该如何设计“失败重试”机制?

通俗易懂:基于集群的移动端IM接入层负载均衡方案分享

微信对网络影响的技术试验及分析(论文全文)

即时通讯系统的原理、技术和应用(技术论文)

开源IM工程“蘑菇街TeamTalk”的现状:一场有始无终的开源秀

如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源

全面掌握移动端主流图片格式的特点、性能、调优等

子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践

IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列

微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)

自已开发IM有那么难吗?手把手教你自撸一个Andriod版简易IM (有源码)

融云技术分享:解密融云IM产品的聊天消息ID生成策略

IM开发基础知识补课(六):数据库用NoSQL还是SQL?读这篇就够了!

适合新手:从零开发一个IM服务端(基于Netty,有完整源码)

拿起键盘就是干:跟我一起徒手开发一套分布式IM系统

适合新手:手把手教你用Go快速搭建高性能、可扩展的IM系统(有源码)

IM里“附近的人”功能实现原理是什么?如何高效率地实现它?

IM要做手机扫码登录?先看看微信的扫码登录功能技术原理

IM消息ID技术专题(一):微信的海量IM聊天消息序列号生成实践(算法原理篇)

IM消息ID技术专题(二):微信的海量IM聊天消息序列号生成实践(容灾方案篇)

IM消息ID技术专题(三):解密融云IM产品的聊天消息ID生成策略

IM消息ID技术专题(四):深度解密美团的分布式ID生成算法

IM消息ID技术专题(五):开源分布式ID生成器UidGenerator的技术实现

IM开发宝典:史上最全,微信各种功能参数和逻辑规则资料汇总

IM开发干货分享:我是如何解决大量离线消息导致客户端卡顿的

IM开发快速入门(一):什么是IM系统?

>> 更多同类文章 ……

(本文同步发布于:http://www.52im.net/thread-3065-1-1.html

posted @ 2020-07-09 14:16 Jack Jiang 阅读(30) | 评论 (0)编辑 收藏

1、引言

IM系统中,特别是在企业应用场景下,消息的已读未读状态是一个强需求。

以阿里的钉钉为例,钉钉的产品定位是用于商务交流,其“强制已读回执”功能,让职场人无法再“假装不在线”、“假装没收到”。更有甚者,钉钉的群聊“强制已读回执”功能,甚至能够知道谁读了消息,谁没有读消息(老板的福音啊)。

 

▲ 钉钉里的群聊消息已读未读功能效果

功能看起来很酷,但用起来是一言难尽(上班族心里苦.... )。实际上,技术实现也并不容易。

那么,对于已读未读状态:

  • 1)如果是私聊:消息的阅读状态比较容易实现,在性能和存储上也不存在问题;
  • 2)如果是群聊:考虑到存储和处理性能,特别当处于一个云环境时,如何高效地处理群聊的已读未读状态是一个非常值得探讨的话题。

这里提到的“高效”含3个方面:

  • 1)存储空间;
  • 2)处理速度;
  • 3)传输字节数。

本文将从服务端的角度来探讨已读未读状态,在具体的技术实现上对于存储空间占用方面的思路差异。能力有限,权当个人笔记,欢迎交流。

学习交流:

- 即时通讯/推送技术开发交流5群:215477170[推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

本文已同步发布于“即时通讯技术圈”公众号,欢迎关注:

▲ 本文在公众号上的链接是:https://mp.weixin.qq.com/s/yUkKPOBsdqLlxiFrGmwFRQ,原文链接是:http://www.52im.net/thread-3054-1-1.html

2、内容点评

在收录本文前,Jack Jiang建议原作者对某些具体的技术点进行更深入的分享,但因作者工作较忙,本文中的某些关键技术点未来的及作进一步展开。

所以,本文可以作为IM聊天消息(主要是群聊)中已读未读功能的基本实现思路方面的参考,但不建议盲目迷信文中的结论或方案,避免被一些不够具体的技术指标而误导。

3、相关文章

如果你还想了解更多有关IM群聊中已读未读功能的实现逻辑,可以进一步阅读干货文章《IM群聊消息的已读回执功能该怎么实现?》(强烈推荐)。

如果你对IM中的已读未读功能有产品方面的痛点困惑,可以参考一下微信对已读未读功能的设计定位,详见《IM热门功能思考:为什么微信里没有消息“已读”功能?》。

更多IM群聊技术方面的文章详见文本附录部分。

4、已读未读状态交互流程

发送者发送的IM聊天消息,在接收者阅读消息后,是否要求阅读者通知已读,可能是由系统配置、组织配置、群组配置等决定,也可能由发送者根据业务需求决定。以下的讨论,均假设消息需要已读未读状态。

客户端与服务端之间,关于阅读状态的命令只需3个,每个命令含请求和应答。

4.1 通知消息已读(私聊、群聊通用)

当小宝阅读了一条或若干条消息,需向服务端发送消息已读通知:“众爱卿发的x+y+z消息,朕已阅”。

服务端收到小宝的已读通知时,需完成以下事项:

  • 1)存储消息的已读状态;
  • 2)返回应答给小宝;
  • 3)向已读列表的消息的原始发送者通知消息已读。

对于第“3)”步:

  • 1)私聊的场合,比较好理解,就是发送给私聊的对方;
  • 2)群聊的场合,可很不一样:因为小宝发送的已读消息列表,可能是由众爱卿发送的。考虑这种假设:张三、李四、王五发出的群聊消息,被小宝一下都阅读了,那么小宝发出的已读通知包含的消息列表,需要被IMS分解成3个已读通知(3个不同的消息列表),分别通知给张三、李四、王五,通知内容是“爱卿(不含'"众")发的这些消息,朕已阅”。

下面是大致的逻辑流程图: 

4.2 查询消息的未读人数(私聊、群聊通用)

消息的发送者,加载消息列表到聊天窗口时,可能需要展示消息是否被已读。

对群聊而言,显示的信息可能是n人未读的提示,那么需要向服务端查询消息的未读人数,由于客户端可能在UI显示自己发出的多条消息,需支持一次请求查询多条消息。

以未读人数的方式来表示消息的阅读状态,统一了私聊、群聊的查询,使得客户端-服务端间的接口更简单,同时使客户端的实现逻辑更统一。

就像下面这样:

  • 1)对于私聊:如果未读人数n>0,表示消息未读;
  • 2)对于群聊:直接显示n人未读即可,当然,当n等于0时表示全部已读。

4.3 查询群消息的已读、未读人员清单(群聊)

当客户端希望显示某一条群聊消息的已读、未读人员列表,需向服务端发起查询。

大致的逻辑流程图如下:

5、几种具体的已读未读状态存储思路探讨

5.1 基本约定

群聊的阅读状态比私聊复杂,因此这里着重讨论群聊的阅读状态。

假设群成员数是n,各个客户端立即IM服务端发送已读通知。服务端需存储每个人的阅读状态,包括那些未读的成员。由于群的成员清单可能变化,比如今天增加了一个成员,则昨天发的消息、与今天发的消息,其接收者列表不一样。

即:

  • 1)同一个群的不同消息,对应的接收者列表可能不一样。
  • 2)换言之,每一条消息都需要记录完整的接收者列表和已读人员列表。

为了方便讨论,本章假设群成员有640人为前提。

5.2 存储思路1

每一条消息都维护:

  • 1)接收人员列表receiver_list;
  • 2)已读人员列表read_list。

具体是:

  • 1)IM Server收到一条消息时,用全体群成员构建receiver_list;
  • 2)IM Server收到群成员对这条消息的已读通知时,将此成员加入到read_list。

客户端获取此消息的数据:

  • 1)当需要获取未读人数时,用receiver_list的个数减去read_list的个数;
  • 2)当需要获取已读、未读人员列表时,需用receiver_list减去read_list得到未读人员列表。

那么,思路1每条消息的存储空间是:

640个ID + 不定数量的已读人员ID

5.3 存储思路2

每一条消息维护:

  • 1)未读人员列表unread_list;
  • 2)已读人员列表read_list。

具体是:

  • 1)IM Server收到一条消息时,用全体群成员构建unread_list;
  • 2)IM Server收到群成员对这条消息的已读通知时,将此成员从unread_list移出,同时加入到read_list。

客户端获取此消息的数据:

  • 1)当需要获取未读人数时,直接计算unread_list的个数;
  • 2)当需要获取已读、未读人员列表时,直接返回unread_list和read_list。

那么,思路2每条消息的存储空间是:

未读人员ID + 已读人员ID,合计640个ID

思路2的实现,占用的空间是案1的0.5倍~1.0倍。即案2占用的空间少,但在每次收到客户端的已读通知时,比案1多了一个操作:从unread_list进行减员。

5.4 存储思路3(我的实现)

5.4.1)探讨5.2节、5.3节的不足:

5.2节、5.3节这两种思路,都能满足功能需求,但存在巨大的存储浪费。

该群有640人,如果群内聊天每天有1024条消息,人员ID以4字节存储计算,那么为该群每天的消息阅读状态需要消耗的空间是:

5.2节思路1:1024 * (640 * 4 + 已读人数 * 4),范围是 2.5MB ~ 5MB;

5.3节思路2:1024 * 640 * 4,等于2.5MB。

这仅仅是一个群在一天之内产生的阅读状态数据,如果是在云平台运行,单此功能消耗的空间,呵呵~~

题外话:如果成员不是用4字节整型存储,而改用字符串,比如"1123356777",那就更可观了。

5.4.2)如何减少存储空间:

考虑群成员并非时时刻刻都在变化,多数情况下,群成员的列表是相对稳定的,今天的和上周(甚至更久以前)的列表甚至可能是一样的,那么有可能几百条消息,甚至几万条消息对应的群成员列表是相同的。

因此,引出本文的重点思想:

考虑让不同的消息共用群成员列表,即把消息的阅读状态与群成员列表分开存储,并记录它们之间的关联。

假定平均每1024条消息共用一个群成员列表,发了1024条消息后,群成员变化了,此后需要用新的群成员列表。

那么这一千条消息的阅读状态所占用的空间是:

群成员列表空间 + 1024条消息的阅读状态:640 * 4 + 1024 * 每条消息的阅读状态所占空间

在具备群成员列表的前提下,如何减少每条消息的阅读状态所占空间?

很自然会想到用bit来表示已读人员,因为一个32位整型可表示32个人的已读状态。bit的顺序只需与群成员列表的顺序一致即可。

当一条消息没有人已读时,阅读状态占用0字节;当群内每个人都阅读时,占用的空间最大,即640 / 32 = 20字节。

因此优化之后,这一千条消息的阅读状态所占用的空间,范围是2.5KB ~ (2.5KB + 1024 * 20B),即2.5KB ~ 22.5KB,此数值与5.2节思路1、5.3节思路2对比,有了极大幅度地下降。

如下图所示:

该表格的前提条件:

  • 1)一个群有640人;
  • 2)该群连续1024条消息对应的群成员列表是稳定的。

退一步考虑,哪怕这1024条消息对应的群成员列表不稳定,中间变化了10次,那么也仅会多出2.5KB * 10即25KB的存储空间,与案1、案2相比仍然有极大优势。

6、如何提高已读未读状态的处理速度

小宝往公司群发了一条消息我来给大家介绍一下新来的女同事,大家立即、马上、瞬间、闪电般地查看消息,感觉迟1秒就会失去秒杀女神的机会一样,意味着一瞬间会有N多条已读通知发送到IMS。

对这些消息的处理流程是一样的:

  • 1)可合并这些操作以批量形式进行存储、转发;
  • 2)由于存储消息的阅读状态是一个设置bit的过程,所以不存在互斥的问题,即使在分布式环境也可以放心操作;
  • 3)消息对应的成员列表信息可临时缓存在内存对象内,以减少查询IO,提高效率。

附录:更多IM群聊技术文章

快速裂变:见证微信强大后台架构从0到1的演进历程(一)

如何保证IM实时消息的“时序性”与“一致性”?

IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?

IM群聊消息如此复杂,如何保证不丢不重?

微信后台团队:微信后台异步消息队列的优化升级实践分享

移动端IM中大规模群消息的推送如何保证效率、实时性?

现代IM系统中聊天消息的同步和存储方案探讨

关于IM即时通讯群聊消息的乱序问题讨论

IM群聊消息的已读回执功能该怎么实现?

IM群聊消息究竟是存1份(即扩散读)还是存多份(即扩散写)?

一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践

[技术脑洞] 如果把14亿中国人拉到一个微信群里技术上能实现吗?

IM群聊机制,除了循环去发消息还有什么方式?如何优化?

网易云信技术分享:IM中的万人群聊技术方案实践总结

阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处

IM群聊消息的已读未读功能在存储空间方面的实现思路探讨

>> 更多同类文章 ……

(本文同步发布于:http://www.52im.net/thread-3054-1-1.html

posted @ 2020-07-02 14:04 Jack Jiang 阅读(111) | 评论 (0)编辑 收藏

1、引言

IM在Android上的保活问题经常在即时通讯网的论坛和技术群里被讨论,自从Android 8.0后系统大大降低了后台运行应用的保活容忍度(详见《Android P正式版即将到来:后台应用保活、消息推送的真正噩梦》),保活从黑科技横行的时代进入了技术蛮荒阶段,真要实现保活,技术难度越来越大。

不过话说回来,既然用黑科技进行保活是Andriod技术的逆潮流,那何不回头是岸,做个“良民”?

本文将以某款线上的IM产品为例,介绍它是如何引导用户在多款主流机型上加白名单的,并分享了该款IM中已制作完成的多达7款主流Andriod机型的详细加白FAQ页面资源(含完整HTML+图片),方便您进行参考、学习和研究,希望能为你的应用开发带来帮助。

特别申明:本文示例中的资源来自某款真实的IM产品,仅供学习和研究,请勿用作非法用途,如有侵权,请告之于我。

学习交流:

- 即时通讯/推送技术开发交流5群:215477170[推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

本文已同步发布于“即时通讯技术圈”公众号,欢迎关注:

▲ 本文在公众号上的链接是:https://mp.weixin.qq.com/s/JqWloZLBYicpxElVL_HKYw ,原文链接是:http://www.52im.net/thread-3033-1-1.html

2、Android保活,变的越来越不可能了

IM产品在Android上的保活问题从早期的系统版本到现在,从未有人停止过尝试。即时通讯通讯网也随着Andriod系统版本的升级,持续整理了很多篇相关文章,比如下面这些(文章的顺序按照Android系统的版本从低到高)。

上面这些文章,我们可以看到,自从Android 8.0(即Andriod P)以后,IM以及其它需要在后台保活的产品,存活难度越来越高,黑科技几乎都不起作用了。

于是,一些技术从牛们只能从更深的Android系统层面尝试突破系统的保活限制,比如这两篇:《史上最强Android保活思路:深入剖析腾讯TIM的进程永生技术》、《Android进程永生技术终极揭密:进程被杀底层原理、APP应对被杀技巧》。

正如上面两篇文章,为了跟系统作斗争,可谓斗智斗勇。但Android系统的历史进程终究无人能阻挡,越来越严格的保活限制已经是Android官方及各大手机厂商的共识。

好吧,之前费尽心机折腾的各种黑科技,如今就像浮云一样。。。

 

3、死磕保活?别做梦了,回头是岸

正如上节所述,鉴于Andriod保活变的越来越不可能,很多原本靠黑科技保活的产品,开始重新审视保活技术实现,到底是把保活黑科技这条路走到黑,还是回归Android官方最佳实践(乖乖引导用户手动设置白名单)?

我个人认为,后者是保活技术发展的必然结果,就像之前分享的这篇文章里所做的尝试一样:《2020年了,Android后台保活还有戏吗?看我如何优雅的实现!》,规范地引导用户“加白”。

放弃“黑科技”,并不意味着技术不行,回归“良民”,反而变的一身轻松。

 

4、调用系统代码引导用户加白名单,也不完美

之前整理的《2020年了,Android后台保活还有戏吗?看我如何优雅的实现!》一文,是按照不同的机型,自动适配代码并在代码中调用系统的加白名单设置功能。

比如像下面这样的代码调用:

▲ 以下代码引用自《2020年了,Android后台保活还有戏吗?看我如何优雅的实现!

会弹出这样一个窗口:

这个方法确实不错,但因为机型不同、同机型的ROOM版本不同,代码的兼容处理,可能会相当复杂,所以方法虽好,但也并不能一劳永逸的解决所有问题。

5、应用内提供更多机型的“加白”FAQ帮助,是一个补充办法

正如上节所示,调用系统代码引导用户加白名单确实算的上“优雅”,但在不同的机型、同机型的不同系统版本上,可能差异很大,代码兼容性是个头疼的问题,总之这不是个百分百完美的办法。

这就需要一个补充手段,比如我们可以针对大量不同的机型,针对它的最行或最常用系统版本,在应用内以FAQ帮助网页的方式,为用户提供帮助。

比如可以在手机里打开像下面这样FAQ网页页面:

至少能在调用系统代码无法实现的情况下,可以让用户自主找到解决问题的办法。而这便是本文要分享,下节内容会以一个市面上做的比较好的IM应用为例,为你提供一个完整示例。

6、一个完整的“加白”FAQ帮助示例

最近发现的一款市面上的IM应用(此产品跟即时通讯网无任何关系,仅仅是作为技术研究参考对象而已),它内置的“加白”FAQ帮助就很完善。

以下是从该款IM中截下来的图: 

 

以下是该款IM应用中的运行演示视频(点此打开视频链接):

 

目前该应用中FAQ帮助已覆盖7款主流Andriod机,以下是完整示例页面链接:

可以看到,这款IM里的“加白”FAQ做的还是比较细、覆盖的机型也比较典型, 如果你有类似的想法或需求,完全可以参考这款产品的实现。尤其在一些特定的场景(比如企业内部的IM等)下,这种方式还是能解决大部分终端用户的问题的。

7、覆盖7款主流机型的“加白”FAQ页面静态资源(附件下载)

我整理了上节中提到的这款IM产品中的全部“加白”FAQ帮助页面静态资源,覆盖7款主流Andriod机型,如果你也需要同样的东西,可以参考这份完整的示例实现,打包到手机中使用之。

以下是这份静态资源示例的内容(图太长,已截掉了一部分): 

以下是这份静态资源示例的打包附件:

请从原文附件中下载:http://www.52im.net/thread-3033-1-1.html

附录:更多精品资源汇总

[1] 精品源码下载:

Java NIO基础视频教程、MINA视频教程、Netty快速入门视频 [有源码]

轻量级即时通讯框架MobileIMSDK的iOS源码(开源版)[附件下载]

开源IM工程“蘑菇街TeamTalk”2015年5月前未删减版完整代码 [附件下载]

微信本地数据库破解版(含iOS、Android),仅供学习研究 [附件下载]

NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战 [附件下载]

NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战 [附件下载]

NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示 [附件下载]

NIO框架入门(一):服务端基于Netty4的UDP双向通信Demo演示 [附件下载]

用于IM中图片压缩的Android工具类源码,效果可媲美微信 [附件下载]

高仿Android版手机QQ可拖拽未读数小气泡源码 [附件下载]

一个WebSocket实时聊天室Demo:基于node.js+socket.io [附件下载]

Android聊天界面源码:实现了聊天气泡、表情图标(可翻页) [附件下载]

高仿Android版手机QQ首页侧滑菜单源码 [附件下载]

开源libco库:单机千万连接、支撑微信8亿用户的后台框架基石 [源码下载]

分享java AMR音频文件合并源码,全网最全

微信团队原创Android资源混淆工具:AndResGuard [有源码]

一个基于MQTT通信协议的完整Android推送Demo [附件下载]

Android版高仿微信聊天界面源码 [附件下载]

高仿手机QQ的Android版锁屏聊天消息提醒功能 [附件下载]

高仿iOS版手机QQ录音及振幅动画完整实现 [源码下载]

Android端社交应用中的评论和回复功能实战分享[图文+源码]

Android端IM应用中的@人功能实现:仿微博、QQ、微信,零入侵、高可扩展[图文+源码]

仿微信的IM聊天时间显示格式(含iOS/Android/Web实现)[图文+源码]

Android版仿微信朋友圈图片拖拽返回效果 [源码下载]

[2] 精品文档和工具下载:

计算机网络通讯协议关系图(中文珍藏版)[附件下载]

史上最全即时通讯软件简史(精编大图版)[附件下载]

重磅发布:《阿里巴巴Android开发手册(规约)》[附件下载]

阿里技术结晶:《阿里巴巴Java开发手册(规约)-终极版》[附件下载]

基于RTMP协议的流媒体技术的原理与应用(技术论文)[附件下载]

独家发布《TCP/IP详解 卷1:协议》CHM版 [附件下载]

良心分享:WebRTC 零基础开发者教程(中文)[附件下载]

MQTT协议手册(中文翻译版)[附件下载]

经典书籍《UNIX网络编程》最全下载(卷1+卷2、中文版+英文版)[附件下载]

音视频开发理论入门书籍之《视频技术手册(第5版)》[附件下载]

国际电联H.264视频编码标准官方技术手册(中文版)[附件下载]

Apache MINA2.0 开发指南(中文版)[附件下载]

网络通讯数据抓包和分析工具 Wireshark 使用教程(中文) [附件下载]

最新收集NAT穿越(p2p打洞)免费STUN服务器列表 [附件下载]

高性能网络编程经典:《The C10K problem(英文)》[附件下载]

即时通讯系统的原理、技术和应用(技术论文)[附件下载]

技术论文:微信对网络影响的技术试验及分析[附件下载]

华为内部3G网络资料: WCDMA系统原理培训手册[附件下载]

网络测试:Android版多路ping命令工具EnterprisePing[附件下载]

Android反编译利器APKDB:没有美工的日子里继续坚强的撸

一款用于P2P开发的NAT类型检测工具 [附件下载]

两款增强型Ping工具:持续统计、图形化展式网络状况 [附件下载]

Android保活从入门到放弃:乖乖引导用户加白名单吧(附7大机型加白示例)

[3] 精选视频、演讲PPT下载:

美图海量用户的IM架构零基础演进之路(PPT)[附件下载]

开源实时音视频工程WebRTC的架构详解与实践总结(PPT+视频)[附件下载]

QQ空间百亿级流量的社交广告系统架构实践(视频+PPT)[附件下载]

海量实时消息的视频直播系统架构演进之路(视频+PPT)[附件下载]

YY直播在移动弱网环境下的深度优化实践分享(视频+PPT)[附件下载]

QQ空间移动端10亿级视频播放技术优化揭秘(视频+PPT)[附件下载]

RTC实时互联网2017年度大会精选演讲PPT [附件下载]

微信分享开源IM网络层组件库Mars的技术实现(视频+PPT)[附件下载]

微服务理念在微信海量用户后台架构中的实践(视频+PPT)[附件下载]

移动端IM开发和构建中的技术难点实践分享(视频+PPT)[附件下载]

网易云信的高品质即时通讯技术实践之路(视频+PPT)[附件下载]

腾讯音视频实验室:直面音视频质量评估之痛(视频+PPT)[附件下载]

腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT[附件下载]

微信朋友圈海量技术之道PPT[附件下载]

手机淘宝消息推送系统的架构与实践(音频+PPT)[附件下载]

如何进行实时音视频的质量评估与监控(视频+PPT)[附件下载]

Go语言构建高并发消息推送系统实践PPT(来自360公司)[附件下载]

网易IM云千万级并发消息处理能力的架构设计与实践PPT [附件下载]

手机QQ的海量用户移动化实践分享(视频+PPT)[附件下载]

钉钉——基于IM技术的新一代企业OA平台的技术挑战(视频+PPT)[附件下载]

微信技术总监谈架构:微信之道——大道至简(PPT讲稿)[附件下载]

Netty的架构剖析及应用案例介绍(视频+PPT)[附件下载]

声网架构师谈实时音视频云的实现难点(视频采访)

滴滴打车架构演变及应用实践(PPT讲稿)[附件下载]

微信海量用户背后的后台系统存储架构(视频+PPT)[附件下载]

在线音视频直播室服务端架构最佳实践(视频+PPT)[附件下载]

从0到1:万人在线的实时音视频直播技术实践分享(视频+PPT)[附件下载]

微信移动端应对弱网络情况的探索和实践PPT[附件下载]

Android版微信从300KB到30MB的技术演进(PPT讲稿)[附件下载]

从零开始搭建瓜子二手车IM系统(PPT)[附件下载]

极光分享:高并发海量消息推送系统架构演进(视频+PPT)[附件下载]

微信红包系统可用性设计实践(PPT) [附件下载]

微信红包数据架构演变(PPT) [附件下载]

百度网盘千万节点的P2P架构设计(PPT) [附件下载]

瓜子IM智能客服系统的数据架构设计(PPT) [附件下载]

基于C++构建微信客户端跨平台开发框架(PPT) [附件下载]

(本文同步发布于:http://www.52im.net/thread-3033-1-1.html

posted @ 2020-06-24 13:55 Jack Jiang 阅读(141) | 评论 (0)编辑 收藏

     摘要: 1、引言好久没写技术文章了,今天这篇不是原理性文章,而是为大家分享一下由笔者主导开发实施的IM即时通讯聊天系统,针对大量离线消息(包括消息漫游)导致的用户体验问题的升级改造全过程。文章中,我将从如下几个方面进行介绍:1)这款IM产品的主要业务及特点;2)IM系统业务现状和痛点;3)升级改造之路;4)消息ACK逻辑的优化。下述内容都是根据笔者开发IM的亲身经历总结下来的宝贵经验,干货满满,期待你的点...  阅读全文

posted @ 2020-06-17 13:47 Jack Jiang 阅读(158) | 评论 (0)编辑 收藏

1、内容点评

本文以轻松幽默的语气,讲解了视频编解码的一些基本常识,并以爱奇艺为例,讲述了视频编解码技术在国内的发展以及未来的一些展望。

▼ 阅读本文需要有一些音视频编解码技术的基础,否则请先阅读以下文章:

即时通讯音视频开发(一):视频编解码之理论概述

即时通讯音视频开发(二):视频编解码之数字视频介绍

即时通讯音视频开发(三):视频编解码之编码基础

即时通讯音视频开发(十九):零基础,史上最通俗视频编码技术入门

本文并未就具体的视频编解码概念进行深入的讨论,目的是尽可能以浅显易懂的方式让读者轻松了解本文标题想呈现的内容。如果您想深入了解视频编解码技术,可继续阅读以下文章。

▼ 以下是比较深入的视频编解码相关文章:

即时通讯音视频开发(四):视频编解码之预测技术介绍

即时通讯音视频开发(五):认识主流视频编码技术H.264

即时通讯音视频开发(十三):实时视频编码H.264的特点与优势

即时通讯音视频开发(十七):视频编码H.264、VP8的前世今生

即时通讯音视频开发(十八):详解音频编解码的原理、演进和应用选型

移动端实时音视频直播技术详解(四):编码和封装

[观点] WebRTC应该选择H.264视频编码的四大理由

▼ 爱奇艺技术产品团队还分享了其它两篇文章,有兴趣也可以读一读:

爱奇艺移动端网络优化实践分享:网络请求成功率优化篇

爱奇艺技术分享:爱奇艺Android客户端启动速度优化实践总结

欢迎关注“即时通讯技术圈”,更多好文会同步发布在公众号:

(本文同步发布于:http://www.52im.net/thread-3028-1-1.html

2、正文引言

初夏最火的造型是什么?不少人可能会脱口而出——“淡黄的长裙,蓬松的头发。。。”

就连我这个上古时期的老年人,都开始每周四和周六准时点开爱奇艺首页,吸一口青春美少女们。原因无他,后疫情灰色时期,还有什么能比漂亮小姐姐的灿烂笑容更能让人感觉到人间值得呢?而我上一次真情实感追完的的女团选秀,可能要追溯到……《超级女声》。

 

不管自己pick的姐姐妹妹能不能顺利出道,至少今天在屏幕上欣赏她们的颜,绝对是一件超幸福的事儿。既不用忍受电视的“马赛克画质”,还能随时随地掏出手机来欣赏妹妹们今日份的可爱。

 

不知道大家有没有同一种快乐,那就是用4G网络看蓝光1080P,已经没有“流量焦虑”了,出现缓冲旋转“小菊花”的情况的几率也在悄然减少。这种观看体验的优化,除了通信网络环境的改变之外,缔造这种视觉快乐的一项关键技术——视频编码,就像是宇宙中的暗物质——鲜为人知,但十分重要。

简单来说:视频编码技术的升级,能够让你用更少的流量、更低的带宽、更快的速度,看更高清晰度的视频画面。比如《青春有你2》溢出屏幕的元气少女感,是不是比2005年的朦胧美更令人心动呢?

 

习惯了1080P高清的用户,绝对不愿意再回到480P的自动马赛克时代了。那么,视频编码到底在高清视频的烹制中,发挥了怎样神奇的化学反应?搞秀之余,不妨来了解一下视频编码的前世今生,看看无数科技巨头如何围绕它撕得花红柳绿。

3、曾今的视频编码标准,是IT巨头们“跑马圈地”的游戏

曾今的视频编码标准,巨头们争相“入股”,视频编码标准有何诱人之处?

思科、微软、苹果、谷歌、奈飞等这些大名鼎鼎的巨头,为什么都觉得视频编码技术这波“入股不亏”,非要pick助其出道?

回答这个问题之前,有必要先简单解释一下,视频编码技术究竟是干什么的?

简单来说:就是将视频压缩成一定的格式,去除掉其中的空间冗余和时间冗余,形成更适合存储和传输的码流。之所以需要被编码压缩,最主要原因就是原始视频的数据量过于庞大。高清视频文件往往高达1G以上,如果本地播放也就算了,一旦需要将其上传、分享给他人,传输网络和存储设备都扛不住那么巨大的数据量。

所以视频平台就需要对所播放的文件进行重构:

  • 1)通过压缩编码将数据量变小,以方便传输;
  • 2)再依靠解压缩在用户端解码,将视频图像还原出来。

简单总结就是:编码效率决定了你的手机能下载多少部高清视频。

 

如果你经历过一晚上不关机终于下好一部2G大小的视频,却发现播放器弹出一行大字——“该视频无法播放”的绝望,那一定会鼓掌欢迎编解码技术的更新。

 

当然,一些“有流量任性”的小伙伴也会选择直接用4G网络在线观看视频,这时候视频大小可就没什么影响了吧?

这么想可就太天真了。视频编码技术越强,传输需要占用的带宽也就更小,就像堤坝没有加固,但冲击河道的流水变小了,自然也就不会出现出水口淤塞的问题,看视频卡顿、掉帧的事故也就不会上演了。

比如此次疫情期间,网络流量比例不断增加,为互联网服务商带来极大的挑战,传统的解决方案就是在网络带宽有限的前提下,降低视频的清晰度。如,YouTube、亚马逊旗下Prime Video、Netflix等一众互联网视频提供商都在欧洲、印度、澳大利亚等国家降低了视频画质,用户只能默认收看标清视频。

可是,吃惯了高清这盘珍馐,哪个用户还愿意忍受低画质的粗茶淡饭呢?为了留住挑剔的内容食客们,平台们不得不想尽办法,提升对视频的烹饪技艺。

那么,让我们得以随时随地追剧追综的视频编解码技术,到底有哪些呢?

目前,国际上主要有几种主流的视频编解码标准(国际上音视频编码技术的标准化),包括VPx(VP8VP9),H.26x(H.264H.265),AVS(AVS1,AVS2),AVx(AV1)等等。视频平台们用某一种通用编码格式标准,自己开发编码器,就可以用更厉害的标准批量生产视频了。

可详读以下相关文章:

即时通讯音视频开发(五):认识主流视频编码技术H.264

即时通讯音视频开发(十三):实时视频编码H.264的特点与优势

即时通讯音视频开发(十七):视频编码H.264、VP8的前世今生

[观点] WebRTC应该选择H.264视频编码的四大理由

这些标准都是什么?到底哪个更厉害?为什么每个字符我都认识但完全不知道是干什么的?甚至还有种被张含韵张韶涵张涵予张予曦张馨予等支配的恐惧,傻傻分不清楚……别急,其实就算是流媒体从业者,也很少有人将它们搞清楚。其实吧,只需要了解三个关键点,你就能轻松变成“技术派”碾压不少业内人士了。

简单来说:不同的视频编码标准,就是围绕三个要素所展开的“量子纠缠”的。

4、视频编码标准要素之一:高清

上世纪90年代,第一代视频编码标准H.261和MPEG-1就开始出现,其后几乎每十年就有一次迭代更新。

启动视频编码技术不断演进的核心要素,还是人们对于高清、更高清的不断追求。

视频编码技术每进化一代,视频压缩效率都至少提高了一倍。比如十几年前第二代视频编码标准VP8 和 H.264,只能应用在低于HD的中小分辨率视频上,稍微兼顾一点1080P分辨率。而2012年爱立信公司推出了首款H.265编解码器,所引领的第三代视频编码HEVC标准就只需H.264一半带宽,即可播放相同质量的视频。

啥意思的?如果你是一个拥有过MP4设备的互联网早期弄潮儿,同样大的存储空间,你可以多下载一倍大小的视频,告别四处借硬盘的苦日子。

在线看视频则更爽了,基于编解码标准,智能手机、平板等移动设备也能够直接在线播放 1080P 的全高清视频,还支持4K 和 8K 超高清。也就是说,只要有内容方愿意生产8K视频,平台就能给你100%还原出画面来,而不用受最高清晰度720P这样的限制。

那么,为什么HEVC标准推出2年后,采用AV1格式的消费类设备又开始出现呢?因为移动互联网的爆发,原有的编码标准依然不能完全解决带宽消耗的问题。所以更高效的视频编码标准如AVS3、H.266等,也都相继被研发人员安排上了。

为什么视频平台关于编码标准的“墙头”这么多?

试想一下,如果你用的是一个高分辨率配置的智能手机,但视频只能到480P的清晰度,为硬件高配置花的钱不就白瞎了吗?有的用户为了防止观看卡顿或模糊,还得额外下一个完美解码、格式工厂之类的第三方解码器,将视频转化一下才能看。

而只要视频平台支持更高效率的编解码标准,就能实现低带宽下播放高清视频不卡顿的效果。有现炒的热菜,谁还愿意等打包的盒饭呢?所以细心的读者会发现,编码技术的不断升级,开始让第三方编码工具悄悄退出了追剧党的工具箱。

 

5、视频编码标准要素之二:专利

尽管用户体验是视频编码技术的首要进化原则,但专利所带来的限制与成本,也成为产业风云迭起的重要诱因。

由GE、Technicolor、杜比,飞利浦和三菱等组建的H.265专利联盟HEVC Advance,就向使用该标准的厂商收取专利费。

因此,不少开源标准逐渐崛起。其中谷歌打造的VP9标准就是最负盛名的一个。不仅在实际效率上与HEVC/H.265接近,大大优于H.264及它的前身VP8,而且可以对专利免费使用。很快,YouTube全面支持VP9超高清流媒体节目,Netflix、苹果等也加入其中。

当年,爱奇艺的《破冰行动》无疑是热度最高的"爆款剧"之一,一度引起风靡,高清流畅的画面质感为其加分增色不少,就采用了基于VP9标准开发的全新编码器,就采用了基于VP9标准开发的全新编码器面部细节等方面画面真实感尤为显著。

 

而我国自主知识产权的第二代信源编码标准AVS的出现,更与专利有着不解之缘。

大家的童年有没有出现过DVD这种物件,租一部剧不用等更新一个周末看完的快乐,不亚于今天购买视频平台尊贵的“VIP中P”会员。但中国的DVD行业曾经也遇到过一次严重的专利危机。

2002年,一批出口的DVD产品因为技术专利费的缴纳问题没有解决而被扣押。于是同年6月,数字音视频编解码技术标准工作组成立,2006年,第一代视频编码标准AVS1推出,压缩效率和H.264相当,并且每个编解码器只象征性得收取1元专利费,对互联网上的软件服务更是免收专利费,从此摆脱了只能使用国际标准、被高额专利费卡脖子的窘境。

可以说,目前主流的两大标准VP9和AVS,都是在专利的锁链中生长出来的自由之翼。

6、视频编码标准要素之三:垄断

既然VP9已经开源了,那就抱紧谷歌大腿等大佬迭代再应用不就好了吗?一个国家的大部分视频都坐落在某一个标准体系上,等于将标准的议价权交到了别人手中,面对这种“垄断优势”,谷歌表示,我疯起来可能连自己都打,为了不作恶还是赶紧给自己培养个对手吧……

所以2015年,一个由谷歌倡议并参与,试图替代VP9和HEVC/H.265的新标准组织成立了,那就是开放媒体联盟Alliance for Open Media(AOM)。这个新的开源标准很快吸引了Adobe、亚马逊、AMD、奈飞、Facebook、思科、苹果、英特尔、英伟达等等巨头的参与。中国的爱奇艺也率先加入了AOM联盟。

这个由30多家领先的高科技公司组成的会员制联盟,很快开发出了新一代开源的视频编码标准AV1(AOMedia Video Codec 1.0),也就是今天能让我们看到高清版《青春有你2》,特别是选秀舞台上的说唱、劲舞的画面更加清晰平滑的“后台”。

 

AV1之所以在产业端迅速上马,成为包括奈飞、YouTube、BBC、爱奇艺等一众平台的推行目标,主要就是在用户体验上太能打了。

更高的编码效率、更低的码率,同等质量可以节省20%以上的带宽。举个例子,就是下载整期1080P版《青春有你2》,原本需要10G的手机存储,而AV1标准下只需要8G就能搞定,剩下2G空间咱们存点PLMM(漂亮妹妹)的高清大图舔颜它不香吗?

在线观看也很爽,不仅妹妹们的脸看起来会更清晰,而且高清播放所占的带宽也更小,同时下载个东西、刷个微博啥的,也不会因为网络拥挤而卡顿。

作为视频观众,谁不愿意平台默默地为我们殚精竭虑,周全每一点流量、带宽和存储卡呢?

 

不难看出,视频编码标准迭代,既是技术天花板的层层上探,也是整个视频平台必须攻占的体验高地。

7、如今,国内的视频平台正在抢跑编码标准“赛道”

具体到国内视频平台上,关于编码标准目前竞争身位如何,未来还有哪些硬仗要打,都是值得我们重点关注的话题。我们不妨具体到某一个平台的探索经历之中,用历史观的视角来捋一捋,视频编码技术到底给中国这片土地的网民,带来了哪些体验上的蝶变。

比如:以爱奇艺为例,2016年爱奇艺在万能播放器上线了AVS2格式,是当时国内唯一支持这一标准的平台;也是国内第一个实现VP9标准、AV1标准并应用的视频厂商。可以说在编码标准领域,无论是技术领先度、布局完善度上,都能够从一定程度代表中国流媒体产业的关键抉择。

有了标准,是不是只需要拿来直接上手呢?答案显然是否定的。

拿爱奇艺来说,我们的标准探索之旅,又是如何的呢?

我们就以当前效率最高的AV1标准为例,其算法运算复杂度高,所需要的编码时间很长,这样把平台所有视频都处理一遍,可能会等来用户一句“奶奶你等的AV1格式上线了”!

所以,为了提高编码效率,让处理效果能够快速细致,又不影响编码质量,达到工业应用标准,标准编码器就要靠各个平台发挥自主能动性了。

以爱奇艺为例,对每一代开源技术都保持紧密跟进的同时,也会发挥自身的技术特长来进行针对性的迭代,让同一标准在爱奇艺平台上的应用有更优秀的表现。

比如VP9标准推出时,爱奇艺的技术团队就根据开源的版本VP9编码器进行了专门的算法优化,所开发的QVP9编码器的速率是开源版本的5.4倍左右。作为国内首先支持VP9的视频厂商,其画面质量在快速镜头、轮廓边缘、面部细节等方面真实感尤为显著,压缩效率比市面主流的标准更是提升了一倍。可能也是在不知不觉间,突然发现视频中那些高速打斗的场面似乎更加细腻流畅了,人物的皮肤也变得更加立体和容易辨别,连女主角额头的青春痘都是那么的昭然若揭……

 

而伴随着用户在移动场景下观看视频的诉求越来越高,比如我本人就喜欢在地铁上刷短视频,别问,问就是流量多有钱任性!这时候要保证流畅不卡顿,主打PC端的VP9可能就有点不够了,所以对移动端设备更友好的AV1,在推出后也很快被安排的明明白白。

独立研发的QAV1编码器,不仅比H265减小将近一半的带宽,节省40%以上码率。而且速度比开源编码器SVT-AV1还快出5倍左右。比如同样是看《青春有你2》,用QAV1展示的画面效果更棒、颜值更高,反而还更省带宽,直接帮助我节省了不少流量,让满额限速来的更晚一些。

 

8、展望未来,5G让视频编解码技术有了更多的想象空间

目前,首批应用 AV1 的电影已经在爱奇艺上线,用户可以在电脑浏览器端和安卓移动端观看。做到这一步,很难吗?

答案是肯定的。举个例子,终端硬件解码芯片的成熟,与某项标准能否发挥价值有直接关系。比如H.265在硬件支持上比较广泛,就与苹果、高通、英特尔等的芯片都支持H.265的硬件解码器有关。

所以编码器往往需要结合具体的应用场景来进行改进和深度优化。

以AV1在爱奇艺的应用为例,为了更好地适应爱奇艺海量内容,QAV1通过对场景复杂度的预分析,实现了更加合理的码率分配。对于简单场景,QAV1可以自适应地降低码率,在保证画质的情况下节省用户带宽;同时对于复杂场景会适当提高码率,给用户带来更高画质的体验。

 

目前,QAV1已经支持的功能包括多种速度档次、多种码率控制方式、8K视频编码等。这种与差异化环境相匹配的细节打磨,同时兼顾了网络带宽与用户体验。

万众期待的5G,自然也需要与之匹配的视频编码标准来呼应。以爱奇艺为例来说,AVS3应用已经在路上了,用移动智能手机看8K超高清视频、浏览VR新闻资讯、与虚拟偶像互动……这些新娱乐体验,或许都将借助视频编码的技术魔术,被呈现到我们眼前。

从爱奇艺的视频编码探索中,不难看到,技术的时代快车并不容易拿到船票的。唯有长期披荆斩棘,才能顺利摘得王冠。

附录:更多音视频技术方面的资料

[1] 实时音视频开发的精华资料:

即时通讯音视频开发(一):视频编解码之理论概述

即时通讯音视频开发(二):视频编解码之数字视频介绍

即时通讯音视频开发(三):视频编解码之编码基础

即时通讯音视频开发(四):视频编解码之预测技术介绍

即时通讯音视频开发(五):认识主流视频编码技术H.264

即时通讯音视频开发(六):如何开始音频编解码技术的学习

即时通讯音视频开发(七):音频基础及编码原理入门

即时通讯音视频开发(八):常见的实时语音通讯编码标准

即时通讯音视频开发(九):实时语音通讯的回音及回音消除概述

即时通讯音视频开发(十):实时语音通讯的回音消除技术详解

即时通讯音视频开发(十一):实时语音通讯丢包补偿技术详解

即时通讯音视频开发(十二):多人实时音视频聊天架构探讨

即时通讯音视频开发(十三):实时视频编码H.264的特点与优势

即时通讯音视频开发(十四):实时音视频数据传输协议介绍

即时通讯音视频开发(十五):聊聊P2P与实时音视频的应用情况

即时通讯音视频开发(十六):移动端实时音视频开发的几个建议

即时通讯音视频开发(十七):视频编码H.264、VP8的前世今生

即时通讯音视频开发(十八):详解音频编解码的原理、演进和应用选型

即时通讯音视频开发(十九):零基础,史上最通俗视频编码技术入门

实时语音聊天中的音频处理与编码压缩技术简述

网易视频云技术分享:音频处理与压缩技术快速入门

学习RFC3550:RTP/RTCP实时传输协议基础知识

基于RTMP数据传输协议的实时流媒体技术研究(论文全文)

声网架构师谈实时音视频云的实现难点(视频采访)

浅谈开发实时视频直播平台的技术要点

还在靠“喂喂喂”测试实时语音通话质量?本文教你科学的评测方法!

实现延迟低于500毫秒的1080P实时音视频直播的实践分享

移动端实时视频直播技术实践:如何做到实时秒开、流畅不卡

如何用最简单的方法测试你的实时音视频方案

技术揭秘:支持百万级粉丝互动的Facebook实时视频直播

简述实时音视频聊天中端到端加密(E2EE)的工作原理

移动端实时音视频直播技术详解(一):开篇

移动端实时音视频直播技术详解(二):采集

移动端实时音视频直播技术详解(三):处理

移动端实时音视频直播技术详解(四):编码和封装

移动端实时音视频直播技术详解(五):推流和传输

移动端实时音视频直播技术详解(六):延迟优化

理论联系实际:实现一个简单地基于HTML5的实时视频直播

IM实时音视频聊天时的回声消除技术详解

浅谈实时音视频直播中直接影响用户体验的几项关键技术指标

如何优化传输机制来实现实时音视频的超低延迟?

首次披露:快手是如何做到百万观众同场看直播仍能秒开且不卡顿的?

Android直播入门实践:动手搭建一套简单的直播系统

网易云信实时视频直播在TCP数据传输层的一些优化思路

实时音视频聊天技术分享:面向不可靠网络的抗丢包编解码器

P2P技术如何将实时视频直播带宽降低75%?

专访微信视频技术负责人:微信实时视频聊天技术的演进

腾讯音视频实验室:使用AI黑科技实现超低码率的高清实时视频聊天

微信团队分享:微信每日亿次实时音视频聊天背后的技术解密

近期大热的实时直播答题系统的实现思路与技术难点分享

福利贴:最全实时音视频开发要用到的开源工程汇总

七牛云技术分享:使用QUIC协议实现实时视频直播0卡顿!

实时音视频聊天中超低延迟架构的思考与技术实践

理解实时音视频聊天中的延时问题一篇就够

实时视频直播客户端技术盘点:Native、HTML5、WebRTC、微信小程序

写给小白的实时音视频技术入门提纲

微信多媒体团队访谈:音视频开发的学习、微信的音视频技术和挑战等

腾讯技术分享:微信小程序音视频技术背后的故事

微信多媒体团队梁俊斌访谈:聊一聊我所了解的音视频技术

新浪微博技术分享:微博短视频服务的优化实践之路

实时音频的混音在视频直播应用中的技术原理和实践总结

以网游服务端的网络接入层设计为例,理解实时通信的技术挑战

腾讯技术分享:微信小程序音视频与WebRTC互通的技术思路和实践

新浪微博技术分享:微博实时直播答题的百万高并发架构实践

技术干货:实时视频直播首屏耗时400ms内的优化实践

爱奇艺技术分享:轻松诙谐,讲解视频编解码技术的过去、现在和将来

>> 更多同类文章 ……

[2] 开源实时音视频技术WebRTC的文章:

开源实时音视频技术WebRTC的现状

简述开源实时音视频技术WebRTC的优缺点

访谈WebRTC标准之父:WebRTC的过去、现在和未来

良心分享:WebRTC 零基础开发者教程(中文)[附件下载]

WebRTC实时音视频技术的整体架构介绍

新手入门:到底什么是WebRTC服务器,以及它是如何联接通话的?

WebRTC实时音视频技术基础:基本架构和协议栈

浅谈开发实时视频直播平台的技术要点

[观点] WebRTC应该选择H.264视频编码的四大理由

基于开源WebRTC开发实时音视频靠谱吗?第3方SDK有哪些?

开源实时音视频技术WebRTC中RTP/RTCP数据传输协议的应用

简述实时音视频聊天中端到端加密(E2EE)的工作原理

实时通信RTC技术栈之:视频编解码

开源实时音视频技术WebRTC在Windows下的简明编译教程

网页端实时音视频技术WebRTC:看起来很美,但离生产应用还有多少坑要填?

了不起的WebRTC:生态日趋完善,或将实时音视频技术白菜化

腾讯技术分享:微信小程序音视频与WebRTC互通的技术思路和实践

>> 更多同类文章 ……

(本文同步发布于:http://www.52im.net/thread-3028-1-1.html

posted @ 2020-06-10 11:54 Jack Jiang 阅读(196) | 评论 (0)编辑 收藏

本文中文译文由作者“ably.io”发布于公众号“高可用架构”,译文原题:《深入解读HTTP3的原理及应用》、英文原题:《HTTP/3 deep dive》(文末有译文和原文链接),即时通讯网收录时有少许改动,感谢原作者和译者的分享。

1、引言

HTTP3是HTTP协议的最新版本。从诞生之初,HTTP就是交换超文本文档的首选应用层协议。多年来,为了跟上互联网的发展,以及WWW上交换的内容种类增加,HTTP进行了几次重大升级,而HTTP/3就是目前的最新版本。

本文将从HTTP/3的基本概念、技术原理、应用场景和如何使用它等方面进行介绍,确保在有限的篇幅内,能让你通俗地理解它。


 

本文是系列文章中的第12篇,本系列文章的大纲如下:

网络编程懒人入门(一):快速理解网络通信协议(上篇)

网络编程懒人入门(二):快速理解网络通信协议(下篇)

网络编程懒人入门(三):快速理解TCP协议一篇就够

网络编程懒人入门(四):快速理解TCP和UDP的差异

网络编程懒人入门(五):快速理解为什么说UDP有时比TCP更有优势

网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门

网络编程懒人入门(七):深入浅出,全面理解HTTP协议

网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接

网络编程懒人入门(九):通俗讲解,有了IP地址,为何还要用MAC地址?

网络编程懒人入门(十):一泡尿的时间,快速读懂QUIC协议

网络编程懒人入门(十一):一文读懂什么是IPv6

网络编程懒人入门(十二):快速读懂Http/3协议,一篇就够!》(本文)

学习交流:

- 即时通讯/推送技术开发交流5群:215477170 [推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

欢迎关注“即时通讯技术圈”,更多好文会同步发布在公众号:

(本文同步发布于:http://www.52im.net/thread-3020-1-1.html

2、相关文章

从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路

网络编程懒人入门(七):深入浅出,全面理解HTTP协议

脑残式网络编程入门(三):HTTP协议必知必会的一些知识

网络编程懒人入门(十):一泡尿的时间,快速读懂QUIC协议》(推荐)

技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解》(推荐)

3、HTTP协议的演进史

在万维网诞生之时,万维网仅仅是一群交换超文本文件的计算机。在计算机之间交换文件是一个简单的程序,包括请求和响应。在此基础上设计了一个简单的基于文本的协议。HTTP(超文本传输协议)应运而生。后来,它被起草成了一个标准化的IETF协议,定义在RFC 1945中,也被称为HTTP/1.0。

多年来,HTTP从HTTP/1.0发展到HTTP/1.1,再到HTTP/2。在每一次迭代中,协议都增加了新的功能,以处理大量的需求,如应用层需求、安全考虑、会话处理和媒体类型等。要深入了解HTTP/2及其演进史,可详读《从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路》。

尽管经历了几次修订,但HTTP的底层传输机制基本没有变化。但是,随着互联网流量的激增,在移动电话的推动下,HTTP的传输机制在保证网页浏览体验的流畅性方面变得问题重重。

HTTP/3是为了处理HTTP/2.0的传输相关问题而生的,可以在各种设备上更快地访问Web。它基于一个新的传输层协议,称为QUIC(Quick UDP Internet Protocol),在UDP之上工作。这一选择与之前版本的HTTP截然不同,之前版本都是基于TCP。TCP是一个比UDP更可靠的协议,那么为什么要在UDP之上重新设计HTTP的传输层呢?


 

让我们来看看在TCP上运行HTTP的局限性,并深入了解一下基于QUIC协议的HTTP/3的设计思想。

4、什么是HTTP/3

当IETF正式标准化HTTP/2时,Google正在独立构建一个新的传输协议,名为gQUIC。它后来成为新互联网草案,并被命名为QUIC。gQUIC最初的实验证明,在网络条件较差的情况下,gQUIC在增强网页浏览体验方面的效果非常好。因此,gQUIC的发展势头越来越好,IETF的大多数成员赞成建立一个在QUIC上运行的HTTP新规范。这个新的倡议被称为HTTP/3,以区别于当前的HTTP/2标准。


 

从语法和语义上看,HTTP/3与HTTP/2相似。HTTP/3遵循相同的请求和响应消息交换顺序,其数据格式包含方法、标题、状态码和body。然而,HTTP/3的显著的偏差在于协议层在UDP之上的堆叠顺序。


 

有关QUIC的更多资料,可以看看《网络编程懒人入门(十):一泡尿的时间,快速读懂QUIC协议》、《技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解》。

5、HTTP/3 是如何工作的?

HTTP/3功能的核心是围绕着底层的QUIC协议来实现的。在讨论QUIC和UDP之前,我们有必要先列出TCP的某些限制,这也是导致QUIC发展的原因。

5.1 TCP可能会间歇性地挂起数据传输

如果一个序列号较低的数据段还没有接收到,即使其他序列号较高的段已经接收到,TCP的接收机滑动窗口也不会继续处理。这将导致TCP流瞬间挂起,在更糟糕的情况下,即使所有的段中有一个没有收到,也会导致关闭连接。这个问题被称为TCP流的行头阻塞(HoL)。


 

5.2 TCP不支持流级复用

虽然TCP确实允许在应用层之间建立多个逻辑连接,但它不允许在一个TCP流中复用数据包。使用HTTP/2时,浏览器只能与服务器打开一个TCP连接,并使用同一个连接来请求多个对象,如CSS、JavaScript等文件。在接收这些对象的同时,TCP会将所有对象序列化在同一个流中。因此,它不知道TCP段的对象级分区。

5.3 TCP会产生冗余通信

TCP连接握手会有冗余的消息交换序列,即使是与已知主机建立的连接也是如此。


 

QUIC协议在以下设计选择的基础上,通过引入一些底层传输机制的改变,解决了这些问题。

1)选择UDP作为底层传输层协议:在TCP之上建立新的传输机制,将继承TCP的上述所有缺点。因此,UDP是一个明智的选择。此外,QUIC是在用户层构建的,所以不需要每次协议升级时进行内核修改。

2)流复用和流控:QUIC引入了连接上的多路流复用的概念。QUIC通过设计实现了单独的、针对每个流的流控,解决了整个连接的行头阻塞问题。


 

3)灵活的拥塞控制机制:TCP的拥塞控制机制是刚性的。该协议每次检测到拥塞时,都会将拥塞窗口大小减少一半。相比之下,QUIC的拥塞控制设计得更加灵活,可以更有效地利用可用的网络带宽,从而获得更好的吞吐量。

4)更好的错误处理能力:QUIC使用增强的丢失恢复机制和转发纠错功能,以更好地处理错误数据包。该功能对于那些只能通过缓慢的无线网络访问互联网的用户来说是一个福音,因为这些网络用户在传输过程中经常出现高错误率。

5)更快的握手:QUIC使用相同的TLS模块进行安全连接。然而,与TCP不同的是,QUIC的握手机制经过优化,避免了每次两个已知的对等者之间建立通信时的冗余协议交换。


 

通过在QUIC之上构建基于HTTP/3的应用层,您可以获得增强型传输机制的所有优势,同时保留HTTP/2的语法和语义。但是,你也必须注意到,HTTP/2不能直接与QUIC集成,因为从应用到传输的底层帧映射是不兼容的。因此,IETF的HTTP工作组建议将HTTP/3作为新的HTTP版本,并根据QUIC协议的帧格式要求修改了帧映射。

除此之外,HTTP/3还使用了一种新的HTTP头压缩机制,称为QPACK,是对HTTP/2中使用的HPACK的增强。在QPACK下,HTTP头可以在不同的QUIC流中不按顺序到达。与HTTP/2中的TCP确保数据包的按顺序传递不同,QUIC流是不按顺序传递的,在不同的流中可能包含不同的HTTP头。因此,QPACK使用查找表机制对报头进行编码和解码。

6、为什么HTTP/3很重要?

TCP已经有40多年的历史了。它在1981年通过RFC 793从而标准化。多年来,它经历了多次更新,是一个非常强大的传输协议,可以支持互联网流量的增长。然而,由于设计上的原因,TCP从来就不适合处理有损无线环境中的数据传输。在互联网的早期,有线网络将网络中的每一台计算机连接起来。

现在,随着智能手机和便携式设备的数量超过台式机和笔记本电脑的数量,超过50%的互联网流量已经通过无线传输。这种趋势给整体的网络浏览体验带来了问题,其中最重要的是在无线覆盖率不足的情况下,TCP中的行头阻塞(关于TCP在移动网络下的不足,请阅读《5G时代已经到来,TCP/IP老矣,尚能饭否?》)。

Google的一些初步实验证明,QUIC作为Google部分热门服务的底层传输协议,极大地提高了速度和用户体验。部署QUIC作为YouTube视频的底层传输协议,导致YouTube视频流的缓冲率下降了30%,这直接影响了用户的视频观看体验。在显示谷歌搜索结果时,也有类似的改善。

网络条件较差的情况下提升非常明显,这促使谷歌更加积极地完善该协议,并最终向IETF提出标准化。

由于这些早期的试验所带来的所有改进,QUIC已经成为带领万维网走向未来的重要因素。在QUIC的支持下,HTTP从HTTP/2到HTTP/3的改头换面,朝着这个方向合理地迈出了一步。


 

7、HTTP/3的最佳用例

HTTP/3将改善我们上网的体验,特别是在仍无法使用高速无线网络的地区。尽管HTTP/2已经解决了一部分问题,然而HTTP/3更进一步。

7.1 物联网(IoT)

HTTP可能不是物联网的首选协议,但在某些情况下,基于HTTP的通信非常适合特定的应用。HTTP/3可以解决从传感器收集数据的移动电话的无线连接损耗问题。这个问题同样适用于安装在车辆或可移动资产上的独立IoT设备。通过HTTP来访问这些设备,可以更加可靠。

7.2 大数据

全球各地的企业都在觉醒,意识到从多个部门收集数据的潜力,并将其整合成更大的信息共享API,供内部和外部受众共享。这些API也为数据的货币化铺平了道路,通过托管这些数据作为流API服务可以实现数据的货币化。随着时间的推移,这些服务会吐出海量的数据。通过HTTP/3托管的流API将使它们比HTTP/2更健壮、更有弹性。

7.3 Web VR

随着浏览器能力的提升,内容格局正在快速变化。其中一个领域就是基于网络的VR。虽然还处于起步阶段,但有很多的用例可以让VR在加强协作方面发挥关键作用。网络在促进VR互动方面占据了核心位置。VR应用需要更多的带宽来渲染虚拟场景中的复杂细节,因此迁移到HTTP/3会大有收获。

8、HTTP/3的局限性

过渡到HTTP/3不仅涉及到应用层的变化,还涉及到底层传输层的变化。因此,与它的前身HTTP/2相比,HTTP/3的采用更具挑战性,因为后者只需要改变应用层。传输层承受着网络中的大量中间层审查。这些中间层,如防火墙、代理、NAT设备等会进行大量的深度数据包检查,以满足其功能需求。因此,新的传输机制的引入对IT基础设施和运维团队来说有一些影响。

然而,HTTP/3被广泛采用的另一个问题是,它是基于QUIC的,在UDP上运行。大多数的Web流量,以及IETF定义的知名服务都是在TCP之上运行的。这也是为什么长时间运行HTTP/3的UDP会话会被防火墙的默认数据包过滤策略所影响的原因。

随着IETF正在进行的标准化工作,这些问题最终都会得到解决。此外,考虑到Google在早期QUIC实验所显示的积极结果,人们对HTTP/3的支持是压倒性的,这将最终迫使中间层厂商标准化。

针对受限的IoT设备,HTTP/3由于过于繁琐从而无法采用。许多IoT应用部署的设备的外形尺寸非常小。因此,它们的RAM和CPU功率都是有限的。为了使设备在电池功率、低比特率和有损连接等限制条件下高效运行,必须执行此要求。HTTP/3在现有的UDP之上,以QUIC的形式在传输层处理,增加了HTTP/3在整个协议栈中的占用空间。这使得HTTP/3较为笨重,不适合那些IoT设备。但这种情况很少出现,而且存在专门的协议,这就避免了直接在此类设备上支持HTTP的需要。此外,还有以物联网为核心的协议,如MQTT

9、开始使用HTTP/3

IETF的HTTP工作组正致力于在2020年后期发布HTTP/3。因此它还没有被NGINX和Apache等主流web服务器正式支持。不过,有几个lib可以用来实验这个新协议,也提供了非官方的补丁。

以下是支持HTTP/3和QUIC传输lib的列表。请注意,这些实现都是基于互联网标准草案某一个版本,而这个版本很可能会被更高的版本所取代,最终的标准会在RFC中发布。

1)Quiche :

Quiche提供了通过QUIC协议发送和接收数据包的底层编程接口。它还支持HTTP/3模块,通过其QUIC协议实现发送HTTP数据包。除此之外,它还为NGINX服务器提供了一个非官方的补丁,可以安装和托管一个能够运行HTTP/3的Web服务器。除此以外,还提供了额外的程序来支持Android和iOS移动应用上使用HTTP/3。

2)Aioquic

Aioquic是QUIC的python实现。它还内置HTTP/3的测试服务器和客户端库。Aioquic建立在asyncio模块之上,asyncio模块是Python的标准异步I/O框架。

3)Neqo

Neqo 是 Mozilla 使用 Rust 实现 QUIC 和 HTTP/3。

如果你想尝试QUIC,请查看这个由QUIC工作组维护的QUIC协议的开源实现链接:https://github.com/quicwg/base-drafts/wiki/Implementations

(本文英文原文链接:点此进入、中文译文链接:点此进入

附录:更多有关HTTP协议的文章

网络编程懒人入门(七):深入浅出,全面理解HTTP协议

技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解

让互联网更快:新一代QUIC协议在腾讯的技术实践分享

从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路

脑残式网络编程入门(三):HTTP协议必知必会的一些知识

脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)

Comet技术详解:基于HTTP长连接的Web端实时通信技术

WebSocket详解(四):刨根问底HTTP与WebSocket的关系(上篇)

WebSocket详解(五):刨根问底HTTP与WebSocket的关系(下篇)

快速理解高性能HTTP服务端的负载均衡技术原理

一分钟理解 HTTPS 到底解决了什么问题

一篇读懂HTTPS:加密原理、安全逻辑、数字证书等

即时通讯安全篇(八):你知道,HTTPS用的是对称加密还是非对称加密?

IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token

即时通讯安全篇(七):如果这样来理解HTTPS原理,一篇就够了

一分钟理解 HTTPS 到底解决了什么问题

一篇读懂HTTPS:加密原理、安全逻辑、数字证书等

小白必读:闲话HTTP短连接中的Session和Token

IM开发基础知识补课:正确理解前置HTTP SSO单点登录接口的原理

基于APNs最新HTTP/2接口实现iOS的高性能消息推送(服务端篇)

全面了解移动端DNS域名劫持等杂症:原理、根源、HttpDNS解决方案等

美图App的移动端DNS优化实践:HTTPS请求耗时减小近半

HTTPS时代已来,打算更新你的HTTP服务了吗?

移动端网络优化之HTTP请求的DNS优化

(本文同步发布于:http://www.52im.net/thread-3020-1-1.html

posted @ 2020-06-03 23:18 Jack Jiang 阅读(258) | 评论 (0)编辑 收藏

     摘要: 1、引言网络优化对于移动端App产品的用户体验至关重要,也与公司的运营和营收息息相关。这里列举两个公开的数据:“《页面加载超过3秒,57%的用户会离开》”“《Amazon页面加载延长1秒,一年就会减少16亿美金营收》”网络性能对于用户体验的影响,将非常直接地反馈到业务的运营上。而且,移动网络固有的弱网问题、DNS问题、连接性能等等都无法跟传统的固定网...  阅读全文

posted @ 2020-05-29 12:06 Jack Jiang 阅读(191) | 评论 (0)编辑 收藏

     摘要: 1、引言网络优化对于移动端App产品的用户体验至关重要,也与公司的运营和营收息息相关。这里列举两个公开的数据:“《页面加载超过3秒,57%的用户会离开》”“《Amazon页面加载延长1秒,一年就会减少16亿美金营收》”网络性能对于用户体验的影响,将非常直接地反馈到业务的运营上。而且,移动网络固有的弱网问题、DNS问题、连接性能等等都无法跟传统的固定网...  阅读全文

posted @ 2020-05-29 12:05 Jack Jiang 阅读(131) | 评论 (0)编辑 收藏

1、引言

IM应用的初学者们,在补全了各种基础技术知识后(如果您仍不具备这些知识,建议马上阅读《新手入门一篇就够:从零开发移动端IM》),在动手编码实践时,很多时候纠结的并不是功能该如何实现,而是这个功能该实现成什么样(没有经验,我特玛能找谁问问?)。

比如,最常见的纠结有以下这些:

  • 1)离线聊天消息该保存多久?
  • 2)好友请求应该保存多久?
  • 3)短视频消息中的视频时长设为多大合适?
  • 4)图片、短视频、语音这些多媒体消息中,未读的文件数据保存多久?
  • 5)群管理的逻辑该怎么弄?参考微信?还是参考QQ?(关键是参考资料哪里有?)
  • 6)朋友圈限制最多发几张照片合适?
  • ... ...

嗯,这些问题,老板认为并不是问题,因为可以“参考微信”啊!

然而,微信又不会亲口说出来它的这些规则到底是多少?难不成要一个一个去试?那太扯了!

本文将根据微信官方目前已公开的资料,将它的一些常用功能参数和逻辑规则资料进行了汇总整理,希望能助力你的IM开发!(本文已发布于:http://www.52im.net/thread-3008-1-1.html

学习交流:

- 即时通讯/推送技术开发交流5群:215477170[推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》

本文已同步发布于“即时通讯技术圈”公众号,欢迎关注:

▲ 本文在公众号上的链接是:https://mp.weixin.qq.com/s/F-pVE9vN21h0Vm8LwnYplg

2、资料来源

本文中整理的所有内容均来自微信官方知识库,如果存在不全或不准确的情况,请在评论中回复,我会逐条核实并修订。

* 特别申明:本文内容仅供研究和学习使用,请勿用作其它用途。如有不妥之处,请指出,我会及时处理。

3、阅读对象

本文适合作为新老IM开发者的备查资料。本文不适合不懂技术的普通用户阅读,因为所有内容都尽量以技术人员的视解整理和表述。

移动端IM产品中,微信是标杆,也是事实的用户体验标准。所以,无论是被老板或产品经理怼,直接说“微信也这样”,能省去很多口水仗(经验啊)。这也是整理本文的初衷,以及价值所在。

4、相关资源

微信本地数据库破解版(含iOS、Android),仅供学习研究 [附件下载]》(* 推荐研究)

仿微信的IM聊天时间显示格式(含iOS/Android/Web实现)[图文+源码]

5、微信的好友关系规则汇总

5.1 好友验证请求有效期限

有效期限为 3 天。

* 补充规则:微信的好友验证请求只保存在手机本地,当卸载重装后,好友请求会消失且无法找回。

5.2 通讯录分组/好友排序

微信通讯录分组、好友排序,是根据微信通讯录朋友昵称的首字母(或首个汉字拼音首字母)由A-Z排序。

* 补充规则:如果好昵称是特殊符号、数字或Emoji表情(比如爱心、气球等),将会归到#类中。

 

5.3 好友验证规则

  • 1)当开启“加我为朋友时需要验证”后,需你同意接受请求后,才能成为好友;
  • 2)未开启“加我为朋友时需要验证”时,任何人都能添加你为好友(无需你确认)。

* 补充规则:如果不想被他人添加好友时搜索到,微信中可以设置关闭“微信号/手机号/QQ号”等搜索方式。

 

5.4 微信有4种添加好友方式

1)搜索加好友:

输入对方的微信号/QQ号/手机号搜索添加即可,但不支持搜索昵称。

* 补充规则:如果对方将关闭了“通过QQ/手机号/微信号搜索到我”,则没有办法通过此种方法添加好友。

2)雷达加朋友:

当被添加者物理距离很近时,一起按住手机,就可以添加对方为朋友。

3)扫二维码加朋友:

扫描对方的二维码名片,就可以添加对方为朋友。

4)手机联系人:

绑定手机联系人的微信帐号,可以查看到手机通讯录联系人已开通了微信的朋友,并直接添加对方为微信好友。

5.5 好友人数上限

微信最多可以添加 5000 个好友。

5.6 通讯录黑名单功能逻辑

将对方加入黑名单后,与对方的关系逻辑如下:

  • 1)在自己的会话列表不再显示与其聊天记录,解除黑名单后会重新出现在会话列表中;
  • 2)在对方的通讯录好友列表中仍然会显示;
  • 3)将不再接收到对方的消息;
  • 4)对方无法给你发消息,会提示“对方拒绝接收您的消息”,自己可以给对方正常发送消息;
  • 5)互相无法查看更新后的头像、个性签名;
  • 6)对方将无法查看你的微信个人相册和对照片进行评论;
  • 7)互相看不到朋友圈更新,拉黑之前在朋友圈分享的照片也不在对方朋友圈展示。

5.7 当被对方删除或“拉黑”后的聊天效果

当好友将你删除或加入黑名单后,你给他发消息时,微信将出现以下提示。

对方将我加入黑名单后,我发消息时的微信提示:

对方把我删除后,我发消息时的微信提示: 

6、微信的群聊规则汇总

6.1 微信群的功能定位

微信群相当于QQ中的讨论组,所以没有QQ里的群号码这种东西。

6.2 群主规则

群的创建者默认是群主。

* 补充规则:当创建者退出该群时,群成员列表中的第一位(也就是建群以来第2个加群的人)将自动成为新群主(好奇葩的规则!)。

另外:当原群创建者(即原群主)再次加群时,身份将会是普通群员。

6.3 群员邀请规则

群成员可以拉其他人加入群,群主不能取消普通群员的这个能力。

* 补充规则:群主可以设置邀请需确认,即需群主确认后才可以让被邀请的好友加到群内。

6.4 群名称规则

每个人(不只是群主)都可以修改群名称。

* 补充规则:当群超过 100 人时,只有群主可以修改群名称。

6.5 群公告规则

只有群主可编辑群公告。

* 补充规则:群公告字数限制为最大 2000 个字(即4000字节)。

6.6 群保存规则

微信群需要手动添加到通讯录才会永久保存,否则它只会保存在本地,一旦你卸载APP后,它就会消失。除非有群内成员发送消息,你才能再次看到,除次之外,你没有别的方法可以找回它。

6.7 群人数限制

微信群最大上限为 500 人。而且,100 人以上的微信群只有已通过实名验证的微信用户才能加入。

6.8 加群验证规则

  • 1)当群人数小于40人时,好友可以自由加入或被邀请加入;
  • 2)当群人数超过40人时,加群邀请需要对方同意;
  • 3)当群人数超过100人时,对方需要通过实名验证才能接受邀请(微信中可以通过绑定银行卡进行实名验证)。

6.9 解散或退出群规则

微信没有像QQ那样的“一键解散群”功能。

可以通过中列方法实现解散群或退出群的能力:

1)如果是群主(创建者或群成员列表第一位),可以将群成员全部删除;

2)如果是普通群员,可以退出群聊。

6.10 群二维码的有效期限

微信群的二维码有效期为 7 天(从二维码生成时开始计算),失效后的2维码扫描时将提示“该二维码已过期”。

6.11 微信群消息屏蔽规则

微信没有屏蔽群聊消息的功能,如果要达到这样的效果,你只能设置不提醒新消息或退出此群。

7、微信的朋友圈规则汇总

7.1 照片数和文字数限制

  • 1)朋友圈照片单次最多可添加 9 张照片,上传照片没有文件数量限制,也没有存储容量限制。
  • 2)最多可输入 1500 个汉字(即 3000 个字节)。

7.2 朋友圈新动态提醒规则

如果关闭了朋友圈更新提醒,当好友有发布新的朋友圈动态时,“发现”按钮上将不会再出现红点提示,否则将提示。

 

7.3 朋友圈查看权限规则

当你未作任何权限设置的情况下:

  • 1)你的所有朋友可以,查看到你在朋友圈发表的所有动态;
  • 2)陌生人可以查看你最近的10条动态。

发新朋友圈时,可以设置回避的人(即设置“谁可以/不可以看”):

  • 1)公开:所有朋友可见;
  • 2)私密:仅自己可见;
  • 3)部分可见:可在通讯录中选择哪些好友可见;
  • 4)不给谁看:可在通讯录中选择哪些好友不可见。
 

可以允许或禁止陌生人查看:

可以允许或禁止陌生人(可能来自扫码但未添加好友、附近的人、摇一摇、群聊时)看到10张最近发的照片。

可以设置朋友圈查看时间范围:

可选择允许好友查看朋友圈最近三天、最近半年或者全部的内容。

可以关闭朋友圈功能:

之前通过朋友圈发表的照片,可在个人相册里查看。但好友仍可以看到。

7.4 朋友圈的评论可见规则

  • 1)评论时,只会通知发布者;
  • 2)当评论时“@”某评论者,只会通知被回复者;
  • 3)评论者只能看到朋友的所有评论(当该条朋友圈的回复者不是朋友时,是看不到他的回复的)。

7.5 朋友圈隐私规则

1)陌生人查看十张照片:

当禁止“允许陌生人查看十张照片”时,陌生人将看不到你发布的任何朋友圈动态。微信默认是允许。

2)不看他(她)的朋友圈(即屏蔽好友的朋友圈):

在您的朋友圈中不会显示对方发送的朋友圈消息。

3)不让他(她)看我的朋友圈(即内容不更新给好友):

对方查看您的朋友圈显示是空白的,不会显示您发送过的任何朋友圈消息。

 

8、微信的聊天消息规则

8.1 聊天记录保存规则

  • 1)微信聊天记录保存在本地手机,一旦卸载微信,则聊天记录永久消失;
  • 2)微信不支持聊天记录漫游功能,一旦更新手机,新手机上无法看到之前手机上的聊天记录。

点评:这里有份完整的微信本地数据库样本,可以用来研究和学习:《微信本地数据库破解版(含iOS、Android),仅供学习研究 [附件下载]》。

8.2 离线消息保存规则

  • 1)微信服务器只保存 72 小时内的离线普通消息(从对方发消息时间开始算起),过期会被服务端清理;
  • 2)微信服务器只保存 72 小时内的多媒体数据(图片、短视频、大文件),即使你的手机已收到该条消息,只要未点击查看,即被视为未读,服务器会在此期限后清理掉多媒体数据。

8.3 “对方正在输入”的显示规则

给对方发送消息后,对方在 10 秒内回复才可以看到该提示。

 

8.4 聊天消息撤回时限

微信的规则是可以撤回2分钟内发送的消息。

8.5 消息已读回执规则

微信不支持已读回执功能。微信认为已读或未读状态属于个人隐私,不希望打破这种自由沟通的感觉。

8.6 语音消息规则

  • 1)最长可录制为 60 秒的语音消息;
  • 2)语音文件格式为:AMR;
  • 3)语音文件压缩比率:60秒语音文件约为45KB。

点评:如果你的IM中,语音文件大大超过微信的这个数据量,就表达存在较大优化空间,可以从采样率等方面进行设置。

8.7 短视频消息规则

  • 1)最长可录制为 10 秒的语音消息;
  • 2)语音文件格式为:MP4;
  • 3)语音文件压缩比率:10秒短视频约文件红为1.5MB至2.0MB。

点评:如果你的IM中,短视频文件大大超过微信的这个数据量,就表达存在较大优化空间,可以从采样率等方面进行设置。

8.8 文件消息规则

微信限制最大可以上传的文件大小为 25 MB。

8.9 聊天消息时间显示规则

  • 1)当天的消息,以每5分钟为一个跨度显示时间(即格式:HH:mm);
  • 2)超过1天、小于1周的消息,将显示“星期+收发消息的时间”;
  • 3)超过1周的消息,将显示手机收发时间的日期(即格式:yyyy-MM-dd)。

点评:这里有一份仿微信的聊天界面时间显示规则代码,可以下载用一用:《仿微信的IM聊天时间显示格式(含iOS/Android/Web实现)[图文+源码]》。

9、微信的其它规则

9.1 收藏功能规则

  • * 收藏的内容:可以收藏文字、语音、图片、视频、地理位置等。
  • * 保存的位置:收藏里面的内容是保存在服务器中的,只要你不主动删除,会一直存在。
  • * 单个文件大小限制:可以收藏的单个文件大小不能超过 25 M。
  • * 存储总容量限制:微信限制收藏数据的总容量为 2 GB,当总收藏容量超出2G后,超出容量的内容,将不能再上传。

9.2 “附近的人”功能规则

  • * 技术实现:当你查看附近的人功能时,微信将通过手机GPS获取你的位置信息,同时会被保留一段时间。
  • * 位置缓存:当你使用过“附近的人”时,服务器就会留下您的地理位置信息一段时间,周围的人可以再次搜到您。

9.3 “摇一摇”功能规则

当距离很近的两个同时“摇一摇”时,不一定能摇到对方。因为微信的“摇一摇”没有距离限制,而且是由服务器随机匹配。

10、电脑版微信的特殊规则

10.1 可以发送的消息类型

微信电脑端,可以发送文字、默认表情、符号表情、动画表情(兔斯基表情)、截图、图片消息,并能同步手机上已收藏的表情并发送。

10.2 可能接收的消息类型

可以接收文字、默认表情、emoji表情、动画表情、图片、文件、语音、视频、公众号消息、名片类型消息、小视频、地理位置消息、转账消息、合并转发的聊天记录消息。

10.3 可以接收但不能查看的的消息类型

红包消息、AA收款消息(收到此类消息会提示请在手机上查看)。

10.4 发送文件的大小限制

微信电脑端,上传文件大小最大为 100 MB,一次最多可以选择10个文件同时发送。

* 补充规则:如果发送的是视频,则文件大小不能超过 25 MB。

附录:微信团队分享技术资料汇总

微信朋友圈千亿访问量背后的技术挑战和实践总结

微信团队分享:微信移动端的全文检索多音字问题解决方案

微信团队分享:iOS版微信的高性能通用key-value组件技术实践

微信团队分享:iOS版微信是如何防止特殊字符导致的炸群、APP崩溃的?

微信团队原创分享:iOS版微信的内存监控系统技术实践

iOS后台唤醒实战:微信收款到账语音提醒技术总结

腾讯技术分享:社交网络图片的带宽压缩技术演进之路

微信团队分享:视频图像的超分辨率技术原理和应用场景

微信团队分享:微信每日亿次实时音视频聊天背后的技术解密

微信团队分享:微信Android版小视频编码填过的那些坑》 

微信手机端的本地数据全文检索优化之路》 

企业微信客户端中组织架构数据的同步更新方案优化实战

微信团队披露:微信界面卡死超级bug“15。。。。”的来龙去脉

月活8.89亿的超级IM微信是如何进行Android端兼容测试的

一篇文章get微信开源移动端数据库组件WCDB的一切!

微信客户端团队负责人技术访谈:如何着手客户端性能监控和优化

微信后台基于时间序的海量数据冷热分级架构设计实践

微信团队原创分享:Android版微信的臃肿之困与模块化实践之路

微信后台团队:微信后台异步消息队列的优化升级实践分享

微信团队原创分享:微信客户端SQLite数据库损坏修复实践》 

腾讯原创分享(一):如何大幅提升移动网络下手机QQ的图片传输速度和成功率》 

腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(下篇)》 

腾讯原创分享(三):如何大幅压缩移动网络下APP的流量消耗(上篇)》 

微信Mars:微信内部正在使用的网络层封装库,即将开源》 

如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源》 

开源libco库:单机千万连接、支撑微信8亿用户的后台框架基石 [源码下载]》 

微信新一代通信安全解决方案:基于TLS1.3的MMTLS详解》 

微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)》 

微信团队原创分享:Android版微信后台保活实战分享(网络保活篇)》 

Android版微信从300KB到30MB的技术演进(PPT讲稿) [附件下载]》 

微信团队原创分享:Android版微信从300KB到30MB的技术演进》 

微信技术总监谈架构:微信之道——大道至简(演讲全文)

微信技术总监谈架构:微信之道——大道至简(PPT讲稿) [附件下载]》 

如何解读《微信技术总监谈架构:微信之道——大道至简》

微信海量用户背后的后台系统存储架构(视频+PPT) [附件下载]

微信异步化改造实践:8亿月活、单机千万连接背后的后台解决方案》 

微信朋友圈海量技术之道PPT [附件下载]》 

微信对网络影响的技术试验及分析(论文全文)》 

一份微信后台技术架构的总结性笔记》 

架构之道:3个程序员成就微信朋友圈日均10亿发布量[有视频]》 

快速裂变:见证微信强大后台架构从0到1的演进历程(一)

快速裂变:见证微信强大后台架构从0到1的演进历程(二)》 

微信团队原创分享:Android内存泄漏监控和优化技巧总结》 

全面总结iOS版微信升级iOS9遇到的各种“坑”》 

微信团队原创资源混淆工具:让你的APK立减1M》 

微信团队原创Android资源混淆工具:AndResGuard [有源码]》 

Android版微信安装包“减肥”实战记录》 

iOS版微信安装包“减肥”实战记录》 

移动端IM实践:iOS版微信界面卡顿监测方案》 

微信“红包照片”背后的技术难题》 

移动端IM实践:iOS版微信小视频功能技术方案实录》 

移动端IM实践:Android版微信如何大幅提升交互性能(一)

移动端IM实践:Android版微信如何大幅提升交互性能(二)

移动端IM实践:实现Android版微信的智能心跳机制》 

移动端IM实践:谷歌消息推送服务(GCM)研究(来自微信)

移动端IM实践:iOS版微信的多设备字体适配方案探讨》 

腾讯信鸽技术分享:百亿级实时消息推送的实战经验

IPv6技术详解:基本概念、应用现状、技术实践(上篇)

IPv6技术详解:基本概念、应用现状、技术实践(下篇)

微信多媒体团队访谈:音视频开发的学习、微信的音视频技术和挑战等

腾讯技术分享:微信小程序音视频技术背后的故事

微信多媒体团队梁俊斌访谈:聊一聊我所了解的音视频技术

腾讯技术分享:微信小程序音视频与WebRTC互通的技术思路和实践

手把手教你读取Android版微信和手Q的聊天记录(仅作技术研究学习)

微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)

微信技术分享:微信的海量IM聊天消息序列号生成实践(容灾方案篇)

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

社交软件红包技术解密(二):解密微信摇一摇红包从0到1的技术演进

社交软件红包技术解密(三):微信摇一摇红包雨背后的技术细节

社交软件红包技术解密(四):微信红包系统是如何应对高并发的

社交软件红包技术解密(五):微信红包系统是如何实现高可用性的

社交软件红包技术解密(六):微信红包系统的存储层架构演进实践

QQ设计团队分享:新版 QQ 8.0 语音消息改版背后的功能设计思路

微信团队分享:极致优化,iOS版微信编译速度3倍提升的实践总结

IM“扫一扫”功能很好做?看看微信“扫一扫识物”的完整技术实现

微信团队分享:微信支付代码重构带来的移动端软件架构上的思考

IM开发宝典:史上最全,微信各种功能参数和逻辑规则资料汇总

>> 更多同类文章 ……

(本文同步发布于:http://www.52im.net/thread-3008-1-1.html

posted @ 2020-05-21 13:23 Jack Jiang 阅读(205) | 评论 (0)编辑 收藏

本文引用了公众号“鲜枣课堂”的《5G消息(RCS),到底是什么?》和公众号“InfoQ”的《5G消息来了,它会干掉微信还是变成另一个飞信?》两篇文章的部分内容,感谢原作者的分享。

1、引言

上个月3大运营商(移动、电信、联通)发布了《5G消息白皮书》(此白皮书PDF版 ▶ 点此附件下载),宣布将共同启动5G消息业务。

 

简单理解,5G消息相当于是原先短消息服务的全新升级。与以前的短消息相比,5G消息具有多媒体、能互动服务的能力,不仅有文字、图片,还能发视频、位置,甚至进行支付。

嗯,听起很熟悉——这不就是微信、支付宝们现在干的活吗?

没错!在移动互联网时代已经沦为微信这类IM巨头的管道工的运营商们,正在试图通过5G消息这个新工具抢回失去的话语权。

那么,5G消息到底是什么?是完全的创新技术还是旧式短信技术的新瓶装旧酒?它是否真的具有可以取代现时移动端主流IM产品的能力?请跟着本文,一起读懂5G消息的前世今生!

学习交流:

- 即时通讯/推送技术开发交流5群:215477170[推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

本文已同步发布于“即时通讯技术圈”公众号,欢迎关注: 

▲ 本文在公众号上的链接是:https://mp.weixin.qq.com/s/BF3ja1Uui6Pn32z0zI0H2g

2、5G消息是全新技术?

No,并不是!

“5G消息”,其实和5G并没有什么关系。它既不是5G特有的功能,也不是5G时代新开发出来的业务。它的真实身份,是诞生已有 10 多年的 RCS 技术。

3大运营商之所以要把它名名为“5G消息”,很大原因应该还是想借5G这个热点,从营销推广的角度进行的考虑,与技术无关。

RCS,全称是“Rich Communication Suite”,中文翻译过来就是“富媒体通讯套件”。

什么是“富媒体(Rich Media)”?传统电话只有语音,传统短信只有文本。而“富媒体”,包括文本、语音、图片、视频、动画、表情、位置等多种媒体形式。我们天天在用的微信,就是一种富媒体通信工具。

 

RCS,也被称为融合通信。所谓“融合”,既可以理解为多种媒体形式融合,也可以理解为IP业务和传统电信网业务的融合。

大白话来说,RCS可以理解为它是升级了传统的短信产品,使“短信”丰富化。

3、RCS技术的发展历程

我们先了解一下RCS技术的发展历程。

3.1 传统PC端IM的兴起,让电信厂商们蠢蠢欲动

我们把时间拨回到20多年前。当时,PC互联网以惊人的速度发展壮大,给人类带来了前所未有的信息大爆炸。

尤其是ICQ、MSN、OICQ(即QQ)等即时通讯工具的出现,让人们见识到多媒体通讯的无限乐趣。

 

▲ 能认全这3个IM的,都是老网民

于是,人们想到,这么有趣的通讯方式,是不是可以移植到手机上?

3.2 IMS的出现

3G移动通信标准,就是在这样的背景下建立起来的(2000年5月)。从3G起,手机的重点发展方向变成了数据业务,以满足人们日益增长的多媒体通信需求。

3G向4G的发展过程中,负责牵头标准制定的3GPP组织,考虑到传统语音通话及短信业务也需要向多媒体演进。于是,在2002年的3GPP Release 5版本中正式提出了IMS。

搞通信的读者一定对IMS这个词非常熟悉。如果是非通信专业的读者,我可以告诉你另外一个和IMS密切相关的词,那就是这几年特别火的VoLTE(Voice over LTE)。

是的,VoLTE业务,就是基于IMS实现的。

IMS的全称,叫做IP多媒体子系统(IP Multimedia Subsystem)。它包括了一系列不同的通信设备网元。

IMS的网络结构和业务流程非常复杂。对于IMS的作用,我们可以这么理解——它帮助4G LTE这个纯数据网络,实现对语音通话和短信的支持,并对它们进行强化(升级为多媒体形式)。

 

▲ IMS就是4G LTE网络的一个“插件”。有了它,4G才能打电话和发短信

在IMS的基础上,才有了VoLTE和RCS。

 

3.3 RCS的出现

2007年,RCS由一小部分GSMA(全球移动通信系统协会)成员提出,目的是为了运营商之间的多媒体消息互通。

2008年2月,GSMA正式成立RCS项目,并将其命名为“home”。此后,GSMA发布了多个版本的RCS、RCS-e(enhance,增强型)规范。

 

▲ GSMA,可以理解为全球运营商协会,主要代表运营商利益

RCS发布之后,得到了全球众多运营商的拥护。尤其是2008年4G LTE标准发布之后,RCS成为运营商们建设4G的标配。

3.4 RCS在移动端IM的挤压下持续演进

同样是2008年前后,iPhone和安卓相继问世,移动通信进入智能机时代,移动互联网市场开始井喷。

2011年左右,以WhatsApp、LINE、Facebook Message为代表的OTT通讯工具出现并迅速崛起,大量蚕食了传统运营商的语音、短信收入。

 

于是,海外运营商更加仰仗RCS,希望借此与OTT软件进行竞争。当时Vodafone、Orange、SKT、Verizon、O2等海外知名运营商都推出了自己的RCS解决方案和品牌。

2016年,为了进一步推动RCS的产品开发及全球部署,GSMA推出了RCS Universal Profile(通用配置文件,简称UP,相当于是一个规范标准),并陆续更新了多个版本。目前最新的版本,就是2019年10月发布的Version 2.4。

 

▲ RCS和UP的版本演进

3.5 RCS在国内的发展

我们回过头来看看RCS在国内的发展。

中国的3G和4G建设启动普遍晚于欧美日韩。3G就不用说了,晚了8年。4G是晚了5年。2013年底,工信部才发放了LTE商用牌照。

作为LTE的积极建设者,中国移动在2014年LTE大规模建网的同时,就非常看重IMS、VoLTE、RCS的商业价值。

因为飞信的前车之鉴,中国移动已经充分意识到传统运营商正在出现管道化的趋势,利润空间将不断被挤压,急需和OTT抢占流量入口,寻找新的业务增长点。

 

2015年,就在国内LTE网络覆盖初具规模之后,中国移动大幅提前了国内各省IMS和VoLTE网络的建设进度,并积极推动广州研究院的RCS业务验证和测试。

其实国内的三大运营商也都没有闲着,在 2017 年 4 月就完成了 RCS 三方(3大运营商)互通测试规范编制。其中,中国移动较为积极,在 2017 年 12 月即商用 RCS,包含 Native、App、PC 以及 SDK 四种终端形态。2019 年中移终端公司要求,所有在终端公司入库销售的机型都要支持 RCS Native 功能。

随着5G的到来,情况又发生了不同。

为了给5G网络腾挪更多的频谱空间,运营商必须加速2/3G网络的退网。而依附在2/3G网络上的传统语音和短信业务,必须尽快迁移到LTE和IMS网络上。(国内LTE网络的成熟覆盖,IMS的建设完成,使得RCS的推出具备了很好的时机。)

与此同时,面对OTT业务的持续打压,运营商也希望通过RCS进行最后一搏。于是,就有了这次“5G消息”业务的联合发布。

之所以叫“5G消息”,主要是希望借助5G的品牌,体现RCS业务和传统消息业务之间的代差。

4、RCS到底能实现什么样的功能和体验?

接下来我们讲讲RCS到底能实现什么样的功能,以及用户体验,何以让3大运营商重燃对搞微信等IM巨头的信心。

4.1 运营商对RCS的功能定位

中国移动在2014年曾经基于RCS提出了「三新」目标。这里面的三新,指的是:新通话、新消息以及新联系,分别指代了手机上的电话,短信,通讯录这三大入口。

  1. “新通话”以VoLTE为核心,增强用户通话质量和体验;
  2. “新消息”无缝融合多种媒体和消息格式,无缝与传统短/彩信互通;
  3. “新联系”以真实手机号码为前提,构建全新的社交、公众信息服务入口。

其实,这已经很明确地给出了RCS的功能和定位。

从总体上来看,运营商对RCS的应用场景定位分为两种:

  • 一种是个人用户与个人用户之间的消息交互;
  • 一种是企业用户与个人用户之间的消息交互。
 

4.2 RCS在普通用户间的消息交互与微信等IM相比,优势并不明显

针对场景1(即个人用户与个人用户之间的消息交互),RCS支持点对点消息,支持群发、群聊,支持语音、图片、视频多媒体消息,还支持发送位置、名片等,甚至还支持消息云备份和阅后即焚。

RCS的个人用户聊天时可以支持以下消息类型(跟IM很像): 

这些功能和我们目前的微信都差不多,RCS并没有体现出什么优势。考虑到用户习惯等原因,RCS估计很难撬动微信的霸主地位,未来可能主要是处于一个辅助性的地位。

更受运营商及整个产业关注的,其实是场景2(即企业用户与个人用户之间的消息交互)。

4.3 RCS在企业与个人的消息交互场景下,有很大的想象空间

2017年,GSMA在UP2.0规范中引入MaaP,还发布了MaaP白皮书,明确提出了面向A2P(Application to Person)行业消息的“RCS商业富媒体消息(RCS Business Messaging)”,也就是我们所说的场景2。

 

▲ RCS商业富媒体消息

MaaP,就是Messaging as a Platform,消息即平台。

RCS商业富媒体消息,为企业和个人用户之间提供消息交互接口,在图片和视频等基础上增加了交互能力,方便企业向用户输出个性化服务。

例如机票酒店预订查询、物流查询、网购订单查询等一系列轻应用功能,都可以通过RCS商业富媒体消息实现。

 

RCS商业富媒体消息的价值在于,它为企业和用户提供了一条新通道。借助这条通道,企业可以触达用户。用户也可以触达服务。

从某种意义上来说,它很像小程序、微信公众号(服务号),甚至电话客服中心。

为了实现RCS商业富媒体消息,运营商在自身网络上架设了MaaP能力增强开放平台和Chatbot聊天机器人。平台面向企业开放API接口,以提供服务。

技术架构大概是这样的: 

4.4 RCS拥有普通IM所不具备的优势

运营商对于“5G消息”(即RCS技术)这么有信心,源码它的一些独特的优势。

4.4.1)RCS优势1:它需要单独安装APP

它不需要单独安装第三方APP,手机原生就可以支持。这大幅降低了用户使用门槛,也节约了推广成本。

 

▲ 每个人的手机,都少不了这三个图标

虽然目前大部分手机并不支持5G消息,但后续各大厂商对手机进行软件升级,支持RCS UP 2.4规范之后,都可以支持。即使你不是5G手机(但至少是4G手机),也可以支持。

4.4.2)RCS优势2:无需注册账号

RCS业务和手机号码直接关联,用户号码就是账号,无需注册。

这同样降低了用户使用业务的复杂度,不仅解决了身份认证问题,还打通了“平台孤岛”(无需在每个商户单独注册账号)。

 

▲ 手机号即账号,一号通用

4.4.3)RCS优势3:无需添加好友

RCS牢牢掌握住了用户通信录这个社交金钥匙,无需添加好友,即刻就能建立社交网络。

尽管RCS拥有以上优势,但真正决定它能否走向成功的,并不是这些优势,而是它的生态和商业模式。

RCS的产业链既包括运营商、设备商、终端厂商,也包括平台服务商、内容提供商等。

设备商和终端厂商还好说,关键是平台服务商和内容服务商。它们愿不愿意投入,平台和应用该如何开发,开发能不能获得回报,如何吸引商户,要不要收费,如何收费,商户愿不愿意买单,这些都是未知数。

如果生态不能做大做强,就无法孵化更多的5G消息应用场景,也就谈不上商业价值回报。

5、现在才统一起来做“5G消息”,是否有点迟了?

从 3G 时代开始,全球电信运营商就受到 OTT(“OverTheTop”的缩写,指通过互联网向用户提供各种应用服务)厂商的冲击,国内三大运营商也不例外,传统的话音和短信业务收入大幅下降,OTT 服务虽然能带来流量收入,但也难以掩盖其增量不增收的尴尬。

随着微信等移动端IM互联网应用的不断扩张,运营商虽手握数亿用户,期间也有过大大小小的尝试与挣扎,例如中国移动的飞信、中国联通的沃友以及中国电信的易信,但最终都被边缘化。对 RCS 也有不少投入和试点,却还是雷声大雨点小,掀不起水花。三大运营商依然沦为主要提供语音、短信、流量等基础通信服务的“管道工”。

 

似乎,过度的竞争是导致运营商们错失机遇的主因之一。

某运营商直言:“过去,移动披靡一切。但后来对内‘弄不死’电信和联通,对外干不过阿里腾讯,对上交代不了国资委的考核。”。三大运营商终于联手便是 5G 消息的最大意义。

与采用私有协议的 App“孤岛式”的现状相比,由于三家运营商基于同一的国际标准(GSMA RCS UP 2.4),5G 消息在互联互通上的优势更为明显。

对比过去传统的短信业务,5G 消息可快速迭代——相关技术标准在 3 年内已迭代 5 大版本,从 UP1.0(2016 年 Q4)到最新的 UP2.4(2020 年 Q4)。

6、RCS看起来很美,但并非无懈可击

RCS确实具体先天优势,但也并非无懈可击。

RCS 仍面临三大挑战:

  • 1)用户的服务体验不一致,也给终端互联互通带来挑战(它无法做到像微信这样的IM一样,每款手机上安装的都是同一个应用);
  • 2)消息业务将会不断创新演进,需要终端快速跟进和支持,传统的技术研究、标准制定,终端研发,运营商测试等运营商长周期的流程,难以适应 RCS 快速发展;
  • 3)行业客户对 RCS 业务仍不熟悉,开发门槛较高。

另一方面,要培养用户使用短信入口的服务也不是件易事。

5G 时代,是多终端连接的物联网时代,小程序也被视为物联网众多的入口之一,谁都不会想放过这个机遇。

但 5G 消息能否拿回被微信这种IM应用抢走的市场,又或者在新的物联网增量市场分得一杯羹,尚需时日见证。可以肯定的是,对于客户来说,尤其是行业客户,多了一个选择。一个不是腾讯系,不是阿里系,也不是头条系的选择。

7、虽有不确定性,但RCS未来可期

目前,国内运营商的5G消息业务还处于试点大区联调测试阶段。

2020年4月10日,中兴通讯助力中国移动在杭州成功打通了基于GSMA UP2.4标准的5G消息first call,标志着国内5G消息商用进入正式倒计时。

据业内消息,2020年6月份国内就可以推出5G消息的正式商用。国内手机的升级支持,估计需要3个月到1年的时间。

相信随着5G建设的深入,RCS很快会成为大家手机中的标配。

“5G消息”到底会发展成什么样,作为IM开发者和普通用户来说,商业终究不是普通人该考虑的。从功能和体验上来说,多一种选择也未偿不是件好事,我们期待它早日到来!

 

8、最新动态:中国移动已于2020年5月10日上线“5G消息”APP

“5G消息”App是中国移动基于国际RCS标准打造的一款通讯及服务软件,支持发送文本、图片、音视频、地理位置等丰富消息;还可与商户的聊天机器人进行交互,获取7*24小时的智能服务。已于5月10日上线到苹果App store。

 

不幸的是,“5G消息”App上线仅一天就被下架(下架时间为5月11日)。

中国移动回应下架事件时说:因当前一些终端尚未支持5G消息功能,中国移动开发了“5G消息”APP,可以让开发者完成Chatbot(智能聊天机器人)应用开发后,真实体验消息交互服务,吸引广大开发者积极参与5G消息的合作生态构建,并非面向客户商用发布的产品。

中国移动表示:由于前期三家运营商联合发布5G消息白皮书,引发较高舆论关注,为保护“5G消息”名称不被恶意抢占,中国移动近日在应用市场进行上线(指的就是上线“5G消息”App)。因存在一些技术问题,该APP目前临时下线,稍后会重新上线。

在过去数年里,运营商与苹果公司的沟通讨论一直在进行中。目前通过安装App体验的做法,可以帮助苹果公司和苹果手机用户体验和使用5G消息。

9、《“5G消息”白皮书》附件下载

(附件无法上传,请从此链接下载:http://www.52im.net/thread-3001-1-1.html

10、参考资料

[1] 5G消息白皮书

[2] 中国移动率先发布5G消息APP:支持iOS/Android

[3] “5G消息”来了,App小心了!

[4] 中国移动、中国电信、中国联通联合发布《5G消息白皮书》

[5] 5G消息(RCS),到底是什么?

[6] 5G消息来了,它会干掉微信还是变成另一个飞信?

附录:更多IM产品方面的文章

技术往事:微信估值已超5千亿,雷军曾有机会收编张小龙及其Foxmail

QQ和微信凶猛成长的背后:腾讯网络基础架构的这些年

闲话即时通讯:腾讯的成长史本质就是一部QQ成长史

腾讯开发微信花了多少钱?技术难度真这么大?难在哪?

技术往事:史上最全QQ图标变迁过程,追寻IM巨人的演进历史》 

开发往事:深度讲述2010到2015,微信一路风雨的背后》 

开发往事:记录微信3.0版背后的故事(距微信1.0发布9个月时)》 

微信七年回顾:历经多少质疑和差评,才配拥有今天的强大

前创始团队成员分享:盘点微信的前世今生——微信成功的必然和偶然

QQ的成功,远没有你想象的那么顺利和轻松

[技术脑洞] 如果把14亿中国人拉到一个微信群里技术上能实现吗?》 

QQ和微信止步不前,意味着即时通讯社交应用创业的第2春已来?

那些年微信开发过的鸡肋功能,及其带给我们的思考

为什么说即时通讯社交APP创业就是一个坑?

即时通讯创业必读:解密微信的产品定位、创新思维、设计法则等

老罗最新发布了“子弹短信”这款IM,主打熟人社交能否对标微信?

盘点和反思在微信的阴影下艰难求生的移动端IM应用

QQ现状深度剖析:你还认为QQ已经被微信打败了吗?

那些年微信开发过的鸡肋功能,及其带给我们的思考

渐行渐远的人人网:十年亲历者的互联网社交产品复盘和反思

中国互联网社交二十年:全民见证的互联网创业演义

读懂微信:从1.0到7.0版本,一个主流IM社交工具的进化史

王欣回应微信封禁,解释为何取名“马桶MT”

同为IM社交产品中的王者,QQ与微信到底有什么区别

还原真实的腾讯:从最不被看好,到即时通讯巨头的草根创业史

知识科普:IM聊天应用是如何将消息发送给对方的?(非技术篇)

QQ设计团队分享:新版 QQ 8.0 语音消息改版背后的功能设计思路

社交应用教父级人物的张小龙和马化腾的同与不同

技事往事:你知道IM聊天软件中的“对方正在输入…”功能的起源吗?

盘点移动互联网时代的社交产品进化史(上篇):谁主沉浮

盘点移动互联网时代的社交产品进化史(下篇):大浪淘沙

IM热门功能思考:为什么微信里没有消息“已读”功能?

IM热门功能思考:聊天中加入“对方正在输入…”真的好吗?

别做梦了,社交产品哪有那么容易成功

微信那么牛,为什么海外成功的却是抖音?

专访马化腾:首次开谈个人经历、管理心得、技术创新、微信的诞生等

一文读懂微信之父张小龙:失败天才、颠覆者、独裁者、人性操控师

新技术展望:5G消息能取代IM应用?一文读懂5G消息的前世今生!

>> 更多同类文章 ……

欢迎关注我的“即时通讯技术圈”公众号:

(本文同步更新于:http://www.52im.net/thread-3001-1-1.html

posted @ 2020-05-14 11:47 Jack Jiang 阅读(199) | 评论 (0)编辑 收藏

本文引用了后端技术指南针公众号“浅谈RPC那些事儿1”和即时通讯网的“即时通讯新手入门:快速理解RPC技术——基本概念、原理和用途”两篇文章的部分内容。

1、引言

经常有开发者在纠结怎么开发IM集群,虽然真正的使用人数,可能用个人电脑单机都能支撑。

你也许会说,明明不需要用到IM集群,干吗要自找麻烦?答曰:“老板说这个得有!”、“万一产品做成了,用户量达到百万、千万级呢?”,各种回答,反此种种。总之,IM集群就是得整一个(先甭管用不用的上...)。

当然,玩笑归玩笑,真正要做到可投入到生产级别的IM集群系统,难度还是相当大的。必竟IM这种长连接应用相比传统Http这种短连接应用太不标准。

我们以一个典型的IM聊天消息传输为例:

假设存在两个正在聊天的用户(用户A和用户B),当A连接的是IM集群中的IM实例1、B连接的是IM集群中的IM实例2,此时当用户A向用户B发送一条聊天消息时,这条消息应该如何传递呢?

我们梳理一下上面这个例子的消息流转过程:

  • 1)IM聊天消息首先会由用户A发往IM实例1;
  • 2)IM实例1会将此条消息转交给IM实例2;
  • 3)IM实例2会将此条消息最终投递给连接在本实例上的用户B。

如上述流程所示,这就是一个IM集群系统中典型的聊天消息投递过程。

那么,这其中涉及到一个关键步骤:即第2)步中如何实现“IM实例1会将此条消息转交给IM实例2”?

此时,RPC技术出场了!

 

▲ 上图是个典型的分布式IM架构,注意中间的“RPC通信”字样本图引用自《基于Go的马蜂窝旅游网分布式IM系统技术实践

本文将以通俗易懂的白话形式,帮你快速理解IM集群中的关键技术——RPC。

推荐阅读:另一篇RPC基础知识文章也值得一读《即时通讯新手入门:快速理解RPC技术——基本概念、原理和用途》。

本文已同步发布于“即时通讯技术圈”公众号,欢迎关注:

▲ 本文在公众号上的链接是:https://mp.weixin.qq.com/s/0RXTUWHXDmMddsPVWej2Qg

2、相关文章

▼ 以下两篇文章有助于您对RPC和IM集群有个初步的概念:

即时通讯新手入门:快速理解RPC技术——基本概念、原理和用途》(推荐)

即时通讯新手入门:一文读懂什么是Nginx?它能否实现IM的负载均衡?

▼ IM开发干货系列文章(本文是其第24篇):

IM消息送达保证机制实现(一):保证在线实时消息的可靠投递

IM消息送达保证机制实现(二):保证离线消息的可靠投递

如何保证IM实时消息的“时序性”与“一致性”?

IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?

IM群聊消息如此复杂,如何保证不丢不重?

一种Android端IM智能心跳算法的设计与实现探讨(含样例代码)

移动端IM登录时拉取数据如何作到省流量?

通俗易懂:基于集群的移动端IM接入层负载均衡方案分享

浅谈移动端IM的多点登陆和消息漫游原理

IM开发基础知识补课(一):正确理解前置HTTP SSO单点登陆接口的原理

IM开发基础知识补课(二):如何设计大量图片文件的服务端存储架构?

IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议

IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token

IM群聊消息的已读回执功能该怎么实现?

IM群聊消息究竟是存1份(即扩散读)还是存多份(即扩散写)?

IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列

一个低成本确保IM消息时序的方法探讨

IM开发基础知识补课(六):数据库用NoSQL还是SQL?读这篇就够了!

IM里“附近的人”功能实现原理是什么?如何高效率地实现它?

IM开发基础知识补课(七):主流移动端账号登录方式的原理及设计思路

IM开发基础知识补课(八):史上最通俗,彻底搞懂字符乱码问题的本质

IM的扫码登功能如何实现?一文搞懂主流应用的扫码登陆技术原理

IM要做手机扫码登陆?先看看微信的扫码登录功能技术原理

IM开发基础知识补课(九):想开发IM集群?先搞懂什么是RPC!》(本文)

如果您是IM开发初学者,强烈建议首先阅读《新手入门一篇就够:从零开发移动端IM》。

3、正文概述

限于篇幅原因,本文不会深入展开RPC的底层技术原理,会尽量用通俗白话的方式对概念性的东西进行讲解。

通过本文你将主要了解到以下内容:

  • 1)什么是RPC;
  • 2)为什么需要RPC;
  • 3)RPC的重要组件;
  • 4)常见RPC框架和各自特点。

4、什么是RPC?

RPC 是1984年代由 Andrew D. Birrell & Bruce Jay Nelson 提出的(见二位大佬的论文《Implementing Remote Procedure Calls),所以它并不是最近才有的技术概念。

关于RPC的介绍,正经的资料上大概是这样介绍的:

RPC(Remote Procedure Call)远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。

大白话理解RPC就是:RPC让你用别人家的东西就像自己家的一样。

看得我似懂非懂,于是我不得不问几个问题:

  • 1)为啥要用别人家的东西——请求其他服务);
  • 2)我怎么可以借到别人家的东西——其他服务调用;
  • 3)要是借用的话哪种形式更好——确定一个合适的调用方法);
  • 4)怎么让我用别人东西像自己的一样——屏蔽底层细节透明通信)。

在解答这些问题之前,我们必须达到一个共识问题:RPC只是一种通信模式,和http并不冲突对立,相反http可以作为RPC传输数据的一种协议,把RPC当作一种模式和思想,我们才能更好地理解它。

更严谨的RPC基础知识介绍,请阅读:《即时通讯新手入门:快速理解RPC技术——基本概念、原理和用途》。

5、为什么需要RPC?

以大家最熟悉的电商系统为例,这样规模的分布式系统,需要拆分出用户服务、商品服务、优惠券服务、支付服务、订单服务、物流服务、售后服务等等。这些服务之间都相互调用,这时内部调用最好使用 RPC ,同时每个服务都可以独立部署,独立上线。 

也就说当我们的项目太大,需要解耦服务,扩展性强、部署灵活,这时就要用到 RPC ,这主要是解决了分布式系统中,服务与服务之间的调用问题。

 

▲ 上图中的分布系统内部,就是用RPC实现的本图引用自《从新手到架构师,一篇就够:从100到1000万高并发的架构演进之路

对于IM集群这样的分布式系统来说,不同IM实例间的用户聊天消息,就是通过RPC进行流转的。

6、为什么不直接使用HTTP,而要搞RPC?

在日常业务中我们可以把功能封装成静态库、动态库、sdk、独立服务等,最常见也最方便的还是HTTP这种形式的调用。

HTTP服务把需要提供的服务暴露成接口(也就是通常所说的http rest接口啦),使用方直接按约定的HTTP方法和URI进行数据交互。

我们都知道HTTP协议是应用层协议,是个非常标准的协议,在HTTP协议之下还有网络层、传输层、数据链路层等,一个数据包packet除了净荷payload之外还有很多header,由于标准和通用性的设计目标也使得HTTP一次数据交互真正传输的payload只是其中一部分。

 

HTTP是我们用的最多最熟悉的交互模式,在系统内部各个服务之间接口较少,交互不多的情况下工作得还不错。

但如果在内部系统调用很复杂的前提下,HTTP调用的效率和安全性就不那么理想了。

 

以IM系统为例,单个IM实例的吞吐效率至少可以达到几万甚至数十万QPS,使用HTTP这种短连接(调用时建立socket连接,完成后释放连接)方式显的相当低效(每次调用都要重新经历TCP的3次握手、4次挥手过程),在分布式的情况下势必拉低整个IM集群的吞吐效率。而对于RPC,这种socket长连接方式对于高性能场景来说,效果是显而易见的。

更重要的是面对众多的服务我们需要的不仅仅是一个通信方式,而是一个内部服务的管理系统,这也就是我们今天说的RPC框架。注意:RPC是一种模式策略和框架,并不是单纯的通信协议。

题外话:实际上,HTTP在RPC系统中,并不是个你死我活的关系,必竟HTTP只是个通信协议,而HTTP有某些性能要求不敏感的场景来说,是完全可以作为RPC的具体实现协议之一来使用的。

7、RPC的调用过程是什么样的?

 

▲ 典型的RPC调用过程

如上图所示,一个典型的RPC调用过程是这样(过程序号对应上图中的数字):

  • 1)客户端(client)以本地调用方式调用服务;
  • 2)客户端存根(client stub)接收到调用后,负责将方法、参数等组装成能够进行网络传输的消息体(将消息体对象序列化为二进制);
  • 3)客户端通过 sockets 将消息发送到服务端;
  • 4)服务端存根(server stub)收到消息后进行解码(将消息对象反序列化);
  • 5)服务端存根(server stub)根据解码结果调用本地的服务;
  • 6)本地服务执行并将结果返回给服务端存根(server stub);
  • 7)服务端存根(server stub)将返回结果打包成消息(将结果消息对象序列化);
  • 8)服务端(server)通过 sockets 将消息发送到客户端;
  • 9)客户端存根(client stub)接收到结果消息,并进行解码(将结果消息发序列化);
  • 10)客户端(client)得到最终结果。

RPC的作用,其实就是要把上述2、3、4、7、8、9 这些步骤都封装起来。是不是很神奇?

8、关于HTTP和RPC的一些争议

HTTP和RPC是两个很容易混淆的概念,对于刚开始接触RPC的人来说,通常都会困惑:有HTTP了为什么还要用RPC?

在知乎上看到了这个很有趣的问题:《既然有http请求,为什么还要用rpc?

其中一个大佬的回答感觉很有意思: 

换个角度来说:HTTP 与 RPC 的关系就好比普通话与方言的关系。要进行跨企业服务调用时,往往都是通过 HTTP API,也就是普通话,虽然效率不高,但是通用,没有太多沟通的学习成本。但是在企业内部还是 RPC 更加高效,同一个企业公用一套方言进行高效率的交流,要比通用的 HTTP 协议来交流更加节省资源。整个中国有非常多的方言,正如有很多的企业内部服务各有自己的一套交互协议一样。虽然国家一直在提倡使用普通话交流,但是这么多年过去了,你回一趟家乡探个亲什么的就会发现身边的人还是流行说方言。

如果再深入一点说,普通话本质上也是一种方言,只不过它是官方的方言,使用最为广泛的方言,相比而言其它方言都是小语种,小语种之中也会有几个使用比较广泛比较特色的方言占比也会比较大。这就好比开源 RPC 协议中 Protobuf 和 Thrift 一样,它们两应该是 RPC 协议中使用最为广泛的两个。

总之:RPC是一种编程模式和概念,并不是非常具体的一种技术,实际上和HTTP没有明确的冲突,HTTP可以作为RPC传输协议,原因还是RPCpid际上是一种内部服务框架而不是一个具体的通信协议,它可以涉及服务注册、服务治理、服务发现、熔断机制、负载均衡等。

9、典型的RPC框架

一个典型RPC框架中,包含了服务发现、负载、容错、网络传输、序列化等组件,其中“RPC 协议”就指明了程序如何进行网络传输和序列化。

 

▲ 一个典型的 RPC 架构原理图本图引用自《即时通讯新手入门:快速理解RPC技术——基本概念、原理和用途

 

▲ 著名RPC框架Dubbo的架构图本图引用自《即时通讯新手入门:快速理解RPC技术——基本概念、原理和用途

一个 RPC 最重要的功能模块,就是上图中的”RPC 协议”部分: 

其中的序列化和反序列化的意思是:

  • 1)序列化:将数据结构或对象转换成二进制串的过程;
  • 2)反序列化:将序列化中所生成的二进制串转换成数据结构或者对象的过程。

在网络消息传输中可以基于TCP、UDP、http来实现,各自都有各自的特点。

基于 TCP 实现的 RPC 调用,能够灵活对协议字段进行定制,减少网络开销提高性能,实现更大的吞吐量和并发数,但要关注底层细节,在进行数据解析时更加复杂一些(比如最受欢迎的Protobuf的使用)。

基于 HTTP 实现的 RPC 可以使用 JSON 和 XML 格式的请求或响应数据,解析工具很成熟,在其上进行二次开发会非常便捷和简单。但是 HTTP 是上层协议,所占用的字节数会比使用 TCP 协议传输所占用的字节数更高。

对于其他部分,本文不再展开。

10、市面上常见的RPC框架及其特点

常见 RPC 技术和框架有:

  • 1)应用级的服务框架:阿里的 Dubbo/Dubbox、Google gRPC、Spring Boot/Spring Cloud。
  • 2)远程通信协议:RMI、Socket、SOAP(HTTP XML)、REST(HTTP JSON)。
  • 3)通信框架:MINA 和 Netty。

目前流行的开源 RPC 框架还是比较多的,有阿里巴巴的 Dubbo、Facebook 的 Thrift、Google 的 gRPC、Twitter 的 Finagle 等。

下面重点介绍当前最流行的三种RPC框架主要特点:

  • 1)gRPC:是 Google 公布的开源软件,基于最新的 HTTP 2.0 协议,并支持常见的众多编程语言。RPC 框架是基于 HTTP 协议实现的,底层使用到了 Netty 框架的支持;
  • 2)Thrift:是 Facebook 的开源 RPC 框架,主要是一个跨语言的服务开发框架。用户只要在其之上进行二次开发就行,应用对于底层的 RPC 通讯等都是透明的。不过这个对于用户来说需要学习特定领域语言这个特性,还是有一定成本的;
  • 3)Dubbo:是阿里集团开源的一个极为出名的 RPC 框架,在很多互联网公司和企业应用中广泛使用。协议和序列化框架都可以插拔是极其鲜明的特色。

11、本文小结

小结一下,简单地理解RPC就是:

RPC 就是从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数或方法(可以统称为服务)并得到返回的结果。

RPC 会隐藏底层的通讯细节(不需要直接处理Socket通讯或Http通讯)。

RPC 是一个请求响应模型。客户端发起请求,服务器返回响应(类似于Http的工作方式)。

RPC 在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)。

12、参考资料

[1] 什么是 RPC 框架

[2] 谁能用通俗的语言解释一下什么是 RPC 框架?

[3] 浅谈RPC那些事儿[1]

[4] 即时通讯新手入门:快速理解RPC技术——基本概念、原理和用途

[5] 即时通讯新手入门:一文读懂什么是Nginx?它能否实现IM的负载均衡?

附录:有关IM架构设计的文章

浅谈IM系统的架构设计

简述移动端IM开发的那些坑:架构设计、通信协议和客户端

一套海量在线用户的移动端IM架构设计实践分享(含详细图文)

一套原创分布式即时通讯(IM)系统理论架构方案

从零到卓越:京东客服即时通讯系统的技术架构演进历程

蘑菇街即时通讯/IM服务器开发之架构选择

腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT

微信后台基于时间序的海量数据冷热分级架构设计实践

微信技术总监谈架构:微信之道——大道至简(演讲全文)

如何解读《微信技术总监谈架构:微信之道——大道至简》

快速裂变:见证微信强大后台架构从0到1的演进历程(一)

17年的实践:腾讯海量产品的技术方法论

移动端IM中大规模群消息的推送如何保证效率、实时性?

现代IM系统中聊天消息的同步和存储方案探讨

IM开发基础知识补课(二):如何设计大量图片文件的服务端存储架构?

IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议

IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token

WhatsApp技术实践分享:32人工程团队创造的技术神话

微信朋友圈千亿访问量背后的技术挑战和实践总结

王者荣耀2亿用户量的背后:产品定位、技术架构、网络方案等

IM系统的MQ消息中间件选型:Kafka还是RabbitMQ?

腾讯资深架构师干货总结:一文读懂大型分布式系统设计的方方面面

以微博类应用场景为例,总结海量社交系统的架构设计步骤

快速理解高性能HTTP服务端的负载均衡技术原理

子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践

知乎技术分享:从单机到2000万QPS并发的Redis高性能缓存实践之路

IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列

微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)

微信技术分享:微信的海量IM聊天消息序列号生成实践(容灾方案篇)

新手入门:零基础理解大型分布式架构的演进历史、技术原理、最佳实践

一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践

阿里技术分享:深度揭秘阿里数据库技术方案的10年变迁史

阿里技术分享:阿里自研金融级数据库OceanBase的艰辛成长之路

社交软件红包技术解密(一):全面解密QQ红包技术方案——架构、技术实现等

社交软件红包技术解密(二):解密微信摇一摇红包从0到1的技术演进

社交软件红包技术解密(三):微信摇一摇红包雨背后的技术细节

社交软件红包技术解密(四):微信红包系统是如何应对高并发的

社交软件红包技术解密(五):微信红包系统是如何实现高可用性的

社交软件红包技术解密(六):微信红包系统的存储层架构演进实践

社交软件红包技术解密(七):支付宝红包的海量高并发技术实践

社交软件红包技术解密(八):全面解密微博红包技术方案

社交软件红包技术解密(九):谈谈手Q红包的功能逻辑、容灾、运维、架构等

社交软件红包技术解密(十):手Q客户端针对2020年春节红包的技术实践

即时通讯新手入门:一文读懂什么是Nginx?它能否实现IM的负载均衡?

即时通讯新手入门:快速理解RPC技术——基本概念、原理和用途

多维度对比5款主流分布式MQ消息队列,妈妈再也不担心我的技术选型了

从游击队到正规军(一):马蜂窝旅游网的IM系统架构演进之路

从游击队到正规军(二):马蜂窝旅游网的IM客户端架构演进和实践总结

IM开发基础知识补课(六):数据库用NoSQL还是SQL?读这篇就够了!

瓜子IM智能客服系统的数据架构设计(整理自现场演讲,有配套PPT)

阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处

从游击队到正规军(三):基于Go的马蜂窝旅游网分布式IM系统技术实践

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

IM开发基础知识补课(九):想开发IM集群?先搞懂什么是RPC!

>> 更多同类文章 ……

本文已同步发布于“即时通讯技术圈”公众号,欢迎关注:


(本文同步发布于:http://www.52im.net/thread-2996-1-1.html

posted @ 2020-05-09 11:54 Jack Jiang 阅读(181) | 评论 (0)编辑 收藏

     摘要: 本文为开源工程:“github.com/GuoZhaoran/fastIM”的配套文章,原作者:“绘你一世倾城”,现为:猎豹移动php开发工程师,感谢原作者的技术分享。0、引言阅读提示:本文适合有一定网络通信技术基础的IM新手阅读。如果你对网络编程,以及IM的一些理论知识知之甚少,请务必首先阅读:《新手入门一篇就够:从零开发移动端IM》,按需补充相关...  阅读全文

posted @ 2020-04-28 12:05 Jack Jiang 阅读(244) | 评论 (0)编辑 收藏

阿里巴巴技术团队于2020年04月22日发布《Java开发手册v1.6.0-泰山版》。

1、概述

2017年开春之际,阿里诚意献上重磅大礼:《阿里巴巴Java开发手册(规约)》,首次公开阿里官方Java代码规范标准。这套Java统一规范标准将有助于提高行业编码规范化水平,帮助行业人员提高开发质量和效率、大大降低代码维护成本。

《阿里巴巴Java开发手册(规约)》是阿里内部Java工程师所遵循的开发规范,涵盖编程规约、单元测试规约、异常日志规约、MySQL规约、工程规约、安全规约等,这是近万名阿里Java技术精英的经验总结,并经历了多次大规模一线实战检验及完善。这是阿里回馈给Java社区的一份礼物,希望能够帮助企业开发团队在Java开发上更高效、容错、有协作性,提高代码质量,降低项目维护成本。

另外,《作者谈《阿里巴巴Java开发手册(规约)》背后的故事》一文,可以看看作者怎么说。

下载方式:详见文末 “6、历史版及最新版下载地址” !

2、价值意义

《阿里巴巴Java开发手册(规约)》的愿景是码出高效,码出质量。它结合作者的开发经验和架构历程,提炼阿里巴巴集团技术团队的集体编程经验和软件设计智慧,浓缩成为立体的编程规范和最佳实践。众所周知,现代软件行业的高速发展对开发者的综合素质要求越来越高,因为不仅是编程相关的知识点,其他维度的知识点也会影响软件的最终交付质量,比如,数据库的表结构和索引设计缺陷可能带来软件的架构缺陷或性能风险;单元测试的失位导致集成测试困难;没有鉴权的漏洞代码易被黑客攻击等。所以,本手册以开发者为中心视角,划分为编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约七个维度,每个条目下有相应的扩展解释和说明,正例和反例,全面、立体、形象地帮助到开发者的成长和团队代码规约文化的形成。

从严格意义上讲,《阿里巴巴Java开发手册(规约)》超越了Java语言本身,明确作为一名合格开发者应该具备的基本素质,因此本手册适合计算机相关行业的管理者和研发人员、高等院校的计算机专业师生、求职者等阅读,希望成为大家如良师益友般的工作手册、工具字典。

3、最新动态

关于泰山版(v1.6.0):

此版发布于2020年04月22日,此版升级内容包括:

1)发布错误码统一解决方案,详细参考手册的“附表 3”。

2)新增 34 条新规约。如:日期时间的闰年、闰月问题,三目运算的自动拆箱,SQL查询的表别名限定,Collectors 类的 toMap()方法使用注意等。

3)修改描述 90 处。如:阻塞等待锁、建表的小数类型等。

4)完善若干处示例。如:ISNULL 的示例等

4、主要作者

杨冠宝: 

杨冠宝:花名孤尽,取自《笑傲江湖》中风清扬的“独孤九剑,破尽天下武功”之意,是《阿里巴巴Java开发手册》的主要作者。在阿里巴巴集团历任研发、架构师、技术主管等不同的角色,承担过双11、国际化、代码中心等大型项目,有着丰富的一线编程经验,目前是研发协同平台Aone代码中心负责人。乐于分享与总结,在阿里巴巴集团内部大型分享多达30余次,不懈地追求技术创新,勇于挑战技术难度,在大数据、高并发、研发效能领域均有较深的造诣。

2016年3月,孤尽带领约码项目组编写《阿里巴巴Java开发手册(规约)》,码出高效,码出质量,推动阿里系与业界一起进步,让代码变得更舒服,更清澈,更好维护。

5、部分内容截图预览

 
 
 

6、历史版及最新版下载地址

请从此下载:阿里技术结晶:阿里巴巴Java开发手册-v1.6.0-泰山版》[附件下载]

posted @ 2020-04-23 11:44 Jack Jiang 阅读(831) | 评论 (0)编辑 收藏

本文原始内容由爱奇艺技术产品团队原创分享,本次有修订和改动。

1、引言

由于移动网络的复杂性特点,编写高质量、体验好的具备网络通信能力的移动端应用(尤其是即时通讯这类网络质量高度敏感的应用)有很大的挑战性。

我们平时看到的移动网络主要有如下三个典型特点:

1)移动状态网络信号不稳定,高时延、易抖动丢包、通道狭窄;

2)移动状态网络接入类型和接入点变化频繁;

3)移动状态用户使用高频化、碎片化、非WIFI流量敏感。

(▲ 上述文字,引用自《移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”》)

正是由于上述特点,移动端应用在进行网络数据通信时会面临各种复杂多变的问题。

无论后面的技术有多复杂,但对于普通用户使用APP来说,能顺畅的完成网络请求,是理所当然的事。换句话说,APP网络请求成功率,重要性直接体现在它能直接决定APP服务的可用性,直接影响到数据通信、视频播放、广告展现、支付便捷等服务质量。

本文将以爱奇艺的iOS端APP为例,分享对移动网络请求成功率优化方面的技术实践之路。

本文将同时发布于“即时通讯技术圈”公众号,欢迎关注:

(本文已同步发布于:http://www.52im.net/thread-2981-1-1.html

2、相关文章

现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障

移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”》(* 必读好文

移动端IM开发者必读(二):史上最全移动弱网络优化方法总结

全面了解移动端DNS域名劫持等杂症:技术原理、问题根源、解决方案等

美图App的移动端DNS优化实践:HTTPS请求耗时减小近半

百度APP移动端网络深度优化实践分享(一):DNS优化篇

百度APP移动端网络深度优化实践分享(二):网络连接优化篇

百度APP移动端网络深度优化实践分享(三):移动端弱网优化篇

3、导致移动端网络请求失败的因素

想要优化移动端网络请求成功率,先来了解移动端网络请求全链条可能导致请求失败的环节有哪些。

这些环节往往由以下两类因素导致:

 
 

第一类:不可改善因素:

1)iOS系统对APP的网络访问权限控制、飞行模式或者无网络连接。检测和识别这三种情况,通过适当方式提示用户;

2)路由器故障。

第二类:可以改善因素:

1)蜂窝/Wifi信号的强弱、连接拥堵的假连接状态;

2)DNS故障(比如DNS劫持等);

3)运营商局部节点故障;

4)自有运营负载均衡故障;

5)业务服务器故障:HTTP响应错误,对应APM的HTTP响应错误率;

6)业务逻辑错误:监控子类解析结果,对应APM的解析错误率监控。

对于不可改善因素:目前只能通过网络诊断识别出故障类型,引导用户手动去授权访问网络或者连接可用网络。

其中,如果是路由器故障,可以引导用户重启路由器或者切换4G。通过爱奇艺APP的数据监控,大致可以看到用户无网连接的时长占比有3.8%左右,这说明提供好的无网提示变得十分重要,而从用户使用蜂窝信号的弱信号(0格和1格信号)时长占比有9%左右时长,也可以看出移动端网络环境的复杂性。

 
 

针对可以改善的因素,解决方法可大致分为三类:

1)网络层错误,对应因素1到4。主要体现为超时报错;

2)HTTP响应错误,对应因素5。HTTP状态码为400及以上;

3)解析错误,对应因素6。由基线网络库定义的重载接口进行监控。

为了提高网络请求成功率,首先需要建立监控体系,从而使得基线网络库能够通过网络统计模块向APM投递各种维度的网络请求数据。有了APM的数据统计后,才能有效的发现导致端上网络失败的原因,进而解决问题。

除此之外,由于端上网络请求数据巨大,存储空间的限制使得APM只能采样2%的用户,因此针对重点业务的网络请求(比如首页)则进行了全量采集,从而对成功率的优化实现更客观全面的评估。

4、在基线网络库这一层针对不同业务提供不同的补偿思路

在优化之前,通过APM的归类分析可以得出:请求失败的主要报错是超时(-1001)的占比达到九成,与此同时SSL错误,DNS解析错误占比紧随其后。根据这一数据统计,重试成为最主要的请求成功率优化的措施。

经过不断探索和实践总结,基线网络库针对不同业务需求提供了四种不同的重试手段。

1)IP直连重试,通过配置直连IP数来控制重试次数:

Scheme不变,Host改为直接使用IP(消除域名解析风险)。由于此举需要各个业务线自己提供直连的IP,目前接入的业务主要是登录等强制要求HTTPS连接的业务。

2)超级管道重试,可以配置1~3次重试:

公司自研基于HTTP的网关代理服务(类似于远程charles代理)。Host改为代理IP(消除域名解析风险),Scheme改为HTTP(消除SSL风险,h2降级为HTTP1.1)。由于该措施需要付出流量成本,目前接入的业务都是关键核心业务,比如首页等。

3)HTTP重试,可以配置1~3次重试:

Scheme修改为HTTP(消除SSL风险,h2降级为HTTP1.1),其他不变。鉴于其为普惠性重试手段,目前接入非关键核心的一般业务。

4)原url重试,可以配置1~3次重试:

Scheme和host等都不变,通常意义上理解的重试,单纯的再请求一次。此举目前不是推荐重试手段,由业务方自主决定。

 
 

除了单个重试手段可以重试多次,基础网络库也支持多种重试手段的组合,四种重试手段的优先次序为:IP直连重试 > 超级管道重试 > HTTP重试 > 原URL重试。扣除无网情况,首页推荐页CARD接口成功率通过组合重试在2020第一季度末达到了99.76%。

 

5、其它影响移动端网络请求成功率的因素

除了重试,还有以下因素对网络请求成功率有直接影响。

1)HTTP/2 vs HTTP/1.1:推荐的请求策略是首次请求走H2,当失败重试时走HTTP/1.1:

HTTP/2对HTTP/1.1最大改进是共用一个TCP连接(详见《从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路》),其在网络顺畅时,为HTTP/2带来了速度上的优势。但当网络变坏时,TCP包的绝对顺序编号会导致一个包的丢失而堵住后面所有的请求。这样单TCP连接反而扩大了拥堵,增大了请求失败的可能性。

NSURLSession是HTTP协议自适应的,不能控制请求使用HTTP/2或者HTTP/1.1。不过由于业界事实上的标准要求HTTP/2必须是HTTPs的,这样通过将URL Scheme改为HTTP可以间接降级到HTTP/1.1。

2)适当的超时设置是一个重要影响因素:

NSURLSession的超时实际上是TCP的包间超时,并不是整体请求耗时的超时。

 

推荐的超时设置策略是:首次请求的超时可以小一点,而重试的超时应该大一些。

3)接口请求过于密集并发可能降低请求成功率:

比如播放记录的upload接口在加上多次重试后,成功率仍然只有98.2%。APM监控此接口在IPv4环境失败率只有0.47%,而IPv6失败率高达7.07%。通过端上优化请求策略,降低接口的并发密度后,IPv6环境和IPv4环境同时提高到99.85%的成功率。

4)接口数据体积越小,请求成功率越高:

HTTP/2和HTTP/1.1都是基于TCP连接的,接口数据体积越小,需要传输的TCP包越少,传输失败的概率也就降低了。目前爱奇艺APP正在从gzip转向压缩率更高的br(指的是Brotli压缩算法,详见:《启用 Brotli 压缩算法,对比 Gzip 压缩 CDN 流量再减少 20%)。

6、提高鲁棒性并防止故障的优化措施

在经过各种优化措施提高网络成功率后,我们还通过下面几个措施成功的防止线上故障造成的成功率瞬时下降,提高了网络请求的鲁棒性。

1)超级管道本身的鲁棒性:

下面案例显示使用了超级管道重试的接口错误率只有3.95%,而没有使用超级管道重试的接口错误率高达28.96%。这个案例的时间点还没有使用异地容灾IP,在叠加异地容灾IP之后,错误率曲线几乎可以抹平。

 
 

2)HTTP重试和原URL重试在v4v6双栈环境下,优先IPv4:

由于IPv6仍在建设中,有些接口在IPv6的表现弱于IPv4,那么可以指定重试走IPv4。

3)TLS1.3– 1RTT的节省:

TLS1.3将SSL握手2个RTT降为1个RTT,降低了SSL握手失败的概率。iOS12.2开始,NSURLSession支持TLS1.3。只需要服务器升级支持TLS1.3即可,端上无须改动。

4)IP复合连接竞速:

使用TCP连接测速,目的是剔除坏IP,选择最优IP,从而提高请求的成功概率。

经上述措施的持续优化,爱奇艺APP在2020Q1末,扣除无网情况后,业务成功率达到了99.7%,而网络层成功率达到了99.77%。

▲ 业务成功率 = 网络层成功率+HTTP响应成功率+解析成功率

在完成优化后,爱奇艺APP基础网络库的构成如下:

 

如上图所示,基础网络库各模板的功能作用如下:

1)统一网络库:提供一个网络接口层,所有业务接口都对接使用网络接口层;

2)统一网络库:提供一个网络封装层,对接了iOS系统网络层NSURLSession、ASIHTTPRequest(基于CFNetwork)、和公司自研的长连接网关;

3)网络统计模块:将从业务调用开始到回调给业务方的各个环节的耗时及状态值,变成统计数据,上传到APM汇合;

4)网络诊断模块:对关键业务进行诊断,包括dns解析,ping,tcpconnect,trace等工具对具体IP进行分析,分析结果上传到APM汇合;

5)弱网检测模块:通过借鉴Facebook的弱网检测是基于网速拟合的网络等级分级,分为网络情况非常差(2G或者无网)、网络情况较差(3G)、网络情况一般、网络情况较好、网络情况非常好五个等级;

6)HTTPDNS模块:有效的解决了运营商劫持问题;

7)超级管道重试:基于HTTP的网关代理,具有异地容灾代理能力;

8)ipv4/ipv6模块:识别端上是ipv4 only环境、v4/v6双栈还是ipv6 only环境;

9)复合连接模块:可以在server IP缓存池选出最佳IP,手段包括目标IP连接竞速,IP历史请求统计数据排序;

10)网络日志模块:记录了最近发生的失败网络请求详细数据和网络诊断数据。随反馈一并提交,可以便捷的排查线上网络问题。

7、未来的目标与可能的优化措施

为了持续优化网络成功率,下一步目标是扣除无网情况,重点业务成功率达到99.9%。后续考虑的优化措施如下。

1)Multipath:

当Wifi假连接的时可以走蜂窝流量,iOS 7开始支持Multipath特性(详见:《揭开 iOS 7 之 Multipath TCP 的面纱》)。

2)QUIC:

QUIC是基于UDP的,由于运营商对UDP有针对性的丢包,实测QUIC并没有体现出优势。然而,考虑到libcurl在2019已提供完整QUIC能力,NSURLSession不久也会支持QUIC。随着运营商对UDP包的干扰减少,QUIC的优势将得到体现。

如果对QUIC协议感兴趣,可以读一读下面这些文章:

网络编程懒人入门(十):一泡尿的时间,快速读懂QUIC协议

技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解

让互联网更快:新一代QUIC协议在腾讯的技术实践分享

七牛云技术分享:使用QUIC协议实现实时视频直播0卡顿!

3)智能调度并发:

更精准更灵敏的弱网识别,弱网下对关键核心业务进行倾斜。

4)HTTPDNS的push能力:

HTTPDNS打通APM的质量监控体系后,通过push及时下线故障IP。

关于移动端DNS问题上的优化,业内已经有了很多总结,有兴趣可以深入研究:

全面了解移动端DNS域名劫持等杂症:技术原理、问题根源、解决方案等

美图App的移动端DNS优化实践:HTTPS请求耗时减小近半

百度APP移动端网络深度优化实践分享(一):DNS优化篇

移动端网络优化之HTTP请求的DNS优化

附录:更多网络通信方面的技术资料

TCP/IP详解 - 第11章·UDP:用户数据报协议

TCP/IP详解 - 第17章·TCP:传输控制协议

TCP/IP详解 - 第18章·TCP连接的建立与终止

TCP/IP详解 - 第21章·TCP的超时与重传

技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)

通俗易懂-深入理解TCP协议(上):理论基础

通俗易懂-深入理解TCP协议(下):RTT、滑动窗口、拥塞处理

理论经典:TCP协议的3次握手与4次挥手过程详解

理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程

计算机网络通讯协议关系图(中文珍藏版)

UDP中一个包的大小最大能多大?

P2P技术详解(一):NAT详解——详细原理、P2P简介

P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解(基本原理篇)

P2P技术详解(三):P2P中的NAT穿越(打洞)方案详解(进阶分析篇)

P2P技术详解(四):P2P技术之STUN、TURN、ICE详解

通俗易懂:快速理解P2P技术中的NAT穿透原理

高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少

高性能网络编程(二):上一个10年,著名的C10K并发连接问题

高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了

高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索

高性能网络编程(五):一文读懂高性能网络编程中的I/O模型

高性能网络编程(六):一文读懂高性能网络编程中的线程模型

Java的BIO和NIO很难懂?用代码实践给你看,再不懂我转行!

不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)

不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)

不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT

不为人知的网络编程(四):深入研究分析TCP的异常关闭

不为人知的网络编程(五):UDP的连接性和负载均衡

不为人知的网络编程(六):深入地理解UDP协议并用好它

不为人知的网络编程(七):如何让不可靠的UDP变的可靠?

不为人知的网络编程(八):从数据传输层深度解密HTTP

不为人知的网络编程(九):理论联系实际,全方位深入理解DNS

网络编程懒人入门(一):快速理解网络通信协议(上篇)

网络编程懒人入门(二):快速理解网络通信协议(下篇)

网络编程懒人入门(三):快速理解TCP协议一篇就够

网络编程懒人入门(四):快速理解TCP和UDP的差异

网络编程懒人入门(五):快速理解为什么说UDP有时比TCP更有优势

网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门

网络编程懒人入门(七):深入浅出,全面理解HTTP协议

网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接

网络编程懒人入门(九):通俗讲解,有了IP地址,为何还要用MAC地址?

网络编程懒人入门(十):一泡尿的时间,快速读懂QUIC协议

网络编程懒人入门(十一):一文读懂什么是IPv6

技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解

让互联网更快:新一代QUIC协议在腾讯的技术实践分享

现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障

聊聊iOS中网络编程长连接的那些事

移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”

移动端IM开发者必读(二):史上最全移动弱网络优化方法总结

IPv6技术详解:基本概念、应用现状、技术实践(上篇)

IPv6技术详解:基本概念、应用现状、技术实践(下篇)

从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路

脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?

脑残式网络编程入门(三):HTTP协议必知必会的一些知识

脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)

脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?

脑残式网络编程入门(六):什么是公网IP和内网IP?NAT转换又是什么鬼?

脑残式网络编程入门(七):面视必备,史上最通俗计算机网络分层详解

脑残式网络编程入门(八):你真的了解127.0.0.1和0.0.0.0的区别?

以网游服务端的网络接入层设计为例,理解实时通信的技术挑战

迈向高阶:优秀Android程序员必知必会的网络基础

全面了解移动端DNS域名劫持等杂症:技术原理、问题根源、解决方案等

美图App的移动端DNS优化实践:HTTPS请求耗时减小近半

Android程序员必知必会的网络通信传输层协议——UDP和TCP

IM开发者的零基础通信技术入门(一):通信交换技术的百年发展史(上)

IM开发者的零基础通信技术入门(二):通信交换技术的百年发展史(下)

IM开发者的零基础通信技术入门(三):国人通信方式的百年变迁

IM开发者的零基础通信技术入门(四):手机的演进,史上最全移动终端发展史

IM开发者的零基础通信技术入门(五):1G到5G,30年移动通信技术演进史

IM开发者的零基础通信技术入门(六):移动终端的接头人——“基站”技术

IM开发者的零基础通信技术入门(七):移动终端的千里马——“电磁波”

IM开发者的零基础通信技术入门(八):零基础,史上最强“天线”原理扫盲

IM开发者的零基础通信技术入门(九):无线通信网络的中枢——“核心网”

IM开发者的零基础通信技术入门(十):零基础,史上最强5G技术扫盲

IM开发者的零基础通信技术入门(十一):为什么WiFi信号差?一文即懂!

IM开发者的零基础通信技术入门(十二):上网卡顿?网络掉线?一文即懂!

IM开发者的零基础通信技术入门(十三):为什么手机信号差?一文即懂!

IM开发者的零基础通信技术入门(十四):高铁上无线上网有多难?一文即懂!

IM开发者的零基础通信技术入门(十五):理解定位技术,一篇就够

百度APP移动端网络深度优化实践分享(一):DNS优化篇

百度APP移动端网络深度优化实践分享(二):网络连接优化篇

百度APP移动端网络深度优化实践分享(三):移动端弱网优化篇

技术大牛陈硕的分享:由浅入深,网络编程学习经验干货总结

可能会搞砸你的面试:你知道一个TCP连接上能发起多少个HTTP请求吗?

知乎技术分享:知乎千万级并发的高性能长连接网关技术实践

5G时代已经到来,TCP/IP老矣,尚能饭否?

爱奇艺移动网络优化实践分享:网络请求成功率优化篇(iOS端)

>> 更多同类文章 ……

欢迎关注我的“即时通讯技术圈”公众号:

(本文已同步发布于:http://www.52im.net/thread-2981-1-1.html

posted @ 2020-04-21 14:20 Jack Jiang 阅读(174) | 评论 (0)编辑 收藏

本文同时发布于“即时通讯技术圈”公众号,链接是:https://mp.weixin.qq.com/s/cS5xB2DrjF52rmz6EGVJ6A

本文参考了公众号鲜枣课堂的“IPv6,到底是什么?”一文的部分内容,感谢原作者。

1、引言

现在IPv6的技术应用已经越来越普及了,很多应用都开始支持IPv6。

 

▲ 去年开始,支付宝的官网上就已出现“支持IPv6”标识

对于即时通讯技术(尤其是IM应用)的开发者来说,新产品上架苹果的App Store因IPv6问题被拒的情况,很常见。每次也都能根据网上的资料一一解决,并顺利通过审核。

然而几次下来,到底什么是IPv6,还是有点云里雾里。

那么,IP协议在TCP/IP体系中到底有多重要?看看下图便知(原因清晰版:从此处进入下载)。

 

▲ 红圈处就是IP协议,它几乎是整个TCP/IP协议簇的支撑(图引用自《计算机网络通讯协议关系图》)

总之,IP协议在TCP/IP体系中,是非常重要的一环(可以认为,没它,也就没有了互联网),作为IPv4的下一代协议,了解IPv6非常有必要。而作为即时通讯开发者来说,了解IPv6就显的尤为迫切,说不定某天你的IM就会因为IPv6问题而导致无法通信的局面出现。

本文将用浅显易懂的文字,带你了解到底什么是IPv6。

(本文同步发布于:http://www.52im.net/thread-2979-1-1.html

2、系列文章

本文是系列文章中的第11篇,本系列文章的大纲如下:

网络编程懒人入门(一):快速理解网络通信协议(上篇)

网络编程懒人入门(二):快速理解网络通信协议(下篇)

网络编程懒人入门(三):快速理解TCP协议一篇就够

网络编程懒人入门(四):快速理解TCP和UDP的差异

网络编程懒人入门(五):快速理解为什么说UDP有时比TCP更有优势

网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门

网络编程懒人入门(七):深入浅出,全面理解HTTP协议

网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接

网络编程懒人入门(九):通俗讲解,有了IP地址,为何还要用MAC地址?

网络编程懒人入门(十):一泡尿的时间,快速读懂QUIC协议

网络编程懒人入门(十一):一文读懂什么是IPv6》(本文)

3、复习一下什么是IPv4?

IPv4是Internet Protocol version 4的缩写,中文翻译为互联网通信协议第四版,通常简称为网际协议版本4。

IPv4使用32位(4字节)地址,因此地址空间中只有 4,294,967,296(即2^32) 个地址。

IPv4地址可被写作任何表示一个32位整数值的形式,但为了方便人类阅读和分析,它通常被写作点分十进制的形式,即四个字节被分开用十进制写出,中间用点分隔。

通常IPv4地址的地址格式为 nnn.nnn.nnn.nnn,就像下面这样:

172.16.254.1

下图看起来更清晰一些:

4、IPv6又是什么?

IPv6是Internet Protocol version 6的缩写,中文翻译为互联网通信协议(TCP/IP协议)第6版,通常简称为网际协议版6。IPv6具有比IPv4大得多的编码地址空间,用它来取代IPv4主要是为了解决IPv4地址枯竭问题,同时它也在其他方面对于IPv4有许多改进。

其实,IPv6并不是新技术,从IPv6最早的工作组成立1992年到现在,已过去27年。在互联网技术的发展历程中,IPv6年龄甚至有些太大了。

IPv6的“6”表示的是TCP/IP协议的第六个版本,IPv4的“4”表示的是TCP/IP协议的第四个版本。其实除了这两个版本,当然还有其它版本,TCP/IP协议其实从IPv1开始,到现在IPv10都已经出现了,这些不同版本之间并没有关联,也不是简单IP地址长度的长短。

IPv6地址由八组、每组四位16进制数字组成,每组之间由":"来分隔。

看个简单的例子:

2610:00f8:0c34:67f9:0200:83ff:fe94:4c36,每个“:”前后都是4位16进制的数字,共分隔成8组。

如下图所示: 

 

小知识:如何查看手机或者电脑的网络是否支持IPv6呢?

可以在你手机或者电脑上的浏览器中打开:Ipv6-test.com,就像下图这样: 

5、为什么要使用IPv6?

最主要的原因,就是地址数量不够用了。

IPv4迄今为止已经使用了30多年。最早期的时候,互联网只是设计给美国军方用的,根本没有考虑到它会变得如此庞大,成为全球网络。

尤其是进入21世纪后,随着计算机和智能手机的迅速普及,互联网开始爆发性发展,越来越多的上网设备出现,越来越多的人开始连接互联网。这就意味着,需要越来越多的IP地址。

IPv4的地址总数是2的32次方,也就是约42.9亿个。而全球的网民总数早已超过这个数目。

 

所以说,IPv4地址池接近枯竭,根本无法满足互联网发展的需要。人们迫切需要更高版本的IP协议,更大数量的IP地址池。(有点像固定电话号码升位。)

6、IPv6会带给我们什么?

首先,最重要的一点,就是前面所说的地址池扩容。IPv4的地址池是约42.9亿,IPv6能达到多少呢?

数量如下:

340282366920938463463374607431768211456个…

不用数了,太多了… 简单说,是2的128次方。

这个数量,即使是给地球上每一颗沙子都分配一个IP,也是妥妥够用的。

 

▲ 这图你看懂了吗?嗯,我也没看懂,反正就是很多的样子

这个数量值是怎么得来的呢?还是它的地址位长决定的。

如果以二进制来写,IPv6的地址是128位。不过,这样写显然不太方便(一行都写不下)。所以,通常用十六进制来写,也就缩短成32位(32位会分为8组,每组4位)。 

下面就是一个标准、合法的IPv6地址示例:

2001:0db8:85a3:08d3:1319:8a2e:0370:7344

注意:IPv6的地址是可以简写的,每项数字前导的0可以省略。

例如,下面这个地址:

2001:0DB8:02de:0000:0000:0000:0000:0e13

粉红的“0”就可以省略,变成:

2001: DB8:2de:0:0:0:0:e13

如果有一组或连续几组都是0,那么可以简写成“::”,也就是:

2001: DB8:2de::e13

注意:一个IPv6地址,只能有一个“::”。

为什么?很简单,你看下面这四个地址,如果所有0全都缩写,会变成什么样?

2001:0000:0000:0000:0000:25de:0000:cade

2001: 0000: 0000:0000:25de:0000:0000:cade

2001: 0000: 0000:25de:0000:0000:0000:cade

2001: 0000: 25de:0000:0000:0000:0000:cade

是的,都是2001::25de::cade,冲突了。所以,这个地址是非法的,不允许存在的。

关于IPv6还有很多技术细节,因篇幅原因,不再赘述。

除了地址数量之外,IPv6还有很多优点,例如:

1)IPv6使用更小的路由表。使得路由器转发数据包的速度更快;

2)IPv6增加了增强的组播支持以及对流的控制,对多媒体应用很有利,对服务质量(QoS)控制也很有利;

3)IPv6加入了对自动配置的支持。这是对DHCP协议的改进和扩展,使得网络(尤其是局域网)的管理更加方便和快捷;

4)IPv6具有更高的安全性。用户可以对网络层的数据进行加密并对IP报文进行校验,极大地增强了网络的安全性;

5)IPv6具有更好的扩容能力。如果新的技术或应用需要时,IPV6允许协议进行扩充;

6)IPv6具有更好的头部格式。IPV6使用新的头部格式,就简化和加速了路由选择过程,提高了效率;

……

7、IPv6的优点这么多,为什么之前普及却这么慢?

IPv6优点这么多,为什么它问世已经20年了,还是没有完全替代IPv4呢?这里面的水就很深了。。。说白了,主要还是和利益有关。

7.1 NAT这类技术,让IPv4得以续命

如果按照本世纪初专家们的预测,我们IPv4的地址早已枯竭几万次了。但是,一直挺到现在,大家仍然还在用IPv4,对老百姓来说,并没有因为地址不够而无法上网。

这是为什么呢? 就是因为除了IPv6之外,我们还有一些技术,可以变相地缓解地址不足。

例如NAT(Network Address Translation,网络地址转换)。

NAT是什么意思?当我们在家里或公司上网时,你的电脑肯定有一个类似192.168.0.1的地址,这种地址属于私网地址,不属于公共的互联网地址。

▲ 一个典型的NAT应用场景(图自《IPv6,到底是什么?》)

每一个小的局域网,都会使用一个网段的私网地址,在与外界连接时,再变换成公网地址。这样一来,几十个或几百个电脑,都只需要一个公网地址。

甚至还可以私网套私网,NAT套NAT,一层一层套。这样一来,大大节约了公网IP地址数量。正因为如此,才让我们“续命”到了今天,不至于无法上网。

但是,NAT这种方式也有很多缺点,虽然私网地址访问互联网地址方便,但互联网地址访问私网地址就困难了。很多服务,都会受到限制,你只能通过复杂的设置才能解决,也会影响网络的处理效率。

▲ NAT内网的计算机是不能被外网直接访问的(图自《IPv6,到底是什么?》)

7.2 升级IPv6涉及运营商的利益

物以稀为贵,地址越稀缺,就越值钱。掌握地址的人,就越开心。谁开心?运营商和ISP(互联网服务提供商)。

他们就像是经销商,从上游(互联网域名与号码分配机构,即ICANN)申请到IP地址,再卖给下游用户。稀缺没关系,反正,他一定能赚取更多的差价。

如果大家去找运营商或ISP买带宽,或者租赁云服务,带公共地址的,一定比不带公共地址的贵很多很多。

除了地址可以赚钱之外,如果升级支持IPv6,对运营商和ISP来说,也意味着很大的资金投入。现在新设备基本都是支持的,但毕竟还是有一些老设备,如果在使用寿命到期之前就换,就是亏钱。

所以,运营商和ISP都没有动力去启用IPv6。 

至于设备商或手机电脑厂商,出于提前考虑,早已普遍支持了IPv6,意见并不是很大,也决定不了什么。必竟,提供基础设施服务的运营商们更强势。

8、IPv6未来会怎样

随着5G时代的到来,有了IPv6的加持,万物互联或许会成为现实。对于我等实时通信类软件的开发人员来说,某些场景下,或许再也不需要为“P2P打洞”这种事情烦恼了。 

▲ 5G+IPv6,万物互联不是梦

未来已来,你准备好了吗?

9、参考资料

[1] IPv6入门教程

[2] IPv6,到底是什么?

[3] 关于IPv6的发展史!IPv6的秘密史!

[4] 科普:一文读懂IPv6是什么?

[5] 漫话:全球IPv4地址正式耗尽?到底什么是IPv4和IPv6?

附录:更多网络编程基础知识文章

TCP/IP详解 - 第11章·UDP:用户数据报协议

TCP/IP详解 - 第17章·TCP:传输控制协议

TCP/IP详解 - 第18章·TCP连接的建立与终止

TCP/IP详解 - 第21章·TCP的超时与重传

技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)

通俗易懂-深入理解TCP协议(上):理论基础

通俗易懂-深入理解TCP协议(下):RTT、滑动窗口、拥塞处理

理论经典:TCP协议的3次握手与4次挥手过程详解

理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程

计算机网络通讯协议关系图(中文珍藏版)

UDP中一个包的大小最大能多大?

P2P技术详解(一):NAT详解——详细原理、P2P简介

P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解(基本原理篇)

P2P技术详解(三):P2P中的NAT穿越(打洞)方案详解(进阶分析篇)

P2P技术详解(四):P2P技术之STUN、TURN、ICE详解

通俗易懂:快速理解P2P技术中的NAT穿透原理

高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少

高性能网络编程(二):上一个10年,著名的C10K并发连接问题

高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了

高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索

高性能网络编程(五):一文读懂高性能网络编程中的I/O模型

高性能网络编程(六):一文读懂高性能网络编程中的线程模型

Java的BIO和NIO很难懂?用代码实践给你看,再不懂我转行!

不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)

不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)

不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT

不为人知的网络编程(四):深入研究分析TCP的异常关闭

不为人知的网络编程(五):UDP的连接性和负载均衡

不为人知的网络编程(六):深入地理解UDP协议并用好它

不为人知的网络编程(七):如何让不可靠的UDP变的可靠?

不为人知的网络编程(八):从数据传输层深度解密HTTP

不为人知的网络编程(九):理论联系实际,全方位深入理解DNS

技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解

让互联网更快:新一代QUIC协议在腾讯的技术实践分享

现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障

聊聊iOS中网络编程长连接的那些事

移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”

移动端IM开发者必读(二):史上最全移动弱网络优化方法总结

IPv6技术详解:基本概念、应用现状、技术实践(上篇)

IPv6技术详解:基本概念、应用现状、技术实践(下篇)

从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路

脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?

脑残式网络编程入门(三):HTTP协议必知必会的一些知识

脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)

脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?

脑残式网络编程入门(六):什么是公网IP和内网IP?NAT转换又是什么鬼?

脑残式网络编程入门(七):面视必备,史上最通俗计算机网络分层详解

脑残式网络编程入门(八):你真的了解127.0.0.1和0.0.0.0的区别?

以网游服务端的网络接入层设计为例,理解实时通信的技术挑战

迈向高阶:优秀Android程序员必知必会的网络基础

全面了解移动端DNS域名劫持等杂症:技术原理、问题根源、解决方案等

美图App的移动端DNS优化实践:HTTPS请求耗时减小近半

Android程序员必知必会的网络通信传输层协议——UDP和TCP

IM开发者的零基础通信技术入门(一):通信交换技术的百年发展史(上)

IM开发者的零基础通信技术入门(二):通信交换技术的百年发展史(下)

IM开发者的零基础通信技术入门(三):国人通信方式的百年变迁

IM开发者的零基础通信技术入门(四):手机的演进,史上最全移动终端发展史

IM开发者的零基础通信技术入门(五):1G到5G,30年移动通信技术演进史

IM开发者的零基础通信技术入门(六):移动终端的接头人——“基站”技术

IM开发者的零基础通信技术入门(七):移动终端的千里马——“电磁波”

IM开发者的零基础通信技术入门(八):零基础,史上最强“天线”原理扫盲

IM开发者的零基础通信技术入门(九):无线通信网络的中枢——“核心网”

IM开发者的零基础通信技术入门(十):零基础,史上最强5G技术扫盲

IM开发者的零基础通信技术入门(十一):为什么WiFi信号差?一文即懂!

IM开发者的零基础通信技术入门(十二):上网卡顿?网络掉线?一文即懂!

IM开发者的零基础通信技术入门(十三):为什么手机信号差?一文即懂!

IM开发者的零基础通信技术入门(十四):高铁上无线上网有多难?一文即懂!

IM开发者的零基础通信技术入门(十五):理解定位技术,一篇就够

百度APP移动端网络深度优化实践分享(一):DNS优化篇

百度APP移动端网络深度优化实践分享(二):网络连接优化篇

百度APP移动端网络深度优化实践分享(三):移动端弱网优化篇

技术大牛陈硕的分享:由浅入深,网络编程学习经验干货总结

可能会搞砸你的面试:你知道一个TCP连接上能发起多少个HTTP请求吗?

知乎技术分享:知乎千万级并发的高性能长连接网关技术实践

5G时代已经到来,TCP/IP老矣,尚能饭否?

>> 更多同类文章 ……

欢迎关注我的“即时通讯技术圈”公众号: 

(本文同步发布于:http://www.52im.net/thread-2979-1-1.html

posted @ 2020-04-17 11:21 Jack Jiang 阅读(267) | 评论 (0)编辑 收藏

本文已同时发布于我的“即时通讯技术圈”公众号。

1、引言

哈罗,大家好,我是Jack Jiang。。。(一股浓浓的自媒体视频旁白味道)。

对于经常看我文章的即时通讯开发者来说,今天要讨论的这个话题,貌似有点不着边际。

是的,自从我整理完《IM开发者的零基础通信技术入门》系列文章之后,对于网络编程的理解,开始有点飘了。

言归正传。现在,5G技术离我们的生活越来越近了,号称网络延迟1ms、下行速度10Gb/s的5G,在这样逆天的网络性能指标下,老骥伏枥的TCP/IP是否仍能Hold的住?带着这个思考,便有了本文的内容。

 

▲ 5G网速有多快?看图感受一下(图自《零基础,史上最强5G技术扫盲》)

(本文已同步发布于:http://www.52im.net/thread-2976-1-1.html

2、学好TCP/IP够用吗?

对于即时通讯技术的开发者,从技术栈来说,一条最普通的聊天消息的送达,肯定要涉及到网络编程技术,而网络编程最核心的也就是TCP/IP协议(准确的说是TCP/IP协议簇,见《TCP/IP详解》),毫无疑问深入的学习TCP/IP协议肯定是非常有必要了。

基本上,对于普通的IM或消息推送系统开发来说,对TCP/IP相关的计算机网络基础比较熟悉的话,完全够用了。

 

▲ 这本书很多人都读过

3、移动网络问题,只能赖我代码烂?

亲手写过即时通讯的网络通信层的同学都很清楚,在移动网络中(我说的移动网络具体指的是运营商的2g/3g/4g/5g这些),因为无线通信的介质和技术实现特殊性,出现了很多传统有线互联网不曾有过的网络通信问题。

就拿IM在移动弱网中出现的各种问题来说,多数开发者都不自信的认为这应该是自已的网络层代码写的不够优秀,是的,很多时候也确实是这样。

我收集整理的下面这几篇资料,就讨论的是这些,有兴趣可以读一下:

现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障

百度APP移动端网络深度优化实践分享(三):移动端弱网优化篇

微信移动端应对弱网络情况的探索和实践PPT [附件下载]

YY直播在移动弱网环境下的深度优化实践分享(视频+PPT)[附件下载]

其实,很少有人会去思考,在TCP/IP协议被发明出来的50年后,对于现代的移动网络来说,是否仍然能工作的好?以弱网问题为例,难道我写的IM总是丢消息、掉线就仅仅是“我”的代码太烂? 

没错,这不仅仅是应用层的代码编写问题,它或许涉及到TCP/IP的设计局限,甚至移动网络的底层设计也并不是最完美的。

下面这两篇文章,对于弱网问题思考,已经深入到运营商的通信技术这一层,强烈建议读一读:

移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”

移动端IM开发者必读(二):史上最全移动弱网络优化方法总结

如果你的认知,已经开始对底层的网络通信技术有所困惑,下面这几篇就是为你准备的:

IM开发者的零基础通信技术入门(六):移动终端的接头人——“基站”技术

IM开发者的零基础通信技术入门(七):移动终端的千里马——“电磁波”

IM开发者的零基础通信技术入门(八):零基础,史上最强“天线”原理扫盲

IM开发者的零基础通信技术入门(九):无线通信网络的中枢——“核心网”

IM开发者的零基础通信技术入门(十):零基础,史上最强5G技术扫盲

IM开发者的零基础通信技术入门(十一):为什么WiFi信号差?一文即懂!

IM开发者的零基础通信技术入门(十二):上网卡顿?网络掉线?一文即懂!

IM开发者的零基础通信技术入门(十三):为什么手机信号差?一文即懂!

IM开发者的零基础通信技术入门(十四):高铁上无线上网有多难?一文即懂!

4、简单复习一下TCP/IP

从字面意义上讲,有人可能会认为 TCP/IP 是指 TCP 和 IP 两种协议。实际生活当中有时也确实就是指这两种协议。

然而在很多情况下,它只是利用 IP 进行通信时所必须用到的协议簇的统称。

具体来说,IP 或 ICMP、TCP 或 UDP、TELNET 或 FTP、以及 HTTP 等都属于 TCP/IP 协议。他们与 TCP 或 IP 的关系紧密,是互联网必不可少的组成部分。TCP/IP 一词泛指这些协议,因此,有时也称 TCP/IP 为网际协议簇。

互联网进行通信时,需要相应的网络协议,TCP/IP 原本就是为使用互联网而开发制定的协议簇。因此,互联网的协议就是 TCP/IP,TCP/IP 就是互联网的协议。 

▲ 上图反映了TCP/IP协议族的关系(图片引用自《计算机网络通讯协议关系图》)

5、TCP/IP或许太老了

对于现代移动网络来说,TCP/IP或许太老了。我们简单了解一下TCP/IP协议的产生过程。

1973年:卡恩与瑟夫开发出了TCP/IP协议中最核心的两个协议:TCP协议和IP协议。

1974年:卡恩与瑟夫正式发表了TCP/IP协议并对其进行了详细的说明。同时,为了验证TCP/IP协议的可用性,使一个数据包由一端发出,在经过近10万km的旅程后到达服务端。在这次传输中,数据包没有丢失一个字节,这充分说明了TCP/IP协议的成功。

1983年:TCP/IP协议正式替代NCP,从此以后TCP/IP成为大部分因特网共同遵守的一种网络规则。

1984年:TCP/IP协议得到美国国防部的肯定,成为多数计算机共同遵守的一个标准。 

是的,你没有看错,TCP/IP协议设计于距今50年前!

 

▲ 罗伯特·卡恩(左者)与文特·瑟夫(右者)(图片引用自《技术往事:改变世界的TCP/IP协议》)

6、TCP/IP原本是为固定网络设计的

虽然TCP/IP自上世纪70年代发明以来,连接了无数的计算机,推动了互联网的蓬勃发展。

但不可回避的现实是,基于TCP/IP的互联网,它的初衷是为固定网络和网络互连而设计,而今天我们已经发展到了移动互联时代。

再往后看,未来5G将面临AR/VR、超高清视频、物联网、车联网等各种应用、用例纷呈,加之网络安全的紧迫性越发凸显,TCP/IP或许难以适应未来。

7、TCP/IP或许并不适合移动网络

7.1 TCP/IP设计之初无法预见高速移动网时代

在TCP/IP刚被设计的年代,即传统固定互联网的公元元年,主机是固定的,用于编址的IP也是固定的,世界是平的。

可是随着应用程序以及芯片技术的活力涌现,设备越来越小,App越来越丰富,当你觉得浑身憋得慌的时候,移动互联网时代来了。

但传统的TCP/IP并不适合移动网络,以TCP/IP协议簇中我们最常用的TCP协议来说,传统的TCP基于TCP/IP协议头字段的五元组,而标识设备的IP地址仅仅标识了设备位置,并没有标识设备本身(实际上不管到了什么年代,IP地址都不应该标识设备本身,它就是标识位置的!问题是,TCP不应该用一个标识位置的元素来标识设备)。

而对于移动互联网来说,一旦移动设备(比如智能手机)换了位置(通信基站切换了),其IP地址也会改变,进而既有的TCP连接将全部中断。

 

▲ 运营商的基站是有覆盖范围的,而且覆盖范围并不大

对于底层的移动网络通信技术有所了解的开发人员或许知道,手机的通信是由基站进行代理的,而基站是固定的。换句话说,当你移动到下一个基站的位置时,手机就得自动切换到新的基站,进而重新进行一系列的跟运营商的无线体系进行连接建立的过程。

这在日常生活中使用并没有什么问题,但在时速达到350公里每小时的复兴号高铁上用手机上网时,这就会导致严重的问题。因为基站的信号覆盖范围有限,在手机移动速度如此之快的情况下,基站的切换也将频繁到让网络工程师们崩溃(有兴趣可以读一下《IM开发者的零基础通信技术入门(十四):高铁上无线上网有多难?一文即懂!》)。

TCP/IP和网络的关系,可以作个有趣的类比。

假设互联网是公路,那么TCP/IP这就是这条公路上的一套交通规则。这套规则在制定时,可能考虑到的只是普通的市场内道路(最多是高速公路使用),而现在的5G时代,就好比时速350公里的高速铁路,试想普通的市内交通规则套用在高速铁路上,那难道不算是灾难吗。

必竟普通的市内交通速度不会很快,各种规则的制定误差和余量可以比较大,但高速铁路上,速度飞快、交通信号控制精确无比的情况下,这套规则,对于开高铁的司机来说,肯定是胆颤心惊。而TCP/IP对于5G来说,就好比这套老的交通规则,用它来驾驭这么快速的5G快车,是不是很疯狂?

 

7.2 TCP/IP与电信网的基因不同

基于TCP/IP的互联网原本是为固定网络和网络互联设计,而运营商的移动网络是为移动性连接而生。互联网的连接是分布式的,而移动通信网络是集中控制的。

这两者的技术基因确实有很大不同,在早期移动网络网络性能较慢的情况下,这两者的结合,矛盾似乎并不突出。

实际上,在传统电信网(就是大家最常用的电话、短信网络)与IT互联网是两拨人各自有玩耍(电信网为代表的就是3GPP标准化组织,互联网为代表的就是IETF标准化组织)。

在那个移动网还不发达的年代,这两拨人各自玩各自的,大家谁也不用鸟谁。

随着人们对移动上网需求越来越旺盛,搞电信网的这拨人只能想办法接入传统的互联网,必竟在当时传统互联网太强势,而移动网的应用场景还在摸索阶段,为了能快速解决移动上网的问题,与是也不好麻烦IETF这拨人,所有痛苦默默承受——虽然TCP/IP在移动网上的实施并不合适,但只能想办法缝缝补补,把移动网的标准制定,往它上面靠。

这就好比,TCP/IP这辆车已经造好了,至于你搞移动网的人,是修一条普通马路(2G)、还是一条高速公司路(3G)、或者是现在的高速铁路(5G),反正你只能将就这辆车。原本应该是什么路上跑什么车,而现在是不管你什么路,只能跑这辆车。反正车子跑不好,不怪车子,怪路。。

好奇葩的逻辑,而这个逻辑就好比是现在的TCP/IP跟移动网的关系。

所以,在5G,甚至未来的6G、7G时代,这种“勉强”的结合,抛必带来网络低效、基础设施成本高昂等问题。

8、移动运营商们已经意识到问题

是的,大佬们已经意识到了问题的严重性,正在着手解决。

2020年4月初,欧洲电信标准协会(ETSI)已成立了一个新的行业规范工作组“Non-IP Networking”(ISG NIN),以解决新服务、尤其是5G服务面临的老式网络协议所存在的问题。

▲ 详细新闻内容《点此查看

该工作组的目标是为5G网络研究开发新的网络协议,以替代TCP/IP。

是的,这些移动运营商已经发现在4G、甚至5G网络中使用的基于TCP/IP的技术存在一些问题。

由于TCP/IP协议最初是为互联网设计,而非为移动通信网络而生,当移动通信网络引入TCP/IP后,增加了移动性、安全性、QoS等功能,这使得网络更复杂,频谱使用效率较低。为了解决这些问题,后续的修补和替代方案又导致了成本、时延和功耗增加。

大佬们终于承认,对于5G的某些高级服务,TCP/IP确实被认为不是最佳的。

9、移动网络未来会怎样?

虽然TCP/IP可能越来越难以适应移动网络的发展,但不可否认,短期内TCP/IP的不可替代性。

必竟,基于TCP/IP的传统互联网所构建的软件和硬件世界(尤其是硬件)并不是一朝一夕的事,而替换掉这些,无论是从成本还是各方利益来说,都是个需要反复权衡和博弈的事。

一个很好的例子是,IPv4和IPv6,虽然谁都知道IPv4的困境,但IPv6喊了这么多年目前想要普及,仍然还比较遥远,要知道IPv6已经喊了10年了。因为这小小的IP地址,牵涉的是互联网从硬到软几乎所有环节,影响之大,无出其右。

对于IM开发者来说,因为移动网络的特殊性,而技术改朝换代也并不鲜见。

比如众所周之的XMPP协议,设计之初也是野心勃勃——“要让上IM就像打开网页一样简单!”。确实,XMPP无论是肉眼可读性,还是数据结构的优雅,都非常优秀,但悲剧的是,设计者们从来没有想过移动网会发展成今天这样,或者说设计者们从未考虑过XMPP在移动网下的使用。于是,后面的故事,大家都很清楚——每个人都在抱怨XMPP臃肿、冗余(是的,这里我收集了一大堆这样的文章),这算个是把优点做成缺点的典型案例了。

或许,未来会有那么一天,移动网络终有属于为自已定制的网络协议标准。而对于搞网络通信的程序员来说,如果这套新的标准让能基于移动网络的代码编写,变的愉快起来,那真是谢天谢地了!

10、参考资料

[1] TCP/IP 已完 ?New IP 之后,又来一个 Non-IP

[2] 5G:再见,TCP/IP

[3] 重新设计TCP/IP协议栈以支持设备移动性

[4] 5G要抛弃TCP/IP?

[5] ETSI LAUNCHES NEW GROUP ON NON-IP NETWORKING ADDRESSING 5G NEW SERVICES

附录:更多网络编程基础资料

TCP/IP详解 - 第11章·UDP:用户数据报协议

TCP/IP详解 - 第17章·TCP:传输控制协议

TCP/IP详解 - 第18章·TCP连接的建立与终止

TCP/IP详解 - 第21章·TCP的超时与重传

技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)

通俗易懂-深入理解TCP协议(上):理论基础

通俗易懂-深入理解TCP协议(下):RTT、滑动窗口、拥塞处理

理论经典:TCP协议的3次握手与4次挥手过程详解

理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程

计算机网络通讯协议关系图(中文珍藏版)

UDP中一个包的大小最大能多大?

P2P技术详解(一):NAT详解——详细原理、P2P简介

P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解(基本原理篇)

P2P技术详解(三):P2P中的NAT穿越(打洞)方案详解(进阶分析篇)

P2P技术详解(四):P2P技术之STUN、TURN、ICE详解

通俗易懂:快速理解P2P技术中的NAT穿透原理

高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少

高性能网络编程(二):上一个10年,著名的C10K并发连接问题

高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了

高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索

高性能网络编程(五):一文读懂高性能网络编程中的I/O模型

高性能网络编程(六):一文读懂高性能网络编程中的线程模型

Java的BIO和NIO很难懂?用代码实践给你看,再不懂我转行!

不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)

不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)

不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT

不为人知的网络编程(四):深入研究分析TCP的异常关闭

不为人知的网络编程(五):UDP的连接性和负载均衡

不为人知的网络编程(六):深入地理解UDP协议并用好它

不为人知的网络编程(七):如何让不可靠的UDP变的可靠?

不为人知的网络编程(八):从数据传输层深度解密HTTP

不为人知的网络编程(九):理论联系实际,全方位深入理解DNS

网络编程懒人入门(一):快速理解网络通信协议(上篇)

网络编程懒人入门(二):快速理解网络通信协议(下篇)

网络编程懒人入门(三):快速理解TCP协议一篇就够

网络编程懒人入门(四):快速理解TCP和UDP的差异

网络编程懒人入门(五):快速理解为什么说UDP有时比TCP更有优势

网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门

网络编程懒人入门(七):深入浅出,全面理解HTTP协议

网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接

网络编程懒人入门(九):通俗讲解,有了IP地址,为何还要用MAC地址?

网络编程懒人入门(十):一泡尿的时间,快速读懂QUIC协议

技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解

让互联网更快:新一代QUIC协议在腾讯的技术实践分享

现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障

聊聊iOS中网络编程长连接的那些事

移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”

移动端IM开发者必读(二):史上最全移动弱网络优化方法总结

IPv6技术详解:基本概念、应用现状、技术实践(上篇)

IPv6技术详解:基本概念、应用现状、技术实践(下篇)

从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路

脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?

脑残式网络编程入门(三):HTTP协议必知必会的一些知识

脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)

脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?

脑残式网络编程入门(六):什么是公网IP和内网IP?NAT转换又是什么鬼?

脑残式网络编程入门(七):面视必备,史上最通俗计算机网络分层详解

脑残式网络编程入门(八):你真的了解127.0.0.1和0.0.0.0的区别?

以网游服务端的网络接入层设计为例,理解实时通信的技术挑战

迈向高阶:优秀Android程序员必知必会的网络基础

全面了解移动端DNS域名劫持等杂症:技术原理、问题根源、解决方案等

美图App的移动端DNS优化实践:HTTPS请求耗时减小近半

Android程序员必知必会的网络通信传输层协议——UDP和TCP

IM开发者的零基础通信技术入门(一):通信交换技术的百年发展史(上)

IM开发者的零基础通信技术入门(二):通信交换技术的百年发展史(下)

IM开发者的零基础通信技术入门(三):国人通信方式的百年变迁

IM开发者的零基础通信技术入门(四):手机的演进,史上最全移动终端发展史

IM开发者的零基础通信技术入门(五):1G到5G,30年移动通信技术演进史

IM开发者的零基础通信技术入门(六):移动终端的接头人——“基站”技术

IM开发者的零基础通信技术入门(七):移动终端的千里马——“电磁波”

IM开发者的零基础通信技术入门(八):零基础,史上最强“天线”原理扫盲

IM开发者的零基础通信技术入门(九):无线通信网络的中枢——“核心网”

IM开发者的零基础通信技术入门(十):零基础,史上最强5G技术扫盲

IM开发者的零基础通信技术入门(十一):为什么WiFi信号差?一文即懂!

IM开发者的零基础通信技术入门(十二):上网卡顿?网络掉线?一文即懂!

IM开发者的零基础通信技术入门(十三):为什么手机信号差?一文即懂!

IM开发者的零基础通信技术入门(十四):高铁上无线上网有多难?一文即懂!

IM开发者的零基础通信技术入门(十五):理解定位技术,一篇就够

百度APP移动端网络深度优化实践分享(一):DNS优化篇

百度APP移动端网络深度优化实践分享(二):网络连接优化篇

百度APP移动端网络深度优化实践分享(三):移动端弱网优化篇

技术大牛陈硕的分享:由浅入深,网络编程学习经验干货总结

可能会搞砸你的面试:你知道一个TCP连接上能发起多少个HTTP请求吗?

知乎技术分享:知乎千万级并发的高性能长连接网关技术实践

5G时代已经到来,TCP/IP老矣,尚能饭否?

>> 更多同类文章 ……

欢迎关注我的“即时通讯技术圈”公众号: 

(本文已同步发布于:http://www.52im.net/thread-2976-1-1.html

posted @ 2020-04-13 23:41 Jack Jiang 阅读(300) | 评论 (0)编辑 收藏

     摘要: 本文作者腾讯WXG后台开发工程师jeryyzhang,收录时有改动,感谢原作者的分享。1、引言大约3年前,微信技术团队分享了《微信后台基于时间序的海量数据冷热分级架构设计实践》一文,文中总结了微信这种超级IM基于时间序的海量数据存储架构的设计实践,也得以让大家了解了微信后台的架构设计思路。时隔3年,微信再次分享了基于时间序的新一代海量数据存储架构的设计实践(可以认为是《微信后台基于时间序的海量数据...  阅读全文

posted @ 2020-04-09 15:07 Jack Jiang 阅读(203) | 评论 (0)编辑 收藏

     摘要: 一、引言2020年春节早已过去两月有余,回顾本次腾讯手Q春节红包活动的玩法,主要以答题形式结合中国传统文化(成语、诗词、对联、历史等)的方式进行,达到寓教于乐的效果。 ▲ 2020年春节QQ的红包活动对于这种大体量的IM社交应用运营活动,技术上除了前端、后台的大力支撑,对于手Q客户端来说,又是从哪些方面来保证整个红包活动的灵活性、稳定性和用户体验的呢?带着这个问题,我们一起来...  阅读全文

posted @ 2020-04-06 23:41 Jack Jiang 阅读(181) | 评论 (0)编辑 收藏

     摘要: 本文原文由微信客户端高级工程师方秋枋原创发表于WeMobileDev公众号,收录时有修订和加工,感谢作者的无私分享。1、引言作为一个重要业务,微信支付在客户端上面临着各种问题。其中最核心问题就是分平台实现导致的问题:1)iOS 和安卓实现不一致:容易出 Bug、通过沟通保证不了质量;2)扩展性差且无法快速响应业务需求:需求变更迭代周期长、数据上报不全面;3)质量保障体系不完善:缺少业务及设计知识沉...  阅读全文

posted @ 2020-03-25 17:00 Jack Jiang 阅读(291) | 评论 (0)编辑 收藏

     摘要: 1、引言很多人一想到IM应用开发,第一印象就是“长连接”、“socket”、“保活”、“协议”这些关键词,没错,这些确实是IM开发中肯定会涉及的技术范畴。但,当你真正开始编写第一行代码时,最现实的问题实际上是“聊天消息ID该怎么生成?”这个看似微不足道的小事情。说它看似微不足道,...  阅读全文

posted @ 2020-03-19 17:34 Jack Jiang 阅读(239) | 评论 (0)编辑 收藏

本文原文由作者Amazing10原创发布于公众号业余码农,收录时有改动,感谢原作者的技术分享。

1、引言

某天中午,吃完午饭,摊在自己的躺椅上,想趁吃饱喝足的午后时间静静享受独自的静谧。

 
 

干点什么好呢?于是单手操作鼠标打开了一个陌生而隐秘的网站。正开着某个视频起劲。。。

突然浏览器弹出了一个提示:

请使用微信扫码登录账号,继续观看

这...

 
 

但是由于强烈的好奇驱使,迫于无奈,只好选择登录再继续观看。于是熟练的掏出手机,打开微信扫一扫对准上面的二维码,只听见 “叮” 的一声,网页上的二维码放佛活过来了,直接刷新出了本尊的微信头像,同时手机上也弹出登录的提醒。

 
 

心中略微惊叹,但没来得及多想。忙点击手机界面中登录按钮。此时网页刷新,恢复了正常,表示可以继续观看。

上网冲浪的时间总是过得很快,很快就有些疲倦。于是闭上眼睛,脑海中却浮现出了刚刚微信扫描二维码,然后登录网页的场景,心中再次惊叹,并开始思考起其中的原理来。。。

言归正传,本文将以轻松活泼的语言形式,为你分析和讲解微信手机扫码登录的技术原理,希望在你的IM中开发此功能时有所启发。

推荐阅读:另一篇同类文章《IM的扫码登录功能如何实现?一文搞懂主流的扫码登录技术原理》也值得一读。

学习交流:

- 即时通讯/推送技术开发交流5群:215477170[推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

(本文同步发布于:http://www.52im.net/thread-2941-1-1.html

2、IM开发干货系列文章

本文是系列文章中的第23篇,总目录如下:

IM消息送达保证机制实现(一):保证在线实时消息的可靠投递

IM消息送达保证机制实现(二):保证离线消息的可靠投递

如何保证IM实时消息的“时序性”与“一致性”?

IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?

IM群聊消息如此复杂,如何保证不丢不重?

一种Android端IM智能心跳算法的设计与实现探讨(含样例代码)

移动端IM登录时拉取数据如何作到省流量?

通俗易懂:基于集群的移动端IM接入层负载均衡方案分享

浅谈移动端IM的多点登录和消息漫游原理

IM开发基础知识补课(一):正确理解前置HTTP SSO单点登录接口的原理

IM开发基础知识补课(二):如何设计大量图片文件的服务端存储架构?

IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议

IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token

IM群聊消息的已读回执功能该怎么实现?

IM群聊消息究竟是存1份(即扩散读)还是存多份(即扩散写)?

IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列

一个低成本确保IM消息时序的方法探讨

IM开发基础知识补课(六):数据库用NoSQL还是SQL?读这篇就够了!

IM里“附近的人”功能实现原理是什么?如何高效率地实现它?

IM开发基础知识补课(七):主流移动端账号登录方式的原理及设计思路

IM开发基础知识补课(八):史上最通俗,彻底搞懂字符乱码问题的本质

IM的扫码登功能如何实现?一文搞懂主流应用的扫码登录技术原理

IM要做手机扫码登陆?先看看微信的扫码登录功能技术原理》(本文)

3、原理解析

微信扫码登录现在在日常生活中已经是常见不能再常见的场景之一了,但是要知道微信首次公开这项功能时,却是惊艳众人。移动端与PC端以这样一种巧妙的方式链接在了一起,的确是让人惊叹。

以下是一个典型的微信扫码登录全过程: 

本来想在Web版微信上截图,但扫码登陆后出现了下面的提示(貌似很多人都碰到过): 

好吧,这很微信,反正就是不想让你好好用,用户爱咋咋滴。。。

如上图所示,操作过程如下:

1)第一步:电脑上打开PC端(出现2维码);

2)第二步:拿出手机,扫码2维码;

3)第三步:PC端显示扫码成功;

4)第四步:手机端“确认”登录;

5)第五步:成功登陆PC端。

上述实际操作过程,用户体验相当顺滑,也难怪刚出来那会,能惊艳到很多人。

那么,对于上述操作过程的技术实现原理是什么样的呢?

想起来之前听过的前后端的概念,知道账户的数据信息一般都是放在服务器上,前端负责向后端 “讨要数据” 并显示,后端则是对前端的 “讨要” 做出反应。

这样一来,猜测微信登录的过程可能就是:

1)网页前端向微信后台请求账号数据;

2)微信后台接受网页前端的请求,然后将他的账号数据返回;

3)网页前端接收到了数据后,在浏览器里进行显示。

于是,手脚麻利的画了个示意图:

当我正准备沾沾自喜的时候,突然看到桌面上的手机。咦,如果就只是这么个过程,那手机的作用是啥。于是才开始意识到,问题没这么简单。

好吧,我们城要再深入一点探秘微信扫码登录的过程。

4、过程分析

为了更深入的分析整个过程,我们可以去看看微信网页版,地址是:https://wx.qq.com/

 

笔者看着网页中硕大的二维码陷入了沉思——这个二维码跟手机账号有没有什么对应关系呢?如果没有,那它又是怎么生成的呢?

思考间,于是打开了浏览器的开发者工具。

在网络监控一览找到了这幅二维码,与之对应的链接是:

https://login.weixin.qq.com/qrcode/gaO8cOQweA==

如下图所示:

然后习惯性地,尝试多次刷新页面,发现二维码不断发生变化,链接也不断更改:

https://login.weixin.qq.com/qrcode/AencxgKNFQ==

https://login.weixin.qq.com/qrcode/YcD7f_DxvA==

https://login.weixin.qq.com/qrcode/QblN8lCn2g==

似乎发现了些东西:二维码不断变化,其对应的链接尾的代码也相应变化,并且是随机性的变化。

这也就是说,每一次页面刷新都会随机且唯一地生成一个二维码。这或许可以与手机登录的过程联系起来。

似乎开始明白了,于是再次拿起手机,熟练的使用微信扫描了此时的二维码。

“叮” 的一声,网页上的二维码顿时变成了我帅气的微信头像。这个时候,我才突然意识到,是扫码之后网页才与他的微信账号建立起了联系。

如下图所示: 

也就是说:

1)没有扫码之前,页面上的二维码只是随机生成的且与用户无关的码;

2)而当用户扫码之后,二维码便与用户帐号绑定在了一起。

原来手机扫码的用处是这样!

此时注意到,手机微信上弹出了『微信登录确认』的提醒。这个时候谨慎地点击了下方的登录按钮。

如下图所示: 

随着平滑的动画一闪而过,网页上已经显示出了我的微信账号信息,显示微信账号已经登录。再一次体验这个过程,心中开始思索手机微信在登录过程中所起到的具体作用。

首先需要明白几个过程:

1)进入网页登陆界面,随机生成一个二维码;

2)通过手机扫描二维码,将微信账号与二维码绑定;

3)在手机微信点击登录按钮,授权网页登录微信账号;

4)网页获得的账号信息,将数据显示。

5、原理解释

回顾上述过程,结合最开始的原理猜测,开始思索整个环节,是哪里理解的不对。。。

1)网页的二维码到底从何而来?

2)是谁向微信后台请求了账号数据?

实际上:不同的网站可能都需要通过微信后台进行数据的获取,那么每一个网站必然也存在它的后台来给微信后台发送请求。

这样一来,整个过程就能解释得通了:

1)网站页面刷新,网页后台向微信后台请求授权登录;

2)微信后台返回登录所需二维码;

3)用户通过手机扫描二维码,并在手机上授权登录后,微信后台告知网页后台已授权;

4)网页后台向微信后台请求微信账号数据;

5)微信后台返回账号数据;

6)网页后台接收数据并通过浏览器显示;

6、技术剖析

正如上节所述,想清楚了整个过程后,我们应该对整个过程的技术实现进行进一步的探究。

在微信开发官方文档中,我找到了第三方网站应用微信登录开发指南:

https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html

我将整个过程梳理了一遍,画出了这个图: 

如上图所示,整个技术实现如下。

(1)二维码的获得:

  • 1)用户打开网站后,网站后台根据微信OAuth2.0协议向微信开发平台请求授权登录,并传递事先在微信开发平台中审核通过的AppID和AppSecrect等参数;
  • 2)微信开发平台对AppID等参数进行验证,并向网站后台返回二维码;
  • 3)网站后台将二维码传送至网站前端进行显示。

(2)微信客户端授权登录:

  • 1)用户使用微信客户端扫描二维码并授权登录;
  • 2)微信客户端将二维码特定的uid与微信账号绑定,传送至微信开发平台;
  • 3)微信开发平台验证绑定数据,调用网站后台的回调接口,发送授权临时票据code;

(3)网站后台请求数据:

  • 1)网站后台接收到code,表明微信开发平台同意数据请求;
  • 2)网站后台根据code参数,再加上AppID和AppSecret请求微信开发平台换取access_token;
  • 3)微信开发平台验证参数,并返回access_token;
  • 4)网站后台收到access_token后即可进行参数分析获得用户账号数据。

在上述过程中,有几个参数值得解释一下(来源官方文档):

  • 1)AppID:应用唯一标识,在微信开放平台提交应用审核通过后获得;
  • 2)AppSecret:应用密钥,在微信开放平台提交应用审核通过后获得;
  • 3)code:授权临时票据,第三方通过code进行获取access_token的时候需要用到,code的超时时间为10分钟,一个code只能成功换取一次access_token即失效。code的临时性和一次性保障了微信授权登录的安全性。

整个过程从网站后台向微信开发平台请求授权登录开始,最终目的是为了获得access_token:

access_token:用户授权第三方应用发起接口调用的凭证

在获得了access_token后就可以解析用户的一些基本信息,包括头像、用户名、性别、城市等。这样一来,整个微信扫描登录的过程就完成了。

7、写在最后

研究到这,终于大体上对微信扫码登录的整个过程有了清晰的认知。看起来似乎也不难,开发者只需要在网页后端做好对微信公众平台的接口调用即可实现扫码登录。

伸了伸懒腰,忽然又想到在整个过程中还需要考虑超时的问题。比如二维码超时未扫描、二维码扫描后超时授权、获得access_token后超时等等问题。

我发现一个简单的功能实现起来还是需要考虑许多细节,真的是纸上得来终觉浅呀。于是我下定决心,下次得少上网冲浪了,花点时间搭个服务器先把微信扫码登录过程实现看看。

不过,还得先去在微信开放平台注册开发者帐号,并拥有一个已审核通过的网站应用,并获得相应的AppID和AppSecret才行。

想了想,还是让我先趟一会儿吧。。。

 

附录:更多IM开发相关文章

[1] IM开发热门文章:

新手入门一篇就够:从零开发移动端IM

移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”

移动端IM开发者必读(二):史上最全移动弱网络优化方法总结

从客户端的角度来谈谈移动端IM的消息可靠性和送达机制

现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障

腾讯技术分享:社交网络图片的带宽压缩技术演进之路

小白必读:闲话HTTP短连接中的Session和Token

移动端IM开发需要面对的技术问题

开发IM是自己设计协议用字节流好还是字符流好?

请问有人知道语音留言聊天的主流实现方式吗?

通俗易懂:基于集群的移动端IM接入层负载均衡方案分享

微信对网络影响的技术试验及分析(论文全文)

即时通讯系统的原理、技术和应用(技术论文)

开源IM工程“蘑菇街TeamTalk”的现状:一场有始无终的开源秀

QQ音乐团队分享:Android中的图片压缩技术详解(上篇)

QQ音乐团队分享:Android中的图片压缩技术详解(下篇)

腾讯原创分享(一):如何大幅提升移动网络下手机QQ的图片传输速度和成功率

腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(上篇)

腾讯原创分享(三):如何大幅压缩移动网络下APP的流量消耗(下篇)

如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源

基于社交网络的Yelp是如何实现海量用户图片的无损压缩的?

腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的(图片压缩篇)

腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的(音视频技术篇)

字符编码那点事:快速理解ASCII、Unicode、GBK和UTF-8

全面掌握移动端主流图片格式的特点、性能、调优等

子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践

微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)

自已开发IM有那么难吗?手把手教你自撸一个Andriod版简易IM (有源码)

融云技术分享:解密融云IM产品的聊天消息ID生成策略

适合新手:从零开发一个IM服务端(基于Netty,有完整源码)

拿起键盘就是干:跟我一起徒手开发一套分布式IM系统

>> 更多同类文章 …… 

[2] 有关WEB端即时通讯开发:

新手入门贴:史上最全Web端即时通讯技术原理详解

Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE

SSE技术详解:一种全新的HTML5服务器推送事件技术

Comet技术详解:基于HTTP长连接的Web端实时通信技术

新手快速入门:WebSocket简明教程

WebSocket详解(一):初步认识WebSocket技术

WebSocket详解(二):技术原理、代码演示和应用案例

WebSocket详解(三):深入WebSocket通信协议细节

WebSocket详解(四):刨根问底HTTP与WebSocket的关系(上篇)

WebSocket详解(五):刨根问底HTTP与WebSocket的关系(下篇)

WebSocket详解(六):刨根问底WebSocket与Socket的关系

socket.io实现消息推送的一点实践及思路

LinkedIn的Web端即时通讯实践:实现单机几十万条长连接

Web端即时通讯技术的发展与WebSocket、Socket.io的技术实践

Web端即时通讯安全:跨站点WebSocket劫持漏洞详解(含示例代码)

开源框架Pomelo实践:搭建Web端高性能分布式IM聊天服务器

使用WebSocket和SSE技术实现Web端消息推送

详解Web端通信方式的演进:从Ajax、JSONP 到 SSE、Websocket

MobileIMSDK-Web的网络层框架为何使用的是Socket.io而不是Netty?

理论联系实际:从零理解WebSocket的通信原理、协议格式、安全性

微信小程序中如何使用WebSocket实现长连接(含完整源码)

八问WebSocket协议:为你快速解答WebSocket热门疑问

快速了解Electron:新一代基于Web的跨平台桌面技术

一文读懂前端技术演进:盘点Web前端20年的技术变迁史

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题!

>> 更多同类文章 ……

(本文同步发布于:http://www.52im.net/thread-2941-1-1.html

posted @ 2020-03-13 17:15 Jack Jiang 阅读(240) | 评论 (0)编辑 收藏

     摘要: 一、引言对于后端程序员来说,127.0.0.1和0.0.0.0这两个IP地址再熟悉不过了,看起来好像就那么回事,但真正较起真来,这两个IP地址到底有什么作用以及到底有什么不同?貌似谁可以轻松回答,但张嘴却又不知从何说起。。。(这要是面视,估计真会被这搞砸...)本文将系统地总结127.0.0.1和0.0.0.0这两个IP地址的作用,以及它们之间的区别,希望能为你解惑。  * 推...  阅读全文

posted @ 2020-03-03 15:53 Jack Jiang 阅读(406) | 评论 (0)编辑 收藏

     摘要: 1、引言上个月在知乎上发表的由“袁辉辉”分享的关于TIM进程永生方面的文章(即时通讯网重新整理后的标题是:《史上最强Android保活思路:深入剖析腾讯TIM的进程永生技术》),短时间内受到大量关注,可惜在短短的几十个小时后,就在一股神秘力量的干预下被强行删除了。。。 ▲ 该文在知乎上从发布到删除的时间历程(中间省略了N条读者的评论)在《史上最强And...  阅读全文

posted @ 2020-02-26 22:44 Jack Jiang 阅读(270) | 评论 (0)编辑 收藏

本文由马蜂窝技术团队电商交易基础平台研发工程师"Anti Walker"原创分享。

一、引言

即时通讯(IM)功能对于电商平台来说非常重要,特别是旅游电商。

从商品复杂性来看,一个旅游商品可能会包括用户在未来一段时间的衣、食、住、行等方方面面。从消费金额来看,往往单次消费额度较大。对目的地的陌生、在行程中可能的问题,这些因素使用户在购买前、中、后都存在和商家沟通的强烈需求。可以说,一个好用的 IM 可以在一定程度上对企业电商业务的 GMV 起到促进作用。

本文我们将结合马蜂窝旅游电商IM系统的发展历程,单独介绍基于Go重构分布式IM系统过程中的实践和总结(本文相当于《从游击队到正规军(一):马蜂窝旅游网的IM系统架构演进之路》一文的进阶篇),希望可以给有相似问题的朋友一些借鉴。

另外:如果你对Go在高并发系统中的应用感兴趣,即时通讯网的以下两篇也值得一读:

Go语言构建千万级在线的高并发消息推送系统实践(来自360公司)

12306抢票带来的启示:看我如何用Go实现百万QPS的秒杀系统(含源码)

系列文章:

从游击队到正规军(一):马蜂窝旅游网的IM系统架构演进之路

从游击队到正规军(二):马蜂窝旅游网的IM客户端架构演进和实践总结

从游击队到正规军(三):基于Go的马蜂窝旅游网分布式IM系统技术实践》(* 本文

关于马蜂窝旅游网: 

马蜂窝旅游网是中国领先的自由行服务平台,由陈罡和吕刚创立于2006年,从2010年正式开始公司化运营。马蜂窝的景点、餐饮、酒店等点评信息均来自上亿用户的真实分享,每年帮助过亿的旅行者制定自由行方案。

学习交流:

- 即时通讯/推送技术开发交流5群:215477170 [推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

(本文同步发布于:http://www.52im.net/thread-2909-1-1.html

二、相关文章

一套海量在线用户的移动端IM架构设计实践分享(含详细图文)

一套原创分布式即时通讯(IM)系统理论架构方案

从零到卓越:京东客服即时通讯系统的技术架构演进历程

蘑菇街即时通讯/IM服务器开发之架构选择

以微博类应用场景为例,总结海量社交系统的架构设计步骤

一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践

腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT

微信技术总监谈架构:微信之道——大道至简(演讲全文)

如何解读《微信技术总监谈架构:微信之道——大道至简》

快速裂变:见证微信强大后台架构从0到1的演进历程(一)

瓜子IM智能客服系统的数据架构设计(整理自现场演讲,有配套PPT)

阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处

三、技术背景和问题

与广义上的即时通讯不同,电商各业务线有其特有业务逻辑,如客服聊天系统的客人分配逻辑、敏感词检测逻辑等,这些往往要耦合进通信流程中。随着接入业务线越来越多,即时通讯服务冗余度会越来越高。同时整个消息链路追溯复杂,服务稳定性很受业务逻辑的影响。

之前我们 IM 应用中的消息推送主要基于轮询技术,消息轮询模块的长连接请求是通过 php-fpm 挂载在阻塞队列上实现。当请求量较大时,如果不能及时释放 php-fpm 进程,对服务器的性能消耗很大。

为了解决这个问题,我们曾用 OpenResty+Lua 的方式进行改造,利用 Lua 协程的方式将整体的 polling 的能力从 PHP 转交到 Lua 处理,释放一部 PHP 的压力。这种方式虽然能提升一部分性能,但 PHP-Lua 的混合异构模式,使系统在使用、升级、调试和维护上都很麻烦,通用性也较差,很多业务场景下还是要依赖 PHP 接口,优化效果并不明显。

为了解决以上问题,我们决定结合电商 IM 的特定背景对 IM 服务进行重构,核心是实现业务逻辑和即时通讯服务的分离。

更多有关马蜂窝旅游网的IM系统架构的演进过程,请详读:《从游击队到正规军(一):马蜂窝旅游网的IM系统架构演进之路》一文,在此不再赘述。

四、基于Go的双层分布式IM架构

4.1、实现目标

1)业务解耦:

将业务逻辑与通信流程剥离,使 IM 服务架构更加清晰,实现与电商 IM 业务逻辑的完全分离,保证服务稳定性。

2)接入方式灵活:

之前新业务接入时,需要在业务服务器上配置 OpenResty 环境及 Lua 协程代码,非常不便,IM 服务的通用性也很差。考虑到现有业务的实际情况,我们希望 IM 系统可以提供 HTTP 和 WebSocket 两种接入方式,供业务方根据不同的场景来灵活使用。

比如已经接入且运行良好的电商定制化团队的待办系统、定制游抢单系统、投诉系统等下行相关的系统等,这些业务没有明显的高并发需求,可以通过 HTTP 方式迅速接入,不需要熟悉稍显复杂的 WebSocket 协议,进而降低不必要的研发成本。

3)架构可扩展:

为了应对业务的持续增长给系统性能带来的挑战,我们考虑用分布式架构来设计即时通讯服务,使系统具有持续扩展及提升的能力。

4.2、语言选择

目前,马蜂窝技术体系主要包括 PHP,Java,Golang,技术栈比较丰富,使业务做选型时可以根据问题场景选择更合适的工具和语言。

结合 IM 具体应用场景,我们选择 Go 的原因包括:

  • 1)运行性能:在性能上,尤其是针对网络通信等 IO 密集型应用场景。Go 系统的性能更接近 C/C++;
  • 2)开发效率:Go 使用起来简单,代码编写效率高,上手也很快,尤其是对于有一定 C++ 基础的开发者,一周就能上手写代码了。

4.3、架构设计

整体架构图如下: 

名词解释:

  • 1)客户:一般指购买商品的用户;
  • 2)商家:提供服务的供应商,商家会有客服人员,提供给客户一个在线咨询的作用;
  • 3)分发模块:即 Dispatcher,提供消息分发的给指定的工作模块的桥接作用;
  • 4)工作模块:即 Worker 服务器,用来提供 WebSocket 服务,是真正工作的一个模块。

架构分层:

  • 1)展示层:提供 HTTP 和 WebSocket 两种接入方式;
  • 2)业务层:负责初始化消息线和业务逻辑处理。如果客户端以 HTTP 方式接入,会以 JSON 格式把消息发送给业务服务器进行消息解码、客服分配、敏感词过滤,然后下发到消息分发模块准备下一步的转换;通过 WebSocket 接入的业务则不需要消息分发,直接以 WebSocket 方式发送至消息处理模块中;
  • 3)服务层:由消息分发和消息处理这两层组成,分别以分布式的方式部署多个 Dispatcher 和 Worker 节点。Dispatcher 负责检索出接收者所在的服务器位置,将消息以 RPC 的方式发送到合适的 Worker 上,再由消息处理模块通过 WebSocket 把消息推送给客户端;
  • 4)数据层:Redis 集群,记录用户身份、连接信息、客户端平台(移动端、网页端、桌面端)等组成的唯一 Key。

4.4、服务流程

步骤一:

如上图右侧所示:

用户客户端与消息处理模块建立 WebSocket 长连接;

通过负载均衡算法,使客户端连接到合适的服务器(消息处理模块的某个 Worker);

连接成功后,记录用户连接信息,包括用户角色(客人或商家)、客户端平台(移动端、网页端、桌面端)等组成唯一 Key,记录到 Redis 集群。

步骤二:

如图左侧所示,当购买商品的用户要给管家发消息的时候,先通过 HTTP 请求把消息发给业务服务器,业务服务端对消息进行业务逻辑处理。

1)该步骤本身是一个 HTTP 请求,所以可以接入各种不同开发语言的客户端。通过 JSON 格式把消息发送给业务服务器,业务服务器先把消息解码,然后拿到这个用户要发送给哪个商家的客服的。

2)如果这个购买者之前没有聊过天,则在业务服务器逻辑里需要有一个分配客服的过程,即建立购买者和商家的客服之间的连接关系。拿到这个客服的 ID,用来做业务消息下发;如果之前已经聊过天,则略过此环节。

3)在业务服务器,消息会异步入数据库。保证消息不会丢失。

步骤三:

业务服务端以 HTTP 请求把消息发送到消息分发模块。这里分发模块的作用是进行中转,最终使服务端的消息下发给指定的商家。

步骤四:

基于 Redis 集群中的用户连接信息,消息分发模块将消息转发到目标用户连接的 WebSocket 服务器(消息处理模块中的某一个 Worker)

1)分发模块通过 RPC 方式把消息转发到目标用户连接的 Worker,RPC 的方式性能更快,而且传输的数据也少,从而节约了服务器的成本。

2)消息透传 Worker 的时候,多种策略保障消息一定会下发到 Worker。

步骤五:

消息处理模块将消息通过 WebSocket 协议推送到客户端。

1)在投递的时候,接收者要有一个 ACK(应答) 信息来回馈给 Worker 服务器,告诉 Worker 服务器,下发的消息接收者已经收到了。

2)如果接收者没有发送这个 ACK 来告诉 Worker 服务器,Worker 服务器会在一定的时间内来重新把这个信息发送给消息接收者。

3)如果投递的信息已经发送给客户端,客户端也收到了,但是因为网络抖动,没有把 ACK 信息发送给服务器,那服务器会重复投递给客户端,这时候客户端就通过投递过来的消息 ID 来去重展示。

以上步骤的数据流转大致如图所示:

4.5、系统完整性设计

4.5.1 可靠性

(1)消息不丢失:

为了避免消息丢失,我们设置了超时重传机制。服务端会在推送给客户端消息后,等待客户端的 ACK,如果客户端没有返回 ACK,服务端会尝试多次推送。

目前默认 18s 为超时时间,重传 3 次不成功,断开连接,重新连接服务器。重新连接后,采用拉取历史消息的机制来保证消息完整。

(2)多端消息同步:

客户端现有 PC 浏览器、Windows 客户端、H5、iOS/Android,系统允许用户多端同时在线,且同一端可以多个状态,这就需要保证多端、多用户、多状态的消息是同步的。

我们用到了 Redis 的 Hash 存储,将用户信息、唯一连接对应值 、连接标识、客户端 IP、服务器标识、角色、渠道等记录下来,这样通过 key(uid) 就能找到一个用户在多个端的连接,通过 key+field 能定位到一条连接。

4.5.2 可用性

上文我们已经说过,因为是双层设计,就涉及到两个 Server 间的通信,同进程内通信用 Channel,非同进程用消息队列或者 RPC。综合性能和对服务器资源利用,我们最终选择 RPC 的方式进行 Server 间通信。

在对基于 Go 的 RPC 进行选行时,我们比较了以下比较主流的技术方案: 

1)Go STDRPC:Go 标准库的 RPC,性能最优,但是没有治理;

2)RPCX:性能优势 2*GRPC + 服务治理;

3)GRPC:跨语言,但性能没有 RPCX 好;

4)TarsGo:跨语言,性能 5*GRPC,缺点是框架较大,整合起来费劲;

5)Dubbo-Go:性能稍逊一筹, 比较适合 Go 和 Java 间通信场景使用。

最后我们选择了 RPCX,因为性能也很好,也有服务的治理。

两个进程之间同样需要通信,这里用到的是 ETCD 实现服务注册发现机制。

当我们新增一个 Worker,如果没有注册中心,就要用到配置文件来管理这些配置信息,这挺麻烦的。而且你新增一个后,需要分发模块立刻发现,不能有延迟。

如果有新的服务,分发模块希望能快速感知到新的服务。利用 Key 的续租机制,如果在一定时间内,没有监听到 Key 有续租动作,则认为这个服务已经挂掉,就会把该服务摘除。

在进行注册中心的选型时,我们主要调研了 ETCDZooKeeperConsul

三者的压测结果参考如下: 

 

结果显示,ETCD 的性能是最好的。另外,ETCD 背靠阿里巴巴,而且属于 Go 生态,我们公司内部的 K8S 集群也在使用。

综合考量后,我们选择使用 ETCD 作为服务注册和发现组件。并且我们使用的是 ETCD 的集群模式,如果一台服务器出现故障,集群其他的服务器仍能正常提供服务。

小结一下:通过保证服务和进程间的正常通讯,及 ETCD 集群模式的设计,保证了 IM 服务整体具有极高的可用性。

4.5.3 扩展性

消息分发模块和消息处理模块都能进行水平扩展。当整体服务负载高时,可以通过增加节点来分担压力,保证消息即时性和服务稳定性。

4.5.4 安全性

处于安全性考虑,我们设置了黑名单机制,可以对单一 uid 或者 ip 进行限制。比如在同一个 uid 下,如果一段时间内建立的连接次数超过设定的阈值,则认为这个 uid 可能存在风险,暂停服务。如果暂停服务期间该 uid 继续发送请求,则限制服务的时间相应延长。

4.6、性能优化和踩过的坑

4.6.1 性能优化

1)JSON 编解码:

开始我们使用官方的 JSON 编解码工具,但由于对性能方面的追求,改为使用滴滴开源的 Json-iterator,使在兼容原生 Golang 的 JSON 编解码工具的同时,效率上有比较明显的提升。

以下是压测对比的参考图: 

2)time.After:

在压测的时候,我们发现内存占用很高,于是使用 Go Tool PProf 分析 Golang 函数内存申请情况,发现有不断创建 time.After 定时器的问题,定位到是心跳协程里面。

原来代码如下: 

优化后的代码为:

优化点在于 for 循环里不要使用 select + time.After 的组合。

3)Map 的使用:

在保存连接信息的时候会用到 Map。因为之前做 TCP Socket 的项目的时候就遇到过一个坑,即 Map 在协程下是不安全的。当多个协程同时对一个 Map 进行读写时,会抛出致命错误:fetal error:concurrent map read and map write,有了这个经验后,我们这里用的是 sync.Map

4.6.2 踩坑经验

1)协程异常:

基于对开发成本和服务稳定性等问题的考虑,我们的 WebSocket 服务基于 Gorilla/WebSocket 框架开发。其中遇到一个问题,就是当读协程发生异常退出时,写协程并没有感知到,结果就是导致读协程已经退出但是写协程还在运行,直到触发异常之后才退出。

这样虽然从表面上看不影响业务逻辑,但是浪费后端资源。在编码时应该注意要在读协程退出后主动通知写协程,这样一个小的优化可以这在高并发下能节省很多资源。

2)心跳设计:

举个例子:之前我们在闲时心跳功能的开发中走了一些弯路。最初在服务器端的心跳发送是定时心跳,但后来在实际业务场景中使用时发现,设计成服务器读空闲时心跳更好。因为用户都在聊天呢,发一个心跳帧,浪费感情也浪费带宽资源。

这时候,建议大家在业务开发过程中如果代码写不下去就暂时不要写了,先结合业务需求用文字梳理下逻辑,可能会发现之后再进行会更顺利。

3)每天分割日志: 

日志模块在起初调研的时候基于性能考虑,确定使用 Uber 开源的 ZAP 库,而且满足业务日志记录的要求。日志库选型很重要,选不好也是影响系统性能和稳定性的。

ZAP 的优点包括:

1)显示代码行号这个需求,ZAP 支持而 Logrus 不支持,这个属于提效的。行号展示对于定位问题很重要;

2)ZAP 相对于 Logrus 更为高效,体现在写 JSON 格式日志时,没有使用反射,而是用内建的 json encoder,通过明确的类型调用,直接拼接字符串,最小化性能开销。

小坑:每天写一个日志文件的功能,目前 ZAP 不支持,需要自己写代码支持,或者请求系统部支持。

五、性能表现

压测 1:

上线生产环境并和业务方对接以及压测,目前定制业务已接通整个流程,写了一个 Client。模拟定期发心跳帧,然后利用 Docker 环境。开启了 50 个容器,每个容器模拟并发起 2 万个连接。这样就是百万连接打到单机的 Server 上。单机内存占用 30G 左右。

压测 2:

同时并发 3000、4000、5000 连接,以及调整发送频率,分别对应上行:60万、80 万、100 万、200 万, 一个 6k 左右的日志结构体。

其中有一半是心跳包 另一半是日志结构体。在不同的压力下的下行延迟数据如下: 

结论:

随着上行的并发变大,延迟控制在 24-66 毫秒之间。所以对于下行业务属于轻微延迟。另外针对 60 万 5k 上行的同时,用另一个脚本模拟开启 50 个协程并发下行 1k 的数据体,延迟是比没有并发下行的时候是有所提高的,延迟提高了 40ms 左右。

六、本文小结

基于 Go 重构的 IM 服务在 WebSocket 的基础上,将业务层设计为配有消息分发模块和消息处理模块的双层架构模式,使业务逻辑的处理前置,保证了即时通讯服务的纯粹性和稳定性;同时消息分发模块的 HTTP 服务方便多种编程语言快速对接,使各业务线能迅速接入即时通讯服务。

最后,我还想为 Go 摇旗呐喊一下。很多人都知道马蜂窝技术体系主要是基于 PHP,有一些核心业务也在向 Java 迁移。与此同时,Go 也在越来越多的项目中发挥作用。现在,云原生理念已经逐渐成为主流趋势之一,我们可以看到在很多构建云原生应用所需要的核心项目中,Go 都是主要的开发语言,比如 Kubernetes,Docker,Istio,ETCD,Prometheus 等,包括第三代开源分布式数据库 TiDB。

所以我们可以把 Go 称为云原生时代的母语。「云原生时代,是开发者最好的时代」,在这股浪潮下,我们越早走进 Go,就可能越早在这个新时代抢占关键赛道。希望更多小伙伴和我们一起,加入到 Go 的开发和学习阵营中来,拓宽自己的技能图谱,拥抱云原生。

附录:更多IM架构设计方面的文章

[1] 有关IM架构设计的文章:

浅谈IM系统的架构设计

简述移动端IM开发的那些坑:架构设计、通信协议和客户端

一套海量在线用户的移动端IM架构设计实践分享(含详细图文)

一套原创分布式即时通讯(IM)系统理论架构方案

从零到卓越:京东客服即时通讯系统的技术架构演进历程

蘑菇街即时通讯/IM服务器开发之架构选择

腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT

微信后台基于时间序的海量数据冷热分级架构设计实践

微信技术总监谈架构:微信之道——大道至简(演讲全文)

如何解读《微信技术总监谈架构:微信之道——大道至简》

快速裂变:见证微信强大后台架构从0到1的演进历程(一)

17年的实践:腾讯海量产品的技术方法论

移动端IM中大规模群消息的推送如何保证效率、实时性?

现代IM系统中聊天消息的同步和存储方案探讨

IM开发基础知识补课(二):如何设计大量图片文件的服务端存储架构?

IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议

IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token

WhatsApp技术实践分享:32人工程团队创造的技术神话

微信朋友圈千亿访问量背后的技术挑战和实践总结

王者荣耀2亿用户量的背后:产品定位、技术架构、网络方案等

IM系统的MQ消息中间件选型:Kafka还是RabbitMQ?

腾讯资深架构师干货总结:一文读懂大型分布式系统设计的方方面面

以微博类应用场景为例,总结海量社交系统的架构设计步骤

快速理解高性能HTTP服务端的负载均衡技术原理

子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践

知乎技术分享:从单机到2000万QPS并发的Redis高性能缓存实践之路

IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列

微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)

微信技术分享:微信的海量IM聊天消息序列号生成实践(容灾方案篇)

新手入门:零基础理解大型分布式架构的演进历史、技术原理、最佳实践

一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践

阿里技术分享:深度揭秘阿里数据库技术方案的10年变迁史

阿里技术分享:阿里自研金融级数据库OceanBase的艰辛成长之路

社交软件红包技术解密(一):全面解密QQ红包技术方案——架构、技术实现等

社交软件红包技术解密(二):解密微信摇一摇红包从0到1的技术演进

社交软件红包技术解密(三):微信摇一摇红包雨背后的技术细节

社交软件红包技术解密(四):微信红包系统是如何应对高并发的

社交软件红包技术解密(五):微信红包系统是如何实现高可用性的

社交软件红包技术解密(六):微信红包系统的存储层架构演进实践

社交软件红包技术解密(七):支付宝红包的海量高并发技术实践

社交软件红包技术解密(八):全面解密微博红包技术方案

社交软件红包技术解密(九):谈谈手Q红包的功能逻辑、容灾、运维、架构等

即时通讯新手入门:一文读懂什么是Nginx?它能否实现IM的负载均衡?

即时通讯新手入门:快速理解RPC技术——基本概念、原理和用途

多维度对比5款主流分布式MQ消息队列,妈妈再也不担心我的技术选型了

从游击队到正规军(一):马蜂窝旅游网的IM系统架构演进之路

从游击队到正规军(二):马蜂窝旅游网的IM客户端架构演进和实践总结

IM开发基础知识补课(六):数据库用NoSQL还是SQL?读这篇就够了!

瓜子IM智能客服系统的数据架构设计(整理自现场演讲,有配套PPT)

阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处

>> 更多同类文章 ……

[2] 更多其它架构设计相关文章:

腾讯资深架构师干货总结:一文读懂大型分布式系统设计的方方面面

快速理解高性能HTTP服务端的负载均衡技术原理

子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践

知乎技术分享:从单机到2000万QPS并发的Redis高性能缓存实践之路

新手入门:零基础理解大型分布式架构的演进历史、技术原理、最佳实践

阿里技术分享:深度揭秘阿里数据库技术方案的10年变迁史

阿里技术分享:阿里自研金融级数据库OceanBase的艰辛成长之路

达达O2O后台架构演进实践:从0到4000高并发请求背后的努力

优秀后端架构师必会知识:史上最全MySQL大表优化方案总结

小米技术分享:解密小米抢购系统千万高并发架构的演进和实践

一篇读懂分布式架构下的负载均衡技术:分类、原理、算法、常见方案等

通俗易懂:如何设计能支撑百万并发的数据库架构?

多维度对比5款主流分布式MQ消息队列,妈妈再也不担心我的技术选型了

从新手到架构师,一篇就够:从100到1000万高并发的架构演进之路

美团技术分享:深度解密美团的分布式ID生成算法

12306抢票带来的启示:看我如何用Go实现百万QPS的秒杀系统(含源码)

>> 更多同类文章 ……

(本文同步发布于:http://www.52im.net/thread-2909-1-1.html

posted @ 2020-02-19 16:47 Jack Jiang 阅读(185) | 评论 (0)编辑 收藏

     摘要: 1、引言随着Android系统的不断升级,即时通讯网技术群和社区里的IM和推送开发的程序员们,对于进程保活这件事是越来越悲观,必竟系统对各种保活黑科技的限制越来越多了,想超越系统的挚肘,难度越来越大。但保活这件事就像“激情”之后的余味,总是让人欲罢不能,想放弃又不甘心。那么,除了像上篇《2020年了,Android后台保活还有戏吗?看我如何优雅的实现!》这样的正经白名单方式...  阅读全文

posted @ 2020-01-14 14:33 Jack Jiang 阅读(99) | 评论 (0)编辑 收藏

     摘要: 1、引言扫码登录这个功能,最早应该是微信的PC端开始搞,虽然有点反人类的功能(不扫码也没别的方式登录),但不得不说还是很酷的。下面这张图,不管是IM开发者还是普通用户,应该很熟悉: 于是,搞IM产品的老板和产品经理们,从此又多了一个要抛给程序员们的需求——“为什么微信有扫一扫登录,而我们的没有?”。好吧,每次只要是微信有的功能,IM程序员们...  阅读全文

posted @ 2020-01-08 13:39 Jack Jiang 阅读(42) | 评论 (0)编辑 收藏

     摘要: 本文由腾讯WXG应用研究员breezecheng原创发表于公众号“腾讯技术工程”,原题“微信「扫一扫识物」 的背后技术揭秘”。一、引言现在市面上主流的移动端IM应用于都有“扫一扫”功能,看起来好像也就能扫一扫加好友、加群,但实际上作为一个IM产品的重要信息入口,“扫一扫”功能也可以很强大。▲...  阅读全文

posted @ 2020-01-02 20:54 Jack Jiang 阅读(71) | 评论 (0)编辑 收藏

1、引言

对于移动端IM应用和消息推送应用的开发者来说,Android后台保活这件事是再熟悉不过了。

自从Android P(即Android 8.0)出现以后,Android已经从系统层面将后台保活这条路给堵死了(详见:《Android P正式版即将到来:后台应用保活、消息推送的真正噩梦》),曾今那些层出不穷的保活黑科技能用的也越来越少了(详见:《全面盘点当前Android后台保活方案的真实运行效果(截止2019年前)》。虽然可以自已对接厂商的ROOM级推送通道,但一方面各厂商的推送接口都不一样(而且同一厂商不同的系统版本间也存在推送接口的兼容性问题),很不方便。另一方面要一家家引入各自的推送服务SDK包会让APP变的很大,这让APP的下载变的很不友好。

总之,Android应用的后台保活在某些场景下,还是有持续的需求。除了之前那些耳熟能详的保活黑科技以外,在Android 9.0(甚至Android 10)时代,我们还有哪些保活方法可以用?那么,请跟着本文作者的思路,看看更优雅的后台保活实现方法吧。

(本文同步发布于:http://www.52im.net/thread-2881-1-1.html

 

2、关于作者

网名NanBox:毕业于华中科技大学,现为"悦跑圈APP”高级Android开发工程师。主要负责公司 Android 项目,核心模块的开发。涉及 GPS 定位、地图、图片编辑等功能。独立开发了手表应用项目。 在项目中应入了 Flutter 跨平台开发技术,实现了原生和 Flutter 的混合开发。

本文作者乐于分享,平时会写技术文章并分享在多个平台,是掘金专栏作者的一员,文章总阅读量超过 10 万。在 GitHub 上有多个开源项目,多次在团队内部进行技术分享。是 Android 和 Flutter 官方中文文档译者。

3、相关文章

如果你想详细了解目前Android平台上后台保活技术的挑战,请阅读:

Android P正式版即将到来:后台应用保活、消息推送的真正噩梦》。

如果你想回顾那些曾今出现的Android保活黑科技,以下文章值得好好读读:

全面盘点当前Android后台保活方案的真实运行效果(截止2019年前)

应用保活终极总结(一):Android6.0以下的双进程守护保活实践

应用保活终极总结(二):Android6.0及以上的保活实践(进程防杀篇)

应用保活终极总结(三):Android6.0及以上的保活实践(被杀复活篇)

Android进程保活详解:一篇文章解决你的所有疑问

Android端消息推送总结:实现原理、心跳保活、遇到的问题等

深入的聊聊Android消息推送这件小事

为何基于TCP协议的移动端IM仍然需要心跳保活机制?

微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)

融云技术分享:融云安卓端IM产品的网络链路保活技术实践

4、Android保活现状

我们知道,Android 系统会存在杀后台进程的情况,并且随着系统版本的更新,杀进程的力度还有越来越大的趋势(见:《Android P正式版即将到来:后台应用保活、消息推送的真正噩梦》)。

系统这种做法本身出发点是好的,因为可以节省内存,降低功耗,也避免了一些流氓行为。

但有一部分应用,应用本身的使用场景就需要在后台运行,用户也是愿意让它在后台运行的,比如跑步类应用、一些懒得对接厂商推送通道的IM应用、消息推送资讯类应用等。

一方面流氓软件用各种流氓手段进行保活,另一方面系统加大杀后台的力度,导致我们一些真正需要在后台运行的应用被误杀,苦不堪言。

5、优雅的保活?

为了做到保活,出现了不少「黑科技」,比如 1 个像素的 Activity,播放无声音频,双进程互相守护等(可以读读这个系列:《应用保活终极总结(一):Android6.0以下的双进程守护保活实践》、《应用保活终极总结(二):Android6.0及以上的保活实践(进程防杀篇)》、《应用保活终极总结(三):Android6.0及以上的保活实践(被杀复活篇)》)。

这些做法可以说是很流氓了,甚至破坏了 Android 的生态,好在随着 Android 系统版本的更新,这些非常规的保活手段很多都已失效了。

对于那些确实需要在后台运行的应用,我们如何做到优雅的保活呢?

6、加入后台运行白名单,可以优雅的实现保活

从 Android 6.0 开始,系统为了省电增加了休眠模式,系统待机一段时间后,会杀死后台正在运行的进程。但系统会有一个后台运行白名单,白名单里的应用将不会受到影响,在原生系统下,通过:「设置」 - 「电池」 - 「电池优化」 - 「未优化应用」,可以看到这个白名单。

通常会看到下面这两位: 

下次被产品说「 XXX 都可以保活,为什么我们不行!」的时候,你就知道怎么怼回去了。大厂通过和手机厂商的合作,将自己的应用默认加入到白名单中。如果你在一个能谈成这种合作的大厂,也就不用往下看了。

好在系统还没有抛弃我们,允许我们申请把应用加入白名单。

首先,在 AndroidManifest.xml 文件中配置一下权限:

<uses-permissionandroid:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>

可以通过以下方法,判断我们的应用是否在白名单中:

@RequiresApi(api = Build.VERSION_CODES.M)

private boolean isIgnoringBatteryOptimizations() {

    boolean isIgnoring = false;

    PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);

    if(powerManager != null) {

        isIgnoring = powerManager.isIgnoringBatteryOptimizations(getPackageName());

    }

    return isIgnoring;

}

如果不在白名单中,可以通过以下代码申请加入白名单:

@RequiresApi(api = Build.VERSION_CODES.M)

public void requestIgnoreBatteryOptimizations() {

    try{

        Intent intent = newIntent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);

        intent.setData(Uri.parse("package:"+ getPackageName()));

        startActivity(intent);

    } catch(Exception e) {

        e.printStackTrace();

    }

}

申请时,应用上会出现这样一个窗口:

可以看到,这个系统弹窗会有影响电池续航的提醒,所以如果想让用户点允许,必须要有相关的说明。如果要判断用户是否点击了允许,可以在申请的时候调用 startActivityForResult,在 onActivityResult 里再判断一次是否在白名单中。

7、加入后台运行白名单的多厂商适配方法

7.1 基本说明

Android 开发的一个难点在于,各大手机厂商对原生系统进行了不同的定制,导致我们需要进行不同的适配,后台管理就是一个很好的体现。几乎各个厂商都有自己的后台管理,就算应用加入了后台运行白名单,仍然可能会被厂商自己的后台管理干掉。

如果能把应用加入厂商系统的后台管理白名单,可以进一步降低进程被杀的概率。不同的厂商在不同的地方进行设置,一般是在各自的「手机管家」,但更难的是,就算同一个厂商的系统,不同的版本也可能是在不同地方设置。

最理想的做法是,我们根据不同手机,甚至是不同的系统版本,给用户呈现一个图文操作步骤,并且提供一个按钮,直接跳转到指定页面进行设置。但需要对每个厂商每个版本进行适配,工作量是比较大的。我使用真机测试了大部分主流 Android 厂商的手机后,整理出了部分手机的相关资料。

首先我们可以定义这样两个方法:

/**

 * 跳转到指定应用的首页

 */

private void showActivity(@NonNull String packageName) {

    Intent intent = getPackageManager().getLaunchIntentForPackage(packageName);

    startActivity(intent);

}

 

/**

 * 跳转到指定应用的指定页面

 */

private void showActivity(@NonNull String packageName, @NonNull String activityDir) {

    Intent intent = new Intent();

    intent.setComponent(newComponentName(packageName, activityDir));

    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    startActivity(intent);

}

以下是部分手机的厂商判断,跳转方法及对应设置步骤,跳转方法不保证在所有版本上都能成功跳转,都需要加 try catch。

7.2 华为

厂商判断:

public boolean isHuawei() {

    if(Build.BRAND == null) {

        return false;

    } else{

        return Build.BRAND.toLowerCase().equals("huawei") || Build.BRAND.toLowerCase().equals("honor");

    }

}

跳转华为手机管家的启动管理页:

private void goHuaweiSetting() {

    try{

        showActivity("com.huawei.systemmanager",

            "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity");

    } catch(Exception e) {

        showActivity("com.huawei.systemmanager",

            "com.huawei.systemmanager.optimize.bootstart.BootStartActivity");

    }

}

操作步骤:应用启动管理 -> 关闭应用开关 -> 打开允许自启动

7.3 小米

厂商判断:

public static boolean isXiaomi() {

    return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("xiaomi");

}

跳转小米安全中心的自启动管理页面:

private void goXiaomiSetting() {

    showActivity("com.miui.securitycenter",

        "com.miui.permcenter.autostart.AutoStartManagementActivity");

}

操作步骤:授权管理 -> 自启动管理 -> 允许应用自启动

7.4 OPPO

厂商判断:

public static boolean isOPPO() {

    return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("oppo");

}

跳转 OPPO 手机管家:

private void goOPPOSetting() {

    try{

        showActivity("com.coloros.phonemanager");

    } catch(Exception e1) {

        try{

            showActivity("com.oppo.safe");

        } catch(Exception e2) {

            try{

                showActivity("com.coloros.oppoguardelf");

            } catch(Exception e3) {

                showActivity("com.coloros.safecenter");

            }

        }

    }

}

操作步骤:权限隐私 -> 自启动管理 -> 允许应用自启动

7.5 VIVO

厂商判断:

public static boolean isVIVO() {

    return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("vivo");

}

跳转 VIVO 手机管家:

private void goVIVOSetting() {

    showActivity("com.iqoo.secure");

}

操作步骤:权限管理 -> 自启动 -> 允许应用自启动

7.6 魅族

厂商判断:

public static boolean isMeizu() {

    return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("meizu");

}

跳转魅族手机管家:

private void goMeizuSetting() {

    showActivity("com.meizu.safe");

}

操作步骤:权限管理 -> 后台管理 -> 点击应用 -> 允许后台运行

7.7 三星

厂商判断:

public static boolean isSamsung() {

    return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("samsung");

}

跳转三星智能管理器:

private void goSamsungSetting() {

    try{

        showActivity("com.samsung.android.sm_cn");

    } catch(Exception e) {

        showActivity("com.samsung.android.sm");

    }

}

操作步骤:自动运行应用程序 -> 打开应用开关 -> 电池管理 -> 未监视的应用程序 -> 添加应用

7.8 乐视

厂商判断:

public static boolean isLeTV() {

    return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("letv");

}

跳转乐视手机管家:

private void goLetvSetting() {

    showActivity("com.letv.android.letvsafe",

        "com.letv.android.letvsafe.AutobootManageActivity");

}

操作步骤:自启动管理 -> 允许应用自启动

7.9 锤子

厂商判断:

public static boolean isSmartisan() {

    return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("smartisan");

}

跳转手机管理:

private void goSmartisanSetting() {

    showActivity("com.smartisanos.security");

}

操作步骤:权限管理 -> 自启动权限管理 -> 点击应用 -> 允许被系统启动。

8、友商致敬?

在之前做的跑步应用中,我在设置里增加了一个权限设置页面,将上面提到的设置放在这里面。

最近发现友商某咚也跟进了,图 1 是我们做的,图 2 是某咚做的: 

某咚从设计、从我写的不够好的文案,甚至是我从十几台手机上一张一张截下来的图,进行了全方位的致敬。感谢某咚的认可,但最近在某个发布会上听到这么一句话:在致敬的同时,能不能说一句谢谢?

某咚的致敬,一方面说明了目前确实存在进程容易被杀,保活难度大的问题,另一方面也说明了这种引导用户进行白名单设置的手段是有效的。

附录:更多相关技术文章

应用保活终极总结(一):Android6.0以下的双进程守护保活实践

应用保活终极总结(二):Android6.0及以上的保活实践(进程防杀篇)

应用保活终极总结(三):Android6.0及以上的保活实践(被杀复活篇)

Android进程保活详解:一篇文章解决你的所有疑问

Android端消息推送总结:实现原理、心跳保活、遇到的问题等

深入的聊聊Android消息推送这件小事

为何基于TCP协议的移动端IM仍然需要心跳保活机制?

微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)

微信团队原创分享:Android版微信后台保活实战分享(网络保活篇)

移动端IM实践:实现Android版微信的智能心跳机制

移动端IM实践:WhatsApp、Line、微信的心跳策略分析

Android P正式版即将到来:后台应用保活、消息推送的真正噩梦

全面盘点当前Android后台保活方案的真实运行效果(截止2019年前)

一文读懂即时通讯应用中的网络心跳包机制:作用、原理、实现思路等

融云技术分享:融云安卓端IM产品的网络链路保活技术实践

正确理解IM长连接的心跳及重连机制,并动手实现(有完整IM源码)

2020年了,Android后台保活还有戏吗?看我如何优雅的实现!

>> 更多同类文章 ……

(本文同步发布于:http://www.52im.net/thread-2881-1-1.html

posted @ 2019-12-27 14:51 Jack Jiang 阅读(149) | 评论 (0)编辑 收藏

     摘要: 原作者:黄日成,手Q游戏中心后台开发,腾讯高级工程师。从事C++服务后台开发4年多,主要负责手Q游戏中心后台基础系统、复杂业务系统开发,主导过手Q游戏公会、企鹅电竞App-对战系统等项目的后台系统设计,有丰富的后台架构经验。1、引言接本系列的上一篇《P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解(基本原理篇)》,本篇将深入分析各种NAT穿越(打洞)方案的技术实现原理和数据交互过程,希望...  阅读全文

posted @ 2019-12-24 11:25 Jack Jiang 阅读(46) | 评论 (0)编辑 收藏

     摘要: 1、引言岁月真是个养猪场,这几年,人胖了,微信代码也翻了。记得 14 年转岗来微信时,用自己笔记本编译微信工程才十来分钟。如今用公司配的 17 年款 27-inch iMac 编译要接近半小时;偶然间更新完代码,又莫名其妙需要全新编译。在这么低的编译效率下,开发心情受到严重影响。于是年初我向上头请示,优化微信编译效率,上头也同意了。  学习交流:- 即时通讯/推送技术开发交流5...  阅读全文

posted @ 2019-12-19 20:22 Jack Jiang 阅读(43) | 评论 (0)编辑 收藏

     摘要: 1、引言IM等社交应用的开发工作中,乱码问题也很常见,比如:1)IM聊天消息中的Emoji表情为什么发给后端后MySQL数据库里会乱码;2)文件名中带有中文的大文件聊天消息发送后,对方看到的文名是乱码;3)Http rest接口调用时,后端读取到APP端传过来的参数有中文乱码问题;... ...那么,对于乱码这个看似不起眼,但并不是一两话能讲清楚的问题,是很有必要从根源了解字符集和编码原理,知其然...  阅读全文

posted @ 2019-12-17 19:36 Jack Jiang 阅读(56) | 评论 (0)编辑 收藏

1、引言

随着互联网安全意识的普遍提高,对安全要求稍高的应用中,HTTPS的使用是很常见的,甚至在1年前,苹果公司就将使用HTTPS作为APP上架苹果应用市场的先决条件之一(详见:《苹果即将强制实施 ATS,你的APP准备好切换到HTTPS了吗?》)。

所以,无论是即时通讯IM还是其它应用,在网络安全意识增强的今天,很多场景下使用HTTPS是肯定没错的。对于即时通讯IM的开发人员来说,长连接用TLS这没疑问,短连接用HTTPS也没问题,但我想问你一个最基础的面视问题:HTTPS到底用的是对称加密还是非对称加密?

要回答这个问题,显然需要再梳理一下HTTPS的技术原理了,本文将带你了解HTTPS到底用的是对称加密还是非对称加密,以及具体又是怎么使用的。

学习交流:

- 即时通讯/推送技术开发交流5群:215477170 [推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

(本文同步发布于:http://www.52im.net/thread-2866-1-1.html

2、相关文章

➊ 要理解HTTPS,须对HTTP协议有所了解,以下文章可能是您需要的:

网络编程懒人入门(七):深入浅出,全面理解HTTP协议

脑残式网络编程入门(三):HTTP协议必知必会的一些知识

不为人知的网络编程(八):从数据传输层深度解密HTTP

从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路

WebSocket详解(四):刨根问底HTTP与WebSocket的关系(上篇)

WebSocket详解(五):刨根问底HTTP与WebSocket的关系(下篇)

可能会搞砸你的面试:你知道一个TCP连接上能发起多少个HTTP请求吗?

➋ 想更好的理解本文有关HTTPS的知识,建议一并阅以下HTTPS的基础文章:

一分钟理解 HTTPS 到底解决了什么问题

即时通讯安全篇(七):如果这样来理解HTTPS,一篇就够了

一篇读懂HTTPS:加密原理、安全逻辑、数字证书等

HTTPS时代已来,打算更新你的HTTP服务了吗?

美图App的移动端DNS优化实践:HTTPS请求耗时减小近半

➌ 本文是IM通讯安全知识系列文章中的第8篇,此系列总目录如下:

即时通讯安全篇(一):正确地理解和使用Android端加密算法

即时通讯安全篇(二):探讨组合加密算法在IM中的应用

即时通讯安全篇(三):常用加解密算法与通讯安全讲解

即时通讯安全篇(四):实例分析Android中密钥硬编码的风险

即时通讯安全篇(五):对称加密技术在Android平台上的应用实践

即时通讯安全篇(六):非对称加密技术的原理与应用实践

即时通讯安全篇(七):如果这样来理解HTTPS原理,一篇就够了

即时通讯安全篇(八):你知道,HTTPS用的是对称加密还是非对称加密?》(本文)

3、HTTPS灵魂拷问

随着 HTTPS 建站的成本下降,现在大部分的网站都已经开始用上 HTTPS 协议。大家都知道 HTTPS 比 HTTP 安全,也听说过与 HTTPS 协议相关的概念有 SSL 、非对称加密、 CA证书等。

但对于以下灵魂三拷问可能就答不上了:

  • 1)为什么用了 HTTPS 就是安全的?
  • 2)HTTPS 的底层原理如何实现?
  • 3)用了 HTTPS 就一定安全吗?

不用担心,本文将在解答“HTTPS到底用的是对称加密还是非对称加密?”的同时层层深入,从原理上把 HTTPS 的安全性讲透,您也将同时理解上述问题。

4、HTTPS 的实现原理

大家可能都听说过 HTTPS 协议之所以是安全的是因为 HTTPS 协议会对传输的数据进行加密,而加密过程是使用了非对称加密实现。但其实:HTTPS 在内容传输的加密上使用的是对称加密,非对称加密只作用在证书验证阶段。

HTTPS的整体过程分为证书验证和数据传输阶段,具体的交互过程如下: 

① 证书验证阶段:

1)浏览器发起 HTTPS 请求;

2)服务端返回 HTTPS 证书;

3)客户端验证证书是否合法,如果不合法则提示告警。

② 数据传输阶段:

1)当证书验证合法后,在本地生成随机数;

2)通过公钥加密随机数,并把加密后的随机数传输到服务端;

3)服务端通过私钥对随机数进行解密;

4)服务端通过客户端传入的随机数构造对称加密算法,对返回结果内容进行加密后传输。

5、为什么数据传输是用对称加密?

首先:非对称加密的加解密效率是非常低的,而 http 的应用场景中通常端与端之间存在大量的交互,非对称加密的效率是无法接受的。

另外:在 HTTPS 的场景中只有服务端保存了私钥,一对公私钥只能实现单向的加解密,所以 HTTPS 中内容传输加密采取的是对称加密,而不是非对称加密。

6、为什么需要 CA 认证机构颁发证书?

HTTP 协议被认为不安全是因为传输过程容易被监听者勾线监听、伪造服务器,而 HTTPS 协议主要解决的便是网络传输的安全性问题。

首先我们假设不存在认证机构,任何人都可以制作证书,这带来的安全风险便是经典的“中间人攻击”问题。

“中间人攻击”的具体过程如下: 

如上图所以,过程原理如下:

  • 1)本地请求被劫持(如DNS劫持等),所有请求均发送到中间人的服务器;
  • 2)中间人服务器返回中间人自己的证书;
  • 3)客户端创建随机数,通过中间人证书的公钥对随机数加密后传送给中间人,然后凭随机数构造对称加密对传输内容进行加密传输;
  • 4)中间人因为拥有客户端的随机数,可以通过对称加密算法进行内容解密;
  • 5)中间人以客户端的请求内容再向正规网站发起请求;
  • 6)因为中间人与服务器的通信过程是合法的,正规网站通过建立的安全通道返回加密后的数据;
  • 7)中间人凭借与正规网站建立的对称加密算法对内容进行解密;
  • 8)中间人通过与客户端建立的对称加密算法对正规内容返回的数据进行加密传输;
  • 9)客户端通过与中间人建立的对称加密算法对返回结果数据进行解密。

由于缺少对证书的验证,所以客户端虽然发起的是 HTTPS 请求,但客户端完全不知道自己的网络已被拦截,传输内容被中间人全部窃取。

7、浏览器是如何确保 CA 证书的合法性?

7.1 证书包含什么信息?

  • 1)颁发机构信息;
  • 2)公钥;
  • 3)公司信息;
  • 4)域名;
  • 5)有效期;
  • 6)指纹;
  • 7)......

7.2 证书的合法性依据是什么?

  • 1)首先:权威机构是要有认证的,不是随便一个机构都有资格颁发证书,不然也不叫做权威机构;
  • 2)另外:证书的可信性基于信任制,权威机构需要对其颁发的证书进行信用背书,只要是权威机构生成的证书,我们就认为是合法的。

所以权威机构会对申请者的信息进行审核,不同等级的权威机构对审核的要求也不一样,于是证书也分为免费的、便宜的和贵的。

7.3 浏览器如何验证证书的合法性?

浏览器发起 HTTPS 请求时,服务器会返回网站的 SSL 证书,浏览器需要对证书做以下验证:

1)验证域名、有效期等信息是否正确:证书上都有包含这些信息,比较容易完成验证;

2)判断证书来源是否合法:每份签发证书都可以根据验证链查找到对应的根证书,操作系统、浏览器会在本地存储权威机构的根证书,利用本地根证书可以对对应机构签发证书完成来源验证(如下图所示): 

3)判断证书是否被篡改:需要与 CA 服务器进行校验;

4)判断证书是否已吊销:通过CRL(Certificate Revocation List 证书注销列表)和 OCSP(Online Certificate Status Protocol 在线证书状态协议)实现,其中 OCSP 可用于第3步中以减少与 CA 服务器的交互,提高验证效率。

以上任意一步都满足的情况下浏览器才认为证书是合法的。

这里插一个我想了很久的但其实答案很简单的问题:

既然证书是公开的,如果要发起中间人攻击,我在官网上下载一份证书作为我的服务器证书,那客户端肯定会认同这个证书是合法的,如何避免这种证书冒用的情况?

其实这就是非加密对称中公私钥的用处,虽然中间人可以得到证书,但私钥是无法获取的,一份公钥是不可能推算出其对应的私钥,中间人即使拿到证书也无法伪装成合法服务端,因为无法对客户端传入的加密数据进行解密。

7.4 只有认证机构可以生成证书吗?

如果需要浏览器不提示安全风险,那只能使用认证机构签发的证书。但浏览器通常只是提示安全风险,并不限制网站不能访问,所以从技术上谁都可以生成证书,只要有证书就可以完成网站的 HTTPS 传输。

例如早期的 12306 采用的便是手动安装私有证书的形式实现 HTTPS 访问: 

8、本地随机数被窃取怎么办?

证书验证是采用非对称加密实现,但是传输过程是采用对称加密,而其中对称加密算法中重要的随机数是由本地生成并且存储于本地的,HTTPS 如何保证随机数不会被窃取?

其实 HTTPS 并不包含对随机数的安全保证,HTTPS 保证的只是传输过程安全,而随机数存储于本地,本地的安全属于另一安全范畴,应对的措施有安装杀毒软件、反木马、浏览器升级修复漏洞等。

9、用了 HTTPS 会被抓包吗?

HTTPS 的数据是加密的,常规下抓包工具代理请求后抓到的包内容是加密状态,无法直接查看。

但是,正如前文所说,浏览器只会提示安全风险,如果用户授权仍然可以继续访问网站,完成请求。因此,只要客户端是我们自己的终端,我们授权的情况下,便可以组建中间人网络,而抓包工具便是作为中间人的代理。通常 HTTPS 抓包工具的使用方法是会生成一个证书,用户需要手动把证书安装到客户端中,然后终端发起的所有请求通过该证书完成与抓包工具的交互,然后抓包工具再转发请求到服务器,最后把服务器返回的结果在控制台输出后再返回给终端,从而完成整个请求的闭环。

既然 HTTPS 不能防抓包,那 HTTPS 有什么意义?

HTTPS 可以防止用户在不知情的情况下通信链路被监听,对于主动授信的抓包操作是不提供防护的,因为这个场景用户是已经对风险知情。要防止被抓包,需要采用应用级的安全防护,例如采用私有的对称加密,同时做好移动端的防反编译加固,防止本地算法被破解。

10、本文小结

以下用简短的Q&A形式进行全文总结。

Q: HTTPS 为什么安全?

A: 因为 HTTPS 保证了传输安全,防止传输过程被监听、防止数据被窃取,可以确认网站的真实性。

Q: HTTPS 的传输过程是怎样的?

A: 客户端发起 HTTPS 请求,服务端返回证书,客户端对证书进行验证,验证通过后本地生成用于改造对称加密算法的随机数,通过证书中的公钥对随机数进行加密传输到服务端,服务端接收后通过私钥解密得到随机数,之后的数据交互通过对称加密算法进行加解密。

Q: 为什么需要证书?

A: 防止”中间人“攻击,同时可以为网站提供身份证明。

Q: 使用 HTTPS 会被抓包吗?

A: 会被抓包,HTTPS 只防止用户在不知情的情况下通信被监听,如果用户主动授信,是可以构建“中间人”网络,代理软件可以对传输内容进行解密。

好了,回归到本文标的问题,我们来总结回顾一下。

Q: HTTPS用的是对称加密还是非对称加密?

Q: HTTPS 在内容传输的加密上使用的是对称加密,非对称加密只作用在证书验证阶段。

顺手 po 一张学习的过程图(点击查看大图):

附录:更多有关IM安全的文章

传输层安全协议SSL/TLS的Java平台实现简介和Demo演示

理论联系实际:一套典型的IM通信协议设计详解(含安全层设计)

微信新一代通信安全解决方案:基于TLS1.3的MMTLS详解

来自阿里OpenIM:打造安全可靠即时通讯服务的技术实践分享

简述实时音视频聊天中端到端加密(E2EE)的工作原理

移动端安全通信的利器——端到端加密(E2EE)技术详解

Web端即时通讯安全:跨站点WebSocket劫持漏洞详解(含示例代码)

通俗易懂:一篇掌握即时通讯的消息传输安全原理

IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token

快速读懂量子通信、量子加密技术

即时通讯安全篇(七):如果这样来理解HTTPS原理,一篇就够了

一分钟理解 HTTPS 到底解决了什么问题

一篇读懂HTTPS:加密原理、安全逻辑、数字证书等

即时通讯安全篇(八):你知道,HTTPS用的是对称加密还是非对称加密?

>> 更多同类文章 ……

(本文同步发布于:http://www.52im.net/thread-2866-1-1.html) 

posted @ 2019-12-10 12:15 Jack Jiang 阅读(57) | 评论 (0)编辑 收藏

1、引言

在即时通讯网经常能看到各种高大上的高并发、分布式、高性能架构设计方面的文章,平时大家参加的众多开发者大会,主题也都是各种高大上的话题——什么5G啦、AI人工智能啦、什么阿里双11分分钟多少万QPS高并发等等。

但实际上,对于普通的开发者(包括IM开发人员)来说,多数公司、多数团队也都是干着默默无闻、平淡无奇的产品开发,并没有那么多高并发、高大上的事情可以做。

就拿一个IM系统来说,无论你的架构设计考虑了多少分布式、高吞吐、高可用,所有这些事情只要落地,那编码的第一件事情就是要实现几乎所有信息系统都要面对的任务——如何设计账号登录功能?

本文将分享几种典型的移动端账号登陆方式的技术原理,以及设计思路,理解后,完全可以快速实施于你的各种应用系统(并不限于IM系统)中。本文阅读对像主要为刚入门的开发人员,请程序老司机们嘴下留情哦。

 

通过本篇文章, 你可以学到:

1)主流账号登陋技术方案细节;

2)相应的表设计;

3)相应的流程设计。

通过本篇文章, 你无法学到:

与其他原理性的文章一样,本篇不涉及具体代码实现细节(对于程序员来说,只要思路搞通,代码咋写都不会太烂,大家应该都有体会)。

学习交流:

- 即时通讯/推送技术开发交流5群:215477170[推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

(本文同步发布于:http://www.52im.net/thread-2863-1-1.html

2、IM开发干货系列文章

本文是系列文章中的第20篇,总目录如下:

IM消息送达保证机制实现(一):保证在线实时消息的可靠投递

IM消息送达保证机制实现(二):保证离线消息的可靠投递

如何保证IM实时消息的“时序性”与“一致性”?

IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?

IM群聊消息如此复杂,如何保证不丢不重?

一种Android端IM智能心跳算法的设计与实现探讨(含样例代码)

移动端IM登录时拉取数据如何作到省流量?

通俗易懂:基于集群的移动端IM接入层负载均衡方案分享

浅谈移动端IM的多点登陆和消息漫游原理

IM开发基础知识补课(一):正确理解前置HTTP SSO单点登陆接口的原理

IM开发基础知识补课(二):如何设计大量图片文件的服务端存储架构?

IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议

IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token

IM群聊消息的已读回执功能该怎么实现?

IM群聊消息究竟是存1份(即扩散读)还是存多份(即扩散写)?

IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列

一个低成本确保IM消息时序的方法探讨

IM开发基础知识补课(六):数据库用NoSQL还是SQL?读这篇就够了!

IM里“附近的人”功能实现原理是什么?如何高效率地实现它?

IM开发基础知识补课(七):主流移动端账号登录方式的原理及设计思路》(本文)

3、最经典的用户名密码注册登陆方式

一个典型的用户名密码注册登陆功能类似于下面这样:

 

这种账号登陆方式很经典也很常用,先注册、再进行登录,尤其在老一点的CMS系统、网站系统、聊天应用中都能找到这个影子。

它的技术原理流程图如下:

 
 

如上图所示,详细的流程说明如下:

  • 1)前端将用户名、密码发送到服务器,服务器进行常规的判断,判断用户名、密码长度是否满足,用户名是否重复等条件,条件不通过直接返回对应错误码给到前端,这里密码字段,为了防止传输过程中被截胡,建议加密再上传,我们的传输密码默认都是会进行一个md5加密,然后记录到数据库再进行一层加密,就算是脱库也没事,密码不要明文存储。
  • 2)校验通过后,就将用户名密码写入数据库,并进行后面积分发放等操作,这里不展开。
  • 3)现在进行登录,前端将用户名,密码发送给到服务端,服务端首先会校验登录次数是否超过设置的阈值,如果超过只能继续等待被关小黑屋。
  • 4)如果未超过继续登录逻辑,判断用户名、密码是否正确,不正确密码则进行阈值的判断,如果超过则关小黑屋,记住小黑屋必须设置过期时间,要不然就会永久关上了,这个可以用redis的过期来做。
  • 5)登录成功后进行后续的一切后置逻辑,比如加积分。。。等操作。

这种经典的注册登陆方式,具体怎么设计就不在这里赘述了,谁都懂。

4、现今最主流的手机号注册登陆方式

4.1 基本原理

典型的手机号注册登陆功能类似于下图:

 

典型的手机号注册技术原理流程图如下:

 
 

如上图所示,详细的流程说明如下:

  • 1)首先输入手机号:然后发送到服务端,服务端将手机号记录在我们数据库中,然后生成随机验证码,并将手机号和验证码绑定到一个redis里面,然后记录过期时间,这个过期时间一般是10分钟左右,这就是我们一般手机验证码的有效期;
  • 2)手机接收到手机短信后:那么就在界面填写验证码发送服务端,服务端收到验证码后就会在redis里面查询到这个手机号对应的验证码,失败就返回错误码。
  • 3)成功后:就进行登录操作。

这里看起来没有明确的注册登录操作,其实在发送手机号码就可以认为是一个常规的注册,然后后面的验证码输入就是一个登陆操作。

但这种区别于常见的用户名密码注册方式,是没有密码的的。

问: 那我要密码咋办?

答: 在后续产品里面增加一个手机号码密码补录的功能即可,这也是现在很常规的手法,但是现在移动互联网大爆炸时代,密码已经显得不是那么重要了,反正我从来记不住密码,如果手机号码能操作的app,绝对不用密码来操作。

4.2 具体的数据库设计

表结构: 

说明:

这里只是单纯说明需要用到的数据,没有扩展具体场景,这个表结构能够满足上面两个方案的设计。

5、一种辅助的登陆方式:第3方账号登陆

5.1 基本原理

现在很多应用为了降低新用户的使用门槛,都会对接第3方账号进行登陆(比如:用微信号登陆、QQ号登陆、微博账号登陆等)。

这里我以QQ的开放平台登录逻辑为例进行讲解。

某团外卖的QQ账号登陆功能如下图:

 

我们先来一波时序图:

 
 

时序流程详细说明:

  • 1)客户端自己调起登录的界面,进行输入用户名、密码,这里的是第三方的用户名,密码,登录成功后,会返回access_token openid expire_in,这过程会使用到oauth2.0,不过在sdk里面进行内置回调获取了,后面我们会说明我们自身实现的oauth2.0;
  • 2)客户端拿到access_token、openid、login_type(qq、wechat...)请求应用服务器,应用服务器拿到这些数据后就会根据对应的login_type去对应的用户中心进行access_token和openid进行校验。校验不通过则返回对应错误码;
  • 3)校验通过后就会判断本地是否有这个login_type和openid是否存在,不存在则进行获取远程的用户名、头像等基础信息来作为本地基础数据,并且返回code值;
  • 4)如果已经存在,那就是进行登录操作,返回code值;
  • 5)客户端拿到code值后进行token值的换取,这个完全遵照oauth2.0的协议来走的,后续每次请求必须带上token,token值在服务端的时间比较久,因为我们想要做的是那种永不下线的操作,所以每次请求我们都将token过期时间进行累加。

想要深入了解第3方账号登陆,可以读读这两篇:《第三方登录:QQ登录接入指南》、《第三方账号登录功能接入完全流程》。

5.2 具体的数据库设计

表结构:

对于读者的建议,我这里做一下数据库的整理。

 

用户基础表(users):

 

用户验证关联表(user_auth_rel): 

 

本地用户表(user_local_auth):

 

第三方用户表(user_third_auth): 

 

表结说明:

  • 1)users表只是单纯针对我们业务侧的登录,主要是做自身业务的oauth2.0业务;
  • 2)user_local_auth是做自己用户名、密码登录,手机号码登录信息记录;
  • 3)user_third_auth是我们第三方用户体系的数据记录;
  • 4)user_auth_rel是用来关联我们users表与user_local_auth、user_third_auth;
  • 5)整个设计理念就是将自建用户与第三方在存储上区分,这在架构演进上也是合乎情理的,开始用户体系大多自建,而后才是对外接入。

6、本文小结

总的来讲,账号注册登录功能在一般的系统里都是入口功能,一般情况下都不会太复杂。

对于第三方用户的接入技术,也同样比较简单,我文章里设计多一个user_thirds是可以支持足够多的第三方接入,当然一般我们也就两三个登录就好,太多登录方不仅自身维护成本,界面摆盘也不好看不是。

希望大家能够通过以上学习,能够对于账户注册登录有一个比较好的认知,文章里设计方案不包含分表分库、没有服务化,就是简单直接的设计,当然用户量和需要的不一样,在这个基础上还要加很多东西,谢谢大家阅读。

附录:更多IM开发方面的文章

[1] IM开发综合文章:

新手入门一篇就够:从零开发移动端IM

移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”

移动端IM开发者必读(二):史上最全移动弱网络优化方法总结

从客户端的角度来谈谈移动端IM的消息可靠性和送达机制

现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障

腾讯技术分享:社交网络图片的带宽压缩技术演进之路

小白必读:闲话HTTP短连接中的Session和Token

IM开发基础知识补课:正确理解前置HTTP SSO单点登陆接口的原理

移动端IM开发需要面对的技术问题

开发IM是自己设计协议用字节流好还是字符流好?

请问有人知道语音留言聊天的主流实现方式吗?

一个低成本确保IM消息时序的方法探讨

完全自已开发的IM该如何设计“失败重试”机制?

通俗易懂:基于集群的移动端IM接入层负载均衡方案分享

微信对网络影响的技术试验及分析(论文全文)

即时通讯系统的原理、技术和应用(技术论文)

开源IM工程“蘑菇街TeamTalk”的现状:一场有始无终的开源秀

QQ音乐团队分享:Android中的图片压缩技术详解(上篇)

QQ音乐团队分享:Android中的图片压缩技术详解(下篇)

腾讯原创分享(一):如何大幅提升移动网络下手机QQ的图片传输速度和成功率

腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(上篇)

腾讯原创分享(三):如何大幅压缩移动网络下APP的流量消耗(下篇)

如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源

基于社交网络的Yelp是如何实现海量用户图片的无损压缩的?

腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的(图片压缩篇)

腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的(音视频技术篇)

字符编码那点事:快速理解ASCII、Unicode、GBK和UTF-8

全面掌握移动端主流图片格式的特点、性能、调优等

子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践

微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)

自已开发IM有那么难吗?手把手教你自撸一个Andriod版简易IM (有源码)

融云技术分享:解密融云IM产品的聊天消息ID生成策略

适合新手:从零开发一个IM服务端(基于Netty,有完整源码)

拿起键盘就是干:跟我一起徒手开发一套分布式IM系统

>> 更多同类文章 …… 

[2] 有关IM架构设计的文章:

浅谈IM系统的架构设计

简述移动端IM开发的那些坑:架构设计、通信协议和客户端

一套海量在线用户的移动端IM架构设计实践分享(含详细图文)

一套原创分布式即时通讯(IM)系统理论架构方案

从零到卓越:京东客服即时通讯系统的技术架构演进历程

蘑菇街即时通讯/IM服务器开发之架构选择

腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT

微信后台基于时间序的海量数据冷热分级架构设计实践

微信技术总监谈架构:微信之道——大道至简(演讲全文)

如何解读《微信技术总监谈架构:微信之道——大道至简》

快速裂变:见证微信强大后台架构从0到1的演进历程(一)

17年的实践:腾讯海量产品的技术方法论

移动端IM中大规模群消息的推送如何保证效率、实时性?

现代IM系统中聊天消息的同步和存储方案探讨

IM开发基础知识补课(二):如何设计大量图片文件的服务端存储架构?

IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议

IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token

WhatsApp技术实践分享:32人工程团队创造的技术神话

微信朋友圈千亿访问量背后的技术挑战和实践总结

王者荣耀2亿用户量的背后:产品定位、技术架构、网络方案等

IM系统的MQ消息中间件选型:Kafka还是RabbitMQ?

腾讯资深架构师干货总结:一文读懂大型分布式系统设计的方方面面

以微博类应用场景为例,总结海量社交系统的架构设计步骤

快速理解高性能HTTP服务端的负载均衡技术原理

子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践

知乎技术分享:从单机到2000万QPS并发的Redis高性能缓存实践之路

IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列

微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)

微信技术分享:微信的海量IM聊天消息序列号生成实践(容灾方案篇)

新手入门:零基础理解大型分布式架构的演进历史、技术原理、最佳实践

一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践

阿里技术分享:深度揭秘阿里数据库技术方案的10年变迁史

阿里技术分享:阿里自研金融级数据库OceanBase的艰辛成长之路

社交软件红包技术解密(一):全面解密QQ红包技术方案——架构、技术实现等

社交软件红包技术解密(二):解密微信摇一摇红包从0到1的技术演进

社交软件红包技术解密(三):微信摇一摇红包雨背后的技术细节

社交软件红包技术解密(四):微信红包系统是如何应对高并发的

社交软件红包技术解密(五):微信红包系统是如何实现高可用性的

社交软件红包技术解密(六):微信红包系统的存储层架构演进实践

社交软件红包技术解密(七):支付宝红包的海量高并发技术实践

社交软件红包技术解密(八):全面解密微博红包技术方案

社交软件红包技术解密(九):谈谈手Q红包的功能逻辑、容灾、运维、架构等

即时通讯新手入门:一文读懂什么是Nginx?它能否实现IM的负载均衡?

即时通讯新手入门:快速理解RPC技术——基本概念、原理和用途

多维度对比5款主流分布式MQ消息队列,妈妈再也不担心我的技术选型了

从游击队到正规军(一):马蜂窝旅游网的IM系统架构演进之路

从游击队到正规军(二):马蜂窝旅游网的IM客户端架构演进和实践总结

IM开发基础知识补课(六):数据库用NoSQL还是SQL?读这篇就够了!

瓜子IM智能客服系统的数据架构设计(整理自现场演讲,有配套PPT)

阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处

>> 更多同类文章 ……

(本文同步发布于:http://www.52im.net/thread-2863-1-1.html

posted @ 2019-12-07 19:38 Jack Jiang 阅读(46) | 评论 (0)编辑 收藏

1、引言

整个暑假去面试,面试了很多家公司(无论是小厂还是大厂)问到的深度不同,网络原理是面试最容易问到的问题,虽然我们在项目中很少去实践它,但是了解其原理,会让我们背后网络通信是如果工作的,既能在面试官面前体现出你的基础是否扎实,也能对以后深入网络这部分学习有更多的了解。

很多同学面试在准备这部分的时候,都会去背,这部分确实很难掌握,我个人总结的最好的学习网络原理的方法就是不用刻意的去记忆而是完全的结合实际去讲整个原理融会贯通。虽然一开始学习起来很吃力,但是稍微用点心,多看几遍,多问自己为什么,把自己当做是开发网络原理的开发者,面试前的准备只要理清逻辑就足够了,而不是去背这部分内容。

而且这部分相同的知识点面试官有多种提问方式,但是其中很多都是换汤不换药。我记得最多的问的是输入URL,到页面呈现出来,其中经历了什么?这道面试题的背后,涉及到了很多网络原理的知识,我们这篇文章不会全部分享到,而是先把由来和网络层次划分弄清楚,就完成了这篇文章的目的。

(本文同步发布于:http://www.52im.net/thread-2851-1-1.html

相关文章:

网络编程懒人入门(一):快速理解网络通信协议(上篇)》(* 力荐)

网络编程懒人入门(二):快速理解网络通信协议(下篇)》(* 力荐)

网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门

网络编程懒人入门(九):通俗讲解,有了IP地址,为何还要用MAC地址?

学习交流:

- 即时通讯/推送技术开发交流5群:215477170[推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

2、关于作者

小鹿(前端工程师):

微信公众号:小鹿动画学编程

Github地址:https://github.com/luxiangqiang

个人博客:http://luxiangqiang.com/

3、系列文章

本文是系列文章中的第7篇,本系列大纲如下:

脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?

脑残式网络编程入门(三):HTTP协议必知必会的一些知识

脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)

脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?

脑残式网络编程入门(六):什么是公网IP和内网IP?NAT转换又是什么鬼?

脑残式网络编程入门(七):面视必备,史上最通俗计算机网络分层详解》(本文)

4、为什么要进行网络层次划分?

说到网络层次划分并不陌生,我刚刚接触到网络层次的时候一脸懵逼,这么多层,一层不就行了嘛?层与层之间好多协议,还有各种数据包,第一次我放弃了。

当我从新拾起网络层次的时候,我下定决心从根上理解它。首先弄明白它的原理,那必定要知道它的由来,也就是为什么要进行网络层次划分?这个问题问的好。

假如“小鹿”是网络的开发人员,起初认为计算机与计算机之间的通信只需要一根线就可以完成通信,对没错,但是世界那么大,那么多计算机,距离又远,不但浪费线,还没出现各种线被你偷偷剪断的情况,毋庸置疑,那计算机之间通信就不行了。(后边出来了无线网,虽然其中网关、路由之间也需要连线,但不是让每台计算机两两连接,而是一个区域为单位计算机相互连接通信)

不行,老板说,“小鹿”你给我想法子改,改不出来今晚不能睡觉,“小鹿”仔细想了想,这还是个技术活,需要进行全面的改进,也发现所谓的计算机之间的连线只能传送0、1信号,另一台计算并不知道那么多0、1代表什么,而且“小鹿”又发现不同厂商的生产的计算机既然有连线实现通信也是很麻烦的,干脆定义一套规则吧,无论“某硕”计算机还是“某想”计算机,都必须遵守这套规则,其实所说的这套规则就是我们经常说的“网络协议”。

不是说网络层次的由来吗,怎么讲到网络协议了。咱们继续,通过上面的问题,那个计算机之间通过连线传送0、1信号的问题虽然规定了通信规则,但是除了像0、1这种无意义的信号之外,网络中还存在着其他各种各样的问题,两个计算机之间怎么进行识别?以及怎么才能知道对方的地址?以及不同计算机应用程序怎么知道是给自己传递的数据,还有不同的通信数据格式怎么来规定等等一系列的问题都出来了。

“小鹿”发现,如果各种问题都写成一套协议来规定双方通信的规则,但是呢?万一其中哪些规则通信中出现问题,影响到了其他规则,最常见的就是数据包,一个数据包中如果包含各种各样的协议,不就乱套了。

“小鹿”为了能够把它设计的更好,决定采用分层划分的结构,既能规定不同层的完成的功能,又能实现层与层之间的改动而不相互影响,这就是我们经常听到网络划分层次的好处。

5、网络分层是如何进行分层的?

既然我们决定要分层,那么分为几层才好呢?

起初网络分层是标准的七层,也就是我们所说的 OSI 七层模型。

 

▲ OSI参考模型或七层模型

我们所知道的还有 TCP/IP 四层模型和 TCP/IP 五层模型。这又是怎么出来的,其实所谓的 TCP/IP 四层模型和 TCP/IP 五层模型是以 OSI 七层优化而来,把某些层进行合并了,其实本质上还是相同的,但是我个人最喜欢用五层来解释。

 

▲ 五层模型

6、每一层的作用是什么?

这一部分涉及到每一层的很多协议和知识点,但是我们这一节不具体分享,为什么?我们具体深入之前必须大脑里有个具体的网络分层结构图,先要知道每层是做什么的,层与层之间的关系,然后下一节再深入每层中的每个协议怎么通信的,这样的好处学起来条理清晰,而不至于当时我学习的时候表面还不懂,就深入最后懵逼状态。

6.1 物理层

物理层,顾名思义,用物理手段将电脑连接起来,就像我们上边讲到的计算机之间的物理连线。主要用来传输0、1信号,上边也分析过了,0、1信号毕竟没有任何的现实意义,所有我们用另一层用来规定不同0、1组合的意义是什么。

6.2 数据链路层

下层的物理层既然不能规定不同0、1组合的信号代表什么意义,那么我们在数据链路层规定一套协议,专门的给0、1信号进行分组,以及规定不同的组代表什么意思,从而双方计算机都能够进行识别,这个协议就是“以太网协议”(具体的以太网协议内容下节内容详细讲解)。

但是问题又来了,我们要发送给对方计算机,怎么标识对方以及怎么知道对方的地址呢?

6.2.1)MAC 地址:

我们所说的MAC地址到底的作用是啥?说白了它就是作为网络中计算机设备的唯一标识,从计算机在厂商生产出来就被十六进制的数标识为MAC地址。

既然我们知道了用MAC地址作为标识,那么怎么才能知道我们要进行通信的计算机MAC地址呢?

6.2.2)广播:

这里广播详细的在下一节讲,这一节你只需要知道广播可以帮助我们能够知道对方的 MAC 地址。那么既然知道了MAC地址就可以通信了?没有想得那么简单,广播中还存在两种情况,一种是,在同一子网络下(同一局域网下)的计算机是通过 ARP 协议获取到对方 MAC地址的。不同自网络中(不同局域网)中是交给两个局域网的网关(路由器)去处理的。这里边涉及到很多细节的知识,都会集中到下一节,但是这一节你了解怎么进行标识计算机和怎么获取到MAC地址就可以了。

6.3 网络层

物理层和数据链路层都有自己的事情要做,也就是我们上边所讲到的这些(里边很多细节不在这节多说)。上边两层在我看来可以完成正常通信了,那么网络层出来干啥子?

网络层的由来是因为在数据链路层中我们说说两台计算机之间的通信是分为同一子网络和不同子网络之间,那么问题就来了,怎么判断两台计算机是否在同一子网络(局域网)中?这就是网络层要解决的问题。

6.3.1)IP 协议:

我们通常用到的 IP 地址,就是网络层中的东西,所规定的的协议就是 IP 协议。很多小伙伴问,IP 地址想必也是地址吧,上边都有唯一标识的 MAC 地址了,IP 地址出来是混饭吃的?为了能够让大家更方便的理解 IP 地址和 MAC 地址,我们可以将 IP 地址抽象成一种逻辑上的地址,也就是说 MAC 地址是物理上的地址,就是定死了。IP 地址呢,是动态分配的,不是固定死的。

我们就是通过 IP 地址来判断两个计算机设备是否在同一子网络中的,那么你会问它是怎么判断的,以及 IP 地址谁给他分配的?又是如何分配的等一些列问题,我们不着急,这里只说一下大体的流程,详细会后续写一大篇。

既然我们通过 IP 地址来判断两个计算机是否处于同一局域网中,那么首先要知道对方的 IP 地址吧?DNS 解析想必大家都知道,可以将域名解析为 IP 地址。好了,我们知道两台计算机的 IP 地址了,怎么进行判断是否同一局域网中?

6.3.2)子网掩码:

嘿嘿,又是一个只听说过,但是不知道这个什么作用的一个名词,没事,等我聊完,你就明白是做什么的了。

子网掩码就是用来标识同一局域网中的 IP 地址的信息的?什么信息?IP 地址是由 32 个二进制位组成的,也就是四个十进制(如:255.255.255.000)。

子网掩码也是由 32 个二进制位组成的,但是只能用 0 或 1 来表示,如:11111111.11111111.11111111.00000000。

到底什么意思呢?有 1 的部分表示网络部分,有 0 表示主机部分,这和判断两台计算机是否在同一局域网中有什么关系?没错,是有关系的!两台计算机的 IP 地址分别和子网掩码进行一种运算(AND 运算),如果结果相同,两台计算机就在同一局域网中,否则就不在同一局域网中。

AND 是如何进行运算的,IP 的数据包的组成等问题,不在这里多陈述。

6.4 传输层

好了,如果你认为计算机可以进行通信了,那么“小鹿”恭喜你,你已经基本知道了以上几层划分的作用,但是如果你正在一边打 LOL,一边和朋友在 QQ 聊天,突然,游戏中队友聊天信息出现在了 QQ 窗口中,咦?出现了什么情况?

其实是以上层级还是不够,出现上边的原因就是,两台计算机虽然可以通信了,但是每天计算机运行着好多的程序,谁知道你们传输的信息是属于哪些程序的,怨不得 LOL 的聊天信息跑到了 QQ 窗口中。

想必大家猜到了传输层主要用来干啥滴,是的,传输层的主要功能就是为了能够实现“端口到端口”的通信。计算机上运行的不同程序都会分配不同的端口,所以才能使得数据能够正确的传送给不同的应用程序。

6.4.1)UDP 协议:

加入端口号也需要一套规则,那就是 UDP 协议,但是 UDP协议有个缺点,一旦进行通信,就不知道对方是否接收到数据了,我们再定义一套规则,让其可以和对方进行确认,那么 TCP 出现了。

6.4.2)TCP 协议:

我们通常说 TCP 三次握手和四次挥手,没错,这就是传输层中完成的,TCP 三次握手涉及到的内容贼多,都可以单独写一篇长文,这里不多陈述,知道它是在传输层中完成的以及它的作用是什么,能够认识到它就好了。

6.5 应用层协议

“喂,你发给我的是什么破数据,乱七八糟的,我TM能解析吗?能不能按照我的规定给我传送?“

“好的,下次不敢了”

想必大家已经猜到了应用层的协议,应用层的功能就是规定了应用程序的数据格式。我们经常用得到的电子邮件、HTTP协议、以及FTP数据的格式,就是在应用层定义的。

7、每一层的的功能细节是什么?

前面章节主要分享了网络分层的基本概念,为什么要进行网络分层?又是如何进行分层?每一层的基本功能是什么?而且对于每一层的的功能细节方面,比如数据包的组成以及每层包含的一些协议的使用都没有细说,那么本节将继续分享网络分层每层中协议等深入讲解。(PS:可能里边有的讲解不正确,还请大佬指出改正)

7.1 物理层

物理层里边涉及到最多的是硬件底层的一些内容,没有需要过多了解的内容,我们直接看数据链路层。

7.2 数据链路层

上回讲到数据链路层中规定的“以太网协议”来规定电信号的分组形式,什么是以太网,以太网的数据包是什么样子的?

7.2.1)以太网协议:

以太网规定,每组的电信号就是一个数据包,每个数据包我们可以成为“帧”。每帧的组成是由标头(Head)和数据(Data)组成。

 

那么你会问,标头里有什么信息?Data 数据又会存放写什么?为什么分为两部分?放在一块不好吗?

a)标头:

为什么传输数据会有标头,我们想呀,在传输数据的时候,接收端怎么判断是不是给自己发送的,那么就只取出标头来进行判断。

数据包的标头中通常会存放一些有关数据包的说明、发送者是谁、接受者又是谁等相关识别信息。

标头的长度固定为 18 字节,也就是说,一些标头识别信息的大小不能超过 18 字节。

b)数据:

数据,顾名思义,你要传输给接收端什么数据都会放到数据包中,也就是整个数据包的具体内容,比如文件、字符串之类的。

数据部分的长度最小至少为 46 个字节,最长 1500 字节。我们可能会想到,如果小于 46 字节没啥问题可以存放开,那么大于 1500 字节怎么处理呢?很简单,我们就分成两个包处理(分割),两个包存放不下就分割成三个包…

7.2.2)广播:

上回说到,广播的作用就是用来查找接收端的 MAC 地址,从而进行下一步的数据传输。注意,广播只是一种发送数据的形式,而计算机想要知道另一台计算机的 MAC 地址是通过 ARP 协议解决的,ARP 协议会在讲完 IP 协议后再说,因为它会涉及到 IP 协议的一点内容,现在讲可能会有点乱。

如果你觉的上边稍微有点乱,那怎们稍微屡一下,我们想要发送数据,首先要知道对方的唯一标识(MAC 地址),要想知道对方的 MAC 地址,需要使用 ARP 协议,假设我们通过 ARP 协议拿到了接收方的 MAC 地址。

我们开始发送数据,将发送方的 MAC 地址和接收方的 MAC 地址封装在数据包中,然后发送端向同一子网络中(同一局域网)中的所有计算机发送该数据包,所有的计算机接收到该包之后,就对数据包的头部进行提取,提取出里边封装好的接收端 MAC 地址和自己的 MAC 地址作比对,如果相同,就说明该数据包是给自己发送的,否则,就会丢弃该数据包,这个过程就是广播的过程。

上一篇文章在这个地方留下的一个问题就以上是在同一局域网中,如果不在同一局域网中我们怎么处理?我们平常使用无线网都知道每个无线局域网都会有一个路由器,我们先通过以上的方法将数据发送到路由器,然后路由器转发数据到其他局域网中的计算机。

7.3 网络层

网络层中最重要的一个协议就是 IP 协议,我们一般发送端给服务端发送数据同时要知道两个地址才能准确送达到对方,分别为 IP 地址和 MAC 地址。停!stop! 上边讲到的明明知道对方的 MAC 地址就可以传输数据了,为什么现在需要两个地址呢?你给我说明白,说不明白取关!

上边确实是一个 MAC 地址就可以通信,但是前提是通过 ARP 协议获得的 MAC 地址,而 ARP 协议正是利用的接收端的 IP 地址才获取到接收端的 MAC 地址的,所以这两个地址很重要,那么如果实现的,下边会继续讲。

7.3.1)IP 协议:

IP 的数据包是直接放入到以太网数据包的“数据”部分的,这样做有一个好处就是“上层的变动完全涉及不到下层的结构”。然后数据包就变成这个样子了。

 

IP 数据包也分为标头(Head)和数据(Data)两部分:

  • 1)标头:IP 数据包的标头是 20 ~ 60 字节,主要包括版本、IP 地址等信息;
  • 2)数据:数据的最大长度为 65515 字节。整个 IP 数据包的最大总长度为 65535 字节。主要存放 IP 数据包的具体内容。

问题来了,以太网的数据部分最长为 1500 字节,你把一个长度为 65535 字节的 IP 数据包放到以太网的数据包汇总,不会被撑破吗?你在逗我么?确实是呀,那我们就分割数据包吧,分割成几个以太网数据包分开发送。

7.3.2)AND 运算:

IP 协议上篇文章中最重要的作用就是判断两个设备是否属于同一子网中(同一局域网中)。

将两个IP地址与子网掩码分别进行AND运算(两个数位都为1,运算结果为1,否则为0),然后比较结果是否相同,如果是的话,就表明它们在同一个子网络中,否则就不是。

我们可以通过 DNS 解析知道对方的 IP ,除了判断两个计算机是否在同一局域网中,还有一个作用就是然后通过 ARP 协议获取到对方的 MAC 地址。停!真想让我取关吗?ARP 就 TN 的说了多少遍了,该详细说一下了吧?

7.3.3)ARP 协议:

前提:对方的 IP 地址是已知的,通过 DNS 解析得到。

ARP 协议发出一个数据包,包含在以太网的数据包中(其中包含对方的 IP 地址,对方的 MAC 地址栏是 FF:FF:FF:FF:FF:FF)。子网络中的每台主机都会收到这个包,然后从中取出 IP 地址与自身对比,如果两者相同,都做出回复,向对方报告自己的 MAC 地址,否则就丢弃这个包。

7.4 传输层

传输层主要涉及到两个重要协议,UDP 和 TCP 协议,上篇讲过主要用来确定端口到端口的通信,计算机中不同运行的程序端口号不相同。

"端口"是 0 到 65535 之间的一个整数,正好 16 个二进制位。0 到 1023的端口被系统占用,我们只能选用大于1023 的端口。

7.4.1)UDP 协议:

UDP 协议也分为标头(Head)和数据(Data)两部分:

  • 1)标头:标头的长度为 8 字节。主要存放了发送和接收端口号;
  • 2)数据:数据部分和标头部分的总长度不超过 65535 字节,正好放进一个IP数据包。

前边也讲过,数据包之间是包含关系的,所以 UDP 的数据包是放到 IP 数据包的“数据”部分的,IP 数据包又放在以太网数据包的“数据”部分的。

 

7.4.2)TCP 协议:

TCP 和 UDP 是相同的,上一篇讲了 UDP 和 TCP 的优缺点,TCP 保证了网络的可靠性,TCP 三次握手和四次挥手就是这部分内容。

TCP 的数据包和 UDP 相同嵌入在 IP 协议的“数据”部分,TCP 并没有长度限制,但是为了保证传输效率,肯定要进行限制的,TCP 的数据包的长度一般不会超过 IP 数据包的长度了,保证单个的 TCP 数据包不再进行分割。

7.5 应用层

应用层是最高一层,直接面向用户,它的数据包会放在 TCP 的数据包的“数据”部分,那么整个五层的数据包就会变成一下这样。

 

以上五层中的内容基本讲完了,我是从下到上逐层写的,这篇文章可以让你入门网络五层协议的基本内容了。

8、写在最后

如果本文内容看完,还是有点懵,那怎么办?

可以继续以下两篇文章,它们应该可以让你内力倍增:

网络编程懒人入门(一):快速理解网络通信协议(上篇)

网络编程懒人入门(二):快速理解网络通信协议(下篇)

另外,关于计算机网络协议的分层和关系,可以看看下面两图:

 

* 上述两张图的清晰原图,请见:《计算机网络通讯协议关系图(中文珍藏版)[附件下载]》。

附录:更多网络编程基础资料

TCP/IP详解 - 第11章·UDP:用户数据报协议

TCP/IP详解 - 第17章·TCP:传输控制协议

TCP/IP详解 - 第18章·TCP连接的建立与终止

TCP/IP详解 - 第21章·TCP的超时与重传

技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)

通俗易懂-深入理解TCP协议(上):理论基础

通俗易懂-深入理解TCP协议(下):RTT、滑动窗口、拥塞处理

理论经典:TCP协议的3次握手与4次挥手过程详解

理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程

计算机网络通讯协议关系图(中文珍藏版)

UDP中一个包的大小最大能多大?

P2P技术详解(一):NAT详解——详细原理、P2P简介

P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解

P2P技术详解(三):P2P技术之STUN、TURN、ICE详解

通俗易懂:快速理解P2P技术中的NAT穿透原理

高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少

高性能网络编程(二):上一个10年,著名的C10K并发连接问题

高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了

高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索

高性能网络编程(五):一文读懂高性能网络编程中的I/O模型

高性能网络编程(六):一文读懂高性能网络编程中的线程模型

Java的BIO和NIO很难懂?用代码实践给你看,再不懂我转行!

不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)

不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)

不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT

不为人知的网络编程(四):深入研究分析TCP的异常关闭

不为人知的网络编程(五):UDP的连接性和负载均衡

不为人知的网络编程(六):深入地理解UDP协议并用好它

不为人知的网络编程(七):如何让不可靠的UDP变的可靠?

不为人知的网络编程(八):从数据传输层深度解密HTTP

不为人知的网络编程(九):理论联系实际,全方位深入理解DNS

网络编程懒人入门(一):快速理解网络通信协议(上篇)

网络编程懒人入门(二):快速理解网络通信协议(下篇)

网络编程懒人入门(三):快速理解TCP协议一篇就够

网络编程懒人入门(四):快速理解TCP和UDP的差异

网络编程懒人入门(五):快速理解为什么说UDP有时比TCP更有优势

网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门

网络编程懒人入门(七):深入浅出,全面理解HTTP协议

网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接

网络编程懒人入门(九):通俗讲解,有了IP地址,为何还要用MAC地址?

网络编程懒人入门(十):一泡尿的时间,快速读懂QUIC协议

技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解

让互联网更快:新一代QUIC协议在腾讯的技术实践分享

现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障

聊聊iOS中网络编程长连接的那些事

移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”

移动端IM开发者必读(二):史上最全移动弱网络优化方法总结

IPv6技术详解:基本概念、应用现状、技术实践(上篇)

IPv6技术详解:基本概念、应用现状、技术实践(下篇)

从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路

以网游服务端的网络接入层设计为例,理解实时通信的技术挑战

迈向高阶:优秀Android程序员必知必会的网络基础

全面了解移动端DNS域名劫持等杂症:技术原理、问题根源、解决方案等

美图App的移动端DNS优化实践:HTTPS请求耗时减小近半

Android程序员必知必会的网络通信传输层协议——UDP和TCP

IM开发者的零基础通信技术入门(一):通信交换技术的百年发展史(上)

IM开发者的零基础通信技术入门(二):通信交换技术的百年发展史(下)

IM开发者的零基础通信技术入门(三):国人通信方式的百年变迁

IM开发者的零基础通信技术入门(四):手机的演进,史上最全移动终端发展史

IM开发者的零基础通信技术入门(五):1G到5G,30年移动通信技术演进史

IM开发者的零基础通信技术入门(六):移动终端的接头人——“基站”技术

IM开发者的零基础通信技术入门(七):移动终端的千里马——“电磁波”

IM开发者的零基础通信技术入门(八):零基础,史上最强“天线”原理扫盲

IM开发者的零基础通信技术入门(九):无线通信网络的中枢——“核心网”

IM开发者的零基础通信技术入门(十):零基础,史上最强5G技术扫盲

IM开发者的零基础通信技术入门(十一):为什么WiFi信号差?一文即懂!

IM开发者的零基础通信技术入门(十二):上网卡顿?网络掉线?一文即懂!

IM开发者的零基础通信技术入门(十三):为什么手机信号差?一文即懂!

IM开发者的零基础通信技术入门(十四):高铁上无线上网有多难?一文即懂!

IM开发者的零基础通信技术入门(十五):理解定位技术,一篇就够

百度APP移动端网络深度优化实践分享(一):DNS优化篇

百度APP移动端网络深度优化实践分享(二):网络连接优化篇

百度APP移动端网络深度优化实践分享(三):移动端弱网优化篇

技术大牛陈硕的分享:由浅入深,网络编程学习经验干货总结

可能会搞砸你的面试:你知道一个TCP连接上能发起多少个HTTP请求吗?

知乎技术分享:知乎千万级并发的高性能长连接网关技术实践

>> 更多同类文章 ……

(本文同步发布于:http://www.52im.net/thread-2851-1-1.html

posted @ 2019-12-01 15:59 Jack Jiang 阅读(76) | 评论 (0)编辑 收藏

     摘要: 本文引用了唐小智发表于InfoQ公众号上的“钉钉企业级IM存储架构创新之道”一文的部分内容,收录时有改动,感谢原作者的无私分享。1、引言业界的 IM 产品在功能上同质化较高,而企业级的 IM 产品对于高可用、安全性又有更高的要求,如何打造具备差异化的产品,又在高可用、安全性、数据一致性等方面具备较高的品质,是企业级 IM 产品成功的关键。钉钉在过去短短几年时间里,用户数已破...  阅读全文

posted @ 2019-11-26 15:32 Jack Jiang 阅读(55) | 评论 (0)编辑 收藏

     摘要: 本文原题“从实践角度重新理解BIO和NIO”,原文由Object分享,为了更好的内容表现力,收录时有改动。1、引言这段时间自己在看一些Java中BIO和NIO之类的东西,也看了很多博客,发现各种关于NIO的理论概念说的天花乱坠头头是道,可以说是非常的完整,但是整个看下来之后,发现自己对NIO还是一知半解、一脸蒙逼的状态(请原谅我太笨)。 基于以上原因,就有了写本文...  阅读全文

posted @ 2019-11-22 21:55 Jack Jiang 阅读(495) | 评论 (0)编辑 收藏

     摘要: 1、引言如今我们所处的时代,是移动互联网时代,也可以说是视频时代。从快播到抖音,从“三生三世”到“延禧攻略”,我们的生活,被越来越多的视频元素所影响。  而这一切,离不开视频拍摄技术的不断升级,还有视频制作产业的日益强大。 此外,也离不开通信技术的飞速进步。试想一下,如果还是当年的56K Modem拨号,或者是2G手机,...  阅读全文

posted @ 2019-11-19 11:00 Jack Jiang 阅读(421) | 评论 (0)编辑 收藏

     摘要: 本文引用了饿了么资深开发工程师万汨“Redis 到底是怎么实现“附近的人”这个功能的呢?”一文的内容,感谢原作者的分享,为了提升文章品质,即时通讯收录时有内容补充和修订。1、引言基本上以陌生人社交为主的IM产品里,都会增加“附近的人”、“附近的xxx”这种以LBS(地理位置)为导向的产品特色(微信这个熟...  阅读全文

posted @ 2019-11-12 15:04 Jack Jiang 阅读(359) | 评论 (0)编辑 收藏

1、TCP协议到底怎么了?

现时的互联网应用中,Web平台(准确地说是基于HTTP及其延伸协议的客户端/服务器应用)的数据传输都基于 TCP 协议。

但TCP 协议在创建连接之前需要进行三次握手(如下图 1,更详细原理请见《理论经典:TCP协议的3次握手与4次挥手过程详解》),如果需要提高数据交互的安全性,既增加传输层安全协议(TLS),还会增加更多的更多握手次数(如下图 2)。

 
▲ 图 1 - TCP的三次握手原理图
 
▲ 图 2  - TLS的初始化握手原理图

正如上面两张图里演示的原理,TCP 协议连接建立的成本相对较高。

所以,一般的稳定网络传输都是通过TCP,但是在网络基建本身就已经越来越完善的情况下,TCP设计本身的问题便暴露了出来,特别是在弱网环境下,让我们不得不考虑一些新的可能性。

(本文同步发布于:http://www.52im.net/thread-2816-1-1.html

2、QUIC协议登场

和 TCP 相反,UDP 协议是无连接协议。客户端发出 UDP 数据包后,只能“假设”这个数据包已经被服务端接收。这样的好处是在网络传输层无需对数据包进行确认,但存在的问题就是为了确保数据传输的可靠性,应用层协议需要自己完成包传输情况的确认。

此时,QUIC 协议就登场了。

QUIC 是 Quick UDP Internet Connections 的缩写,谷歌发明的新传输协议。

与 TCP 相比,QUIC 可以减少延迟。

QUIC 协议可以在 1 到 2 个数据包(取决于连接的服务器是新的还是已知的)内,完成连接的创建(包括 TLS)(如下图3所示)。

 

▲ 图 3  - QUIC 协议握手原理图

从表面上看:QUIC 非常类似于在 UDP 上实现的 TCP + TLS + HTTP/2。由于 TCP 是在操作系统内核和中间件固件中实现的,因此对 TCP 进行重大更改几乎是不可能的(TCP 协议栈通常由操作系统实现,如 Linux、Windows 内核或者其他移动设备操作系统。修改 TCP 协议是一项浩大的工程,因为每种设备、系统的实现都需要更新)。但是,由于 QUIC 建立在 UDP 之上,因此没有这种限制。QUIC 可以实现可靠传输,而且相比于 TCP,它的流控功能在用户空间而不在内核空间,那么使用者就不受限于 CUBIC 或是 BBR,而是可以自由选择,甚至根据应用场景自由调整优化。

QUIC 与现有 TCP + TLS + HTTP/2 方案相比,有以下几点主要特征:

1)利用缓存,显著减少连接建立时间;

2)改善拥塞控制,拥塞控制从内核空间到用户空间;

3)没有 head of line 阻塞的多路复用;

4)前向纠错,减少重传;

5)连接平滑迁移,网络状态的变更不会影响连接断线。

 

从图上可以看出,QUIC 底层通过 UDP 协议替代了 TCP,上层只需要一层用于和远程服务器交互的 HTTP/2 API。这是因为 QUIC 协议已经包含了多路复用和连接管理,HTTP API 只需要完成 HTTP 协议的解析即可。

有关QUIC的详解请见:《技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解》。

3、QUIC协议的目标

QUIC 协议的主要目的,是为了整合 TCP 协议的可靠性和 UDP 协议的速度和效率。

一张图看懂QUIC协议的优势:

 

对于 Google 来说优化 TCP 协议是一个长期目标,QUIC 旨在创建几乎等同于 TCP 的独立连接,但有着低延迟,并对类似 SPDY 的多路复用流协议有更好的支持。 如果 QUIC 协议的特性被证明是有效的,这些特性以后可能会被迁移入后续版本的 TCP 和 TLS 协议(它们都有很长的开发周期)。

值得注意的是,虽然理论上来说,如果 QUIC 的特性被证明是有效的,这些特性以后可能会被迁移到后续版本的 TCP 协议中,但鉴于TCP协议长达几十年在互联网通信里的垄断地位,以及这么多年积累下来的沉重历史报复,想要根本性地优化或改进TCP协议,难度相当大(或许,有些事情,只能是想想而已,IPV6还喊了这么多年呢,不是一样没普及。。。)。

4、QUIC协议这么好,可以大规模切换为QUIC吗?

理想和现实总是有一定的差距:虽然经过多年的推广的应用,但QUIC协议目前仍未达到大量普及的阶段,在 IETF上的QUIC 依然还是草稿,并且还存在Google QUIC与IETF QUIC两类不稳定的协定。

而且,QUIC还面临以下挑战:

1)小地方,路由封杀UDP 443端口( 这正是QUIC 部署的端口);

2)UDP包过多,由于QS限定,会被服务商误认为是攻击,UDP包被丢弃;

3)无论是路由器还是防火墙目前对QUIC都还没有做好准备。

5、QUIC协议实践

Chrome 浏览器从 2014 年开始已经实验性的支持了 QUIC 协议。可以通过在 Chrome 浏览器中输入 chrome://net-internals/#quic 查看是否已经支持 QUIC 协议。如果还未支持,可以在 chrome://flags/#enable-quic 中进行开启。

开始 Chrome 浏览器对 QUIC 协议的支持之后,可以在 chrome://net-internals/#quic 中查看到当前浏览器的 QUIC 一些连接。当然目前只有 Google 服务才支持 QUIC 协议(如 YouTube、 Google.com)。

 

Google 在 2015 年的一篇博文中分享了一些关于 QUIC 协议实现的结果,这些优势在诸如 YouTube 的视频服务上更为突出:用户报告通过 QUIC 协议在观看视频的时候可以减少 30% 的重新缓冲时间。

6、我想试试QUIC协议,可以怎么做?

目前支持 QUIC 协议的 web 服务只有 0.9 版本以后的 Caddy 。其他常用 web 服务如 nginx、apache 等都未开始支持。

整个 QUIC 协议比较复杂,想自己完全实现一套对笔者来说还比较困难。

所以先看看开源实现有哪些。

1)Chromium

这个是官方支持的。优点自然很多,Google 官方维护基本没有坑,随时可以跟随 chrome 更新到最新版本。不过编译 Chromium 比较麻烦,它有单独的一套编译工具。暂时不建议考虑这个方案。

2)proto-quic

从 chromium 剥离的一个 QUIC 协议部分,但是其 github 主页已宣布不再支持,仅作实验使用。不建议考虑这个方案。

3)goquic

goquic 封装了 libquic 的 go 语言封装,而 libquic 也是从 chromium 剥离的,好几年不维护了,仅支持到 quic-36, goquic 提供一个反向代理,测试发现由于 QUIC 版本太低,最新 chrome 浏览器已无法支持。不建议考虑这个方案。

4)quic-go

quic-go 是完全用 go 写的 QUIC 协议栈,开发很活跃,已在 Caddy 中使用,MIT 许可,目前看是比较好的方案。

那么,对于中小团队或个人开发者来说,比较推荐的方案是最后一个,即采用 caddy 来部署实现 QUIC。caddy 这个项目本意并不是专门用来实现 QUIC 的,它是用来实现一个免签的 HTTPS web 服务器的(caddy 会自动续签证书)。而QUIC 只是它的一个附属功能(不过现实是——好像用它来实现 QUIC 的人更多)。

从Github的技术趋势来说,有关QUIC的开源资源越来越多,有兴趣可以自已逐一研究研究:https://github.com/search?q=quic

7、本文小结

QUIC 协议开创性的使用了 UDP 协议作为底层传输协议,通过各种方式减少了网络延迟。

虽然目前 QUIC 协议已经运行在一些较大的网站上,但离大范围普及还有较长的一段距离,期待 QUIC 协议规范能够成为终稿,并在除了谷歌浏览器之外的其他浏览器和应用服务器中也能够实现。

8、参考资料

9、系列文章

附录:更多网络编程相关资料推荐

TCP/IP详解 - 第11章·UDP:用户数据报协议

TCP/IP详解 - 第17章·TCP:传输控制协议

TCP/IP详解 - 第18章·TCP连接的建立与终止

TCP/IP详解 - 第21章·TCP的超时与重传

技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)

通俗易懂-深入理解TCP协议(上):理论基础

通俗易懂-深入理解TCP协议(下):RTT、滑动窗口、拥塞处理

理论经典:TCP协议的3次握手与4次挥手过程详解

理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程

计算机网络通讯协议关系图(中文珍藏版)

UDP中一个包的大小最大能多大?

P2P技术详解(一):NAT详解——详细原理、P2P简介

P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解

P2P技术详解(三):P2P技术之STUN、TURN、ICE详解

通俗易懂:快速理解P2P技术中的NAT穿透原理

高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少

高性能网络编程(二):上一个10年,著名的C10K并发连接问题

高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了

高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索

高性能网络编程(五):一文读懂高性能网络编程中的I/O模型

高性能网络编程(六):一文读懂高性能网络编程中的线程模型

不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)

不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)

不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT

不为人知的网络编程(四):深入研究分析TCP的异常关闭

不为人知的网络编程(五):UDP的连接性和负载均衡

不为人知的网络编程(六):深入地理解UDP协议并用好它

不为人知的网络编程(七):如何让不可靠的UDP变的可靠?

不为人知的网络编程(八):从数据传输层深度解密HTTP

不为人知的网络编程(九):理论联系实际,全方位深入理解DNS

技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解

让互联网更快:新一代QUIC协议在腾讯的技术实践分享

现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障

聊聊iOS中网络编程长连接的那些事

移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”

移动端IM开发者必读(二):史上最全移动弱网络优化方法总结

IPv6技术详解:基本概念、应用现状、技术实践(上篇)

IPv6技术详解:基本概念、应用现状、技术实践(下篇)

从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路

脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?

脑残式网络编程入门(三):HTTP协议必知必会的一些知识

脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)

脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?

脑残式网络编程入门(六):什么是公网IP和内网IP?NAT转换又是什么鬼?

以网游服务端的网络接入层设计为例,理解实时通信的技术挑战

迈向高阶:优秀Android程序员必知必会的网络基础

全面了解移动端DNS域名劫持等杂症:技术原理、问题根源、解决方案等

美图App的移动端DNS优化实践:HTTPS请求耗时减小近半

Android程序员必知必会的网络通信传输层协议——UDP和TCP

IM开发者的零基础通信技术入门(一):通信交换技术的百年发展史(上)

IM开发者的零基础通信技术入门(二):通信交换技术的百年发展史(下)

IM开发者的零基础通信技术入门(三):国人通信方式的百年变迁

IM开发者的零基础通信技术入门(四):手机的演进,史上最全移动终端发展史

IM开发者的零基础通信技术入门(五):1G到5G,30年移动通信技术演进史

IM开发者的零基础通信技术入门(六):移动终端的接头人——“基站”技术

IM开发者的零基础通信技术入门(七):移动终端的千里马——“电磁波”

IM开发者的零基础通信技术入门(八):零基础,史上最强“天线”原理扫盲

IM开发者的零基础通信技术入门(九):无线通信网络的中枢——“核心网”

IM开发者的零基础通信技术入门(十):零基础,史上最强5G技术扫盲

IM开发者的零基础通信技术入门(十一):为什么WiFi信号差?一文即懂!

IM开发者的零基础通信技术入门(十二):上网卡顿?网络掉线?一文即懂!

IM开发者的零基础通信技术入门(十三):为什么手机信号差?一文即懂!

IM开发者的零基础通信技术入门(十四):高铁上无线上网有多难?一文即懂!

IM开发者的零基础通信技术入门(十五):理解定位技术,一篇就够

百度APP移动端网络深度优化实践分享(一):DNS优化篇

百度APP移动端网络深度优化实践分享(二):网络连接优化篇

百度APP移动端网络深度优化实践分享(三):移动端弱网优化篇

技术大牛陈硕的分享:由浅入深,网络编程学习经验干货总结

可能会搞砸你的面试:你知道一个TCP连接上能发起多少个HTTP请求吗?

知乎技术分享:知乎千万级并发的高性能长连接网关技术实践

>> 更多同类文章 ……

(本文同步发布于:http://www.52im.net/thread-2816-1-1.html

posted @ 2019-11-01 14:32 Jack Jiang 阅读(484) | 评论 (0)编辑 收藏

     摘要: 本文由ITPub根据封宇在【第十届中国系统架构师大会(SACC2018)】现场演讲内容整理而成。1、引言瓜子业务重线下,用户网上看车、预约到店、成交等许多环节都发生在线下。瓜子IM智能客服系统的目的是要把这些线下的活动搬到线上,对线下行为进行追溯,积累相关数据。系统连接用户、客服、电销、销售、AI机器人、业务后台等多个角色及应用,覆盖网上咨询、浏览、预约看车、到店体验、后服、投诉等众多环节,各个角...  阅读全文

posted @ 2019-10-25 15:29 Jack Jiang 阅读(38) | 评论 (0)编辑 收藏

     摘要: 1、引言 说道“心跳”这个词大家都不陌生,当然不是指男女之间的心跳,而是和长连接相关的。顾名思义就是证明是否还活着的依据。 什么场景下需要心跳呢?目前我们接触到的大多是一些基于长连接的应用需要心跳来“保活”。 由于在长连接的场景下,客户端和服务端并不是一直处于通信状态,如果双方长期没有沟通则双方都不清楚对方目前的状态,所以需要发送一段很小的...  阅读全文

posted @ 2019-10-22 10:48 Jack Jiang 阅读(443) | 评论 (0)编辑 收藏

     摘要: 一、引言移动互联网技术改变了旅游的世界,这个领域过去沉重的信息分销成本被大大降低。用户与服务供应商之间、用户与用户之间的沟通路径逐渐打通,沟通的场景也在不断扩展。这促使所有的移动应用开发者都要从用户视角出发,更好地满足用户需求。论坛时代的马蜂窝,用户之间的沟通形式比较单一,主要为单纯的回帖回复等。为了以较小的成本快速满足用户需求,当时采用的是非实时性消息的方案来实现用户之间的消息传递。随着行业和公...  阅读全文

posted @ 2019-10-17 23:14 Jack Jiang 阅读(51) | 评论 (0)编辑 收藏

     摘要: 1、引言老读者应该还记得我在去年国庆节前分享过一篇《技术干货:从零开始,教你设计一个百万级的消息推送系统》,虽然我在文中有贴一些伪代码,依然有些朋友希望能直接分享一些可以运行的源码。好吧,质疑我穷我无话可说(因为是真穷。。),怀疑我撸码的能力那是绝对不行,所以这次准备拉起键盘大干一场——徒手撸套分布式IM出来!^_^!本文记录了我开发的一款面向IM学习者的 IM系统R...  阅读全文

posted @ 2019-10-14 22:49 Jack Jiang 阅读(402) | 评论 (0)编辑 收藏

     摘要: 本文为开源实验性工程:“github.com/GuoZhaoran/spikeSystem”的配套文章,原作者:“绘你一世倾城”,现为:猎豹移动php开发工程师,感谢原作者的技术分享。1、引言Go语言的出现,让开发高性能、高稳定性服务端系统变的容易,与高贵冷艳的Erlang语言不同的是,Go语言简单易学,在高性能服务端架构中的应用越来越广泛。对于即时...  阅读全文

posted @ 2019-10-12 14:46 Jack Jiang 阅读(142) | 评论 (0)编辑 收藏

     摘要: 0、引言站长提示:本文适合IM新手阅读,但最好有一定的网络编程经验,必竟实践性的代码上手就是网络编程。如果你对网络编程,以及IM的一些理论知识知之甚少,请务必首先阅读:《新手入门一篇就够:从零开发移动端IM》,该文为IM小白分类整理了详尽的理论资料,请按需补充相关知识。配套源码:本文写的比较浅显但不太易懂,建议结合代码一起来读,文章配套的完整源码 请从本文文末 “11、完整源...  阅读全文

posted @ 2019-10-09 14:49 Jack Jiang 阅读(782) | 评论 (0)编辑 收藏

     摘要: 原文来源:51CTO技术栈公众号,本文原题:NoSQL还是SQL?这一篇讲清楚,收录时有修订和改动。1、引言随着互联网大数据时代的到来,越来越多的网站、应用系统都需要支撑大量甚至海量数据存储,同时还伴有高并发、高可用、高可扩展等特性要求。很多时候,传统的关系型数据库在应付这些已经显得力不从心,并暴露了许多难以克服的问题。由此,各种各样的 NoSQL(Not Only SQL)数据库作为传统关系型数...  阅读全文

posted @ 2019-09-26 14:16 Jack Jiang 阅读(66) | 评论 (0)编辑 收藏

     摘要: 本文来自美团技术团队“照东”的分享,原题《Leaf——美团点评分布式ID生成系统》,收录时有勘误、修订并重新排版,感谢原作者的分享。1、引言鉴于IM系统中聊天消息ID生成算法和生成策略的重要性(因为某种意义上来说:聊天消息ID的优劣决定了IM应用层某些功能实现的难易度),所以即时通讯网近期正在着重整理有关IM中的聊天消息ID算法方面的文章,包括微信团...  阅读全文

posted @ 2019-09-23 16:25 Jack Jiang 阅读(61) | 评论 (0)编辑 收藏

     摘要: 本文来自融云技术团队原创分享,原文发布于“融云全球互联网通信云”公众号,原题《如何实现分布式场景下唯一 ID 生成?》,即时通讯网收录时有部分改动。1、引言对于IM应用来说,消息ID(或称序列号)是个看似不起眼,但非常重要的东西之一。消息ID的使用贯穿了IM技术逻辑的方方面面,比如:1)聊天消息的顺序保证;2)聊天消息QoS送达保证机制时的去重;3)特定聊天消息的精确查找和...  阅读全文

posted @ 2019-09-19 17:40 Jack Jiang 阅读(55) | 评论 (0)编辑 收藏

     摘要: 本文来自融云技术团队原创分享,原文发布于“ 融云全球互联网通信云”公众号,原题《IM 即时通讯之链路保活》,即时通讯网收录时有部分改动。1、引言众所周知,IM 即时通讯是一项对即时性要求非常高的技术,而保障消息即时到达的首要条件就是链路存活。那么在复杂的网络环境和国内安卓手机被深度定制化的条件下,如何保障链路存活呢?本文详解了融云安卓端IM产品在基于 TCP 协议实现链路保...  阅读全文

posted @ 2019-09-17 11:15 Jack Jiang 阅读(41) | 评论 (0)编辑 收藏

     摘要: 本文原作者:selfboot,博客地址:selfboot.cn,Github地址:github.com/selfboot,感谢原作者的技术分享。1、引言对于 DNS(Domain Name System) 大家肯定不陌生,不就是用来将一个网站的域名转换为对应的IP吗。当我们发现可以上QQ但不能浏览网页时,我们会想到可能是域名服务器挂掉了;当我们用别人提供的hosts文件浏览到一...  阅读全文

posted @ 2019-09-09 15:41 Jack Jiang 阅读(49) | 评论 (0)编辑 收藏

本文来自知乎官方技术团队的“知乎技术专栏”,感谢原作者faceair的无私分享。

1、引言

实时的响应总是让人兴奋的,就如你在微信里看到对方正在输入,如你在王者峡谷里一呼百应,如你们在直播弹幕里不约而同的 666,它们的背后都离不开长连接技术的加持。

每个互联网公司里几乎都有一套长连接系统,它们被应用在消息提醒、即时通讯、推送、直播弹幕、游戏、共享定位、股票行情等等场景。而当公司发展到一定规模,业务场景变得更复杂后,更有可能是多个业务都需要同时使用长连接系统。

业务间分开设计长连接会导致研发和维护成本陡增、浪费基础设施、增加客户端耗电、无法复用已有经验等等问题。共享长连接系统又需要协调好不同系统间的认证、鉴权、数据隔离、协议拓展、消息送达保证等等需求,迭代过程中协议需要向前兼容,同时因为不同业务的长连接汇聚到一个系统导致容量管理的难度也会增大。

经过了一年多的开发和演进,经过我们服务面向内和外的数个 App、接入十几个需求和形态各异的长连接业务、数百万设备同时在线、突发大规模消息发送等等场景的锤炼,我们提炼出一个长连接系统网关的通用解决方案,解决了多业务共用长连接时遇到的种种问题。

知乎长连接网关致力于业务数据解耦、消息高效分发、解决容量问题,同时提供一定程度的消息可靠性保证。

(本文同步发布于:http://www.52im.net/thread-2737-1-1.html

2、相关文章

3、我们怎么设计通讯协议?

3.1 业务解耦

支撑多业务的长连接网关实际上是同时对接多客户端和多业务后端的,是多对多的关系,他们之间只使用一条长连接通讯。

 

这种多对多的系统在设计时要避免强耦合。业务方逻辑也是会动态调整的,如果将业务的协议和逻辑与网关实现耦合会导致所有的业务都会互相牵连,协议升级和维护都会异常困难。

所以我们尝试使用经典的发布订阅模型来解耦长连接网关跟客户端与业务后端,它们之间只需要约定 Topic 即可自由互相发布订阅消息。传输的消息是纯二进制数据,网关也无需关心业务方的具体协议规范和序列化方式。



3.2 权限控制

我们使用发布订阅解耦了网关与业务方的实现,我们仍然需要控制客户端对 Topic 的发布订阅的权限,避免有意或无意的数据污染或越权访问。

假如讲师正在知乎 Live 的 165218 频道开讲,当客户端进入房间尝试订阅 165218 频道的 Topic 时就需要知乎 Live 的后端判断当前用户是否已经付费。这种情况下的权限实际上是很灵活的,当用户付费以后就能订阅,否则就不能订阅。权限的状态只有知乎 Live 业务后端知晓,网关无法独立作出判断。

所以我们在 ACL 规则中设计了基于回调的鉴权机制,可以配置 Live 相关 Topic 的订阅和发布动作都通过 HTTP 回调给 Live 的后端服务判断。



同时根据我们对内