Jack Jiang

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

2018年12月27日

本文来自网易云信团队的技术分享,原创发表于网易云信公众号,原文链接:mp.weixin.qq.com/s/LT2dASI7QVpcOVxDAsMeVg,收录时有改动。

1、引言

在不了解IM技术的人眼里,群聊是再平常不过的功能而已,万人群聊?应该也不难实现吧?!

确实,从前端功能界面上来看,群聊无非就是个循环向群员发送消息的一对多聊天消息分发模式而已,难在何处?

真实的情况是,群聊是IM系统中的高难度技术点之一。难在哪?难在服务端!从某种角度上说,群聊功能的架构设计和技术实现的品质,可以代表这款IM软件的技术水平。

群聊从后台的技术实现上说,至少有以下难点:

1)如何高效地进行大量群员消息的分发?

2)如何高效地管理群员的在线状态?

3)如何高效地读取群员的在线状态?

4)集群系统中,如何高效地保证群员消息的准确送达?

5)群聊消息该扩散写还是扩散读?

6)如何保证大量群聊消息分发的情况下不影响单聊消息体验?

7)如何应对大群突发事件下的性能负载?

.... ....

目前,市面上主流的IM产品中,微信群是500人上限,QQ群是3000人上限(3000人群是按年付费升级,很贵,不是为一般用户准备的)。一方面,从产品的定义上群成员数量不应过多,另一方面,技术成本也是个不可回避的因素。万人群这种超大规模群的技术难度,更是难已想象。

本文内容是网易云信团队为了响应万人群聊功能需求,在设计实现万人群聊技术方案中总结的技术实践,借此机会分享给各IM开发者同行。

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

学习交流:

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

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

2、概述

随着移动互联网的发展,即时通讯服务被广泛应用到各个行业,客户业务快速发展,传统百人或千人上限的群聊已经无法满足很多业务发展需求,因此网易云信IM推出万人群服务。

万人群场景需要解决以下问题:

1)消息需要按1:9999的比例进行转发投递,按常规消息处理流程将产生大量的子任务,对系统吞吐量的要求极高;

2)在微服务系统架构下,如果不采用一些优化方案,服务以及存储(DB、缓存等)之间的QPS和网络流量将非常高;

3)以群为单位的缓存(如群成员列表)内存存储开销较大(假设一个成员200Byte,万人群约2MB);

4)群成员登录后需要同步群离线消息,智能手机上App前后台切换产生的较多登录同步消息协议,因此需要优化消息同步方案。

为了解决以上问题,万人群技术方案采用了“聚合+分层/组+增量”的设计思路:

3、万人群消息的处理流程

1)按群维护在线群成员信息,主要包含两部分(可以理解为两个缓存集合):

a. 群成员在线信息:即用户在线状态变化(上线、下线)时,更新相应群的在线状态信息(即动态维护群有哪些成员在线);

b. 成员IM长连接信息:即用户新登录时,更新用户的Link信息(即登录所在Link的地址信息,消息转发时根据Link地址路由消息)。

2)IM Server收到群消息后,按群ID将消息路由到“群消息服务”模块;

3)群消息模块检查并预处理消息内容,然后通过“群成员在线状态”服务获取在线成员,完成消息转发的基础工作。为了减少群消息模块和群在线成员服务之间的网络流量,采用了“本地缓存+增量同步”的缓存策略,即本地缓存记录最后更新版本号和时间戳,每次同步群在线成员前先检查缓存版本号是否有变更,若有则按最后更新时间增量同步;

4)通过“群成员在线服务”获取在线群成员的Link链接信息,按Link分组路由消息(分组路由的原因:同一Link上的全部群成员只需要路由一条消息即可)。同样为了减少网络开销,成员Link信息也采用“本地缓存+增量同步”的方案;

5)群消息采用“漫游+历史”的存储方案,漫游的消息存储在分布式缓存中,历史消息异步写入HBase。用户登录后可以通过漫游快速的获取到最新消息,并可以通过拉取历史查看更早的消息。

4、万人群方案本地缓存增量同步策略

抛开群在线状态管理逻辑,群成员在线状态服务可以简单理解为分布式集中缓存。

增量同步技术方案如下:

如上图所示:

1)数据缓存是一个集合,其包含了多个缓存数据项,每一个数据项带有最后更新时间信息;另外缓存还有一个严格递增的版本号;

2)缓存数据变更(新增、修改、删除)后,需要增加版本号;

3)本地线程通过缓存管理读取数据时,管理服务先检查本地版本号和分布式缓存中的版本号是否一致,若不一致则按本地最新时间戳增量同步新数据项,并更新本地的版本号和最后更新时间(为了避免分布式集中缓存中并发写入导致的增量时间戳不可靠问题,增量更新时可以将本地记录的最后更新时间戳向前推移,比如减少20ms);

4)为避免本地多线程并发读取相同数据项导致并发更新本地缓存的问题,可以按缓存数据合并更新请求,即解决并发问题还可以减少网络开销;

5)缓存数据由大量数据项构成,为了避免单个缓存数据太大,可以将数据项中的属性业务场景精简(冷热分离),低频次读写的属性额外缓存。

5、万人群水平扩容方案

万人群采用大量本地缓存的方案解决消息处理性能和网络流量的问题,因此本地存储空间成了方案的瓶颈点。因此我们设计了分组路由的技术方案。

消息按群ID和路由策略定向路由到指定分组(集群)上处理,分组由多个计算节点组成,因此方案上可以做到分组内和分组间的水平扩缩容。

6、作为“云”服务,网易云信是如何实现万人群所需的计算资源的?

由于万人群对计算和存储资源消耗比较高,在实施和运维方案上也有一定的特殊性,为了保证业务的可靠性和稳定性,网易云信是将万人大群的能力,仅提供给专属的云客户(普通公有云客户是无法使用的)。

之所以能从软硬件基础设施上为万人群提供保障,网易云信的IM专有云必须具备以下资源能力:

1)需要专属的独立计算资源:保持计算资源独立,且资源冗余度比公有云高,且需要保证不会受到公有云上其他客户业务的影响;

2)需要专属的独立运维服务:从而根据客户业务场景制定最佳的业务监控、弹性扩容、故障迁移等运维方案。

总之,万人群聊的实现,过硬的技术方案设计和技术实现只是一方面,基础计算设施资源和运维能力也是不可或缺。

所以,从今以后,不要随随便便就喊万人群聊,甚至十万人群聊,这不是想实现就能实现的哦!

附录:更多群聊相关技术文章

快速裂变:见证微信强大后台架构从0到1的演进历程(一)
如何保证IM实时消息的“时序性”与“一致性”?
IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?
IM群聊消息如此复杂,如何保证不丢不重?
微信后台团队:微信后台异步消息队列的优化升级实践分享
移动端IM中大规模群消息的推送如何保证效率、实时性?
现代IM系统中聊天消息的同步和存储方案探讨
关于IM即时通讯群聊消息的乱序问题讨论
IM群聊消息的已读回执功能该怎么实现?
IM群聊消息究竟是存1份(即扩散读)还是存多份(即扩散写)?
一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践
[技术脑洞] 如果把14亿中国人拉到一个微信群里技术上能实现吗?
IM群聊机制,除了循环去发消息还有什么方式?如何优化?
网易云信技术分享:IM中的万人群聊技术方案实践总结
>> 更多同类文章 ……

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

posted @ 2019-08-14 10:07 Jack Jiang 阅读(9) | 评论 (0)编辑 收藏

     摘要: 本文原文由作者“张小方”原创发布于“高性能服务器开发”微信公众号,原题《心跳包机制设计详解》,即时通讯网收录时有改动。1、引言一般来说,没有真正动手做过网络通信应用的开发者,很难想象即时通讯应用中的心跳机制的作用。但不可否认,作为即时通讯应用,心跳机制是其网络通信技术底层中非常重要的一环,有没有心跳机制、心跳机制的算法实现好坏,都将直接影响即时通讯应...  阅读全文

posted @ 2019-08-08 12:01 Jack Jiang 阅读(24) | 评论 (0)编辑 收藏

     摘要: 本文由原作者松若章原创发布,作者主页:zhihu.com/people/hrsonion/posts,感谢原作者的无私分享。1、引言一道经典的面试题是:从 URL 在浏览器被被输入到页面展现的过程中发生了什么?大多数回答都是说请求响应之后 DOM 怎么被构建,被绘制出来。但是你有没有想过,收到的 HTML 如果包含几十个图片标签,这些图片是以什么方式、什么顺序、建立了多少连接、使用什么协议被下载下...  阅读全文

posted @ 2019-08-02 09:55 Jack Jiang 阅读(36) | 评论 (0)编辑 收藏

     摘要: 本文由百度技术团队“蔡锐”原创发表于“百度App技术”公众号,原题为《百度App网络深度优化系列《三》弱网优化》,感谢原作者的无私分享。一、前言网络优化解决的核心问题有三个,第一是安全问题,我们在《百度APP移动端网络深度优化实践分享(一):DNS优化篇》进行了详细的讲解。第二是速度问题,我们在《百度APP移动端网络深度优化实践分享(二):网络连接优...  阅读全文

posted @ 2019-07-29 10:29 Jack Jiang 阅读(23) | 评论 (0)编辑 收藏

     摘要: 本文引用自马蜂窝公众号,由马蜂窝技术团队原创分享。一、引言今天,越来越多的用户被马蜂窝持续积累的笔记、攻略、嗡嗡等优质的分享内容所吸引,在这里激发了去旅行的热情,同时也拉动了马蜂窝交易的增长。在帮助用户做出旅行决策、完成交易的过程中,IM 系统起到了重要的作用。IM 系统为用户与商家建立了直接沟通的渠道,帮助用户解答购买旅行产品中的问题,既促成了订单交易,也帮用户打消了疑虑,促成用户旅行愿望的实现...  阅读全文

posted @ 2019-07-24 21:44 Jack Jiang 阅读(22) | 评论 (0)编辑 收藏

     摘要: 本文由作者FreddyChen原创分享,为了更好的体现文章价值,引用时有少许改动,感谢原作者。1、写在前面一直想写一篇关于im即时通讯分享的文章,无奈工作太忙,很难抽出时间。今天终于从公司离职了,打算好好休息几天再重新找工作,趁时间空闲,决定静下心来写一篇文章,毕竟从前辈那里学到了很多东西。工作了五年半,这三四年来一直在做社交相关的项目,有直播、即时通讯、短视频分享、社区论坛等产品,深知即时通讯技...  阅读全文

posted @ 2019-07-22 12:48 Jack Jiang 阅读(50) | 评论 (0)编辑 收藏

     摘要: 1、引言本文以设计淘宝网的后台架构为例,介绍从一百个并发到千万级并发情况下服务端的架构的14次演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知。文章最后汇总了一些架构设计的原则。(本文同步发布于:http://www.52im.net/thread-2665-1-1.html)2、关于作者huashiou:广东工业大学计算机科学与技术硕士毕业,大数据开发工程师。...  阅读全文

posted @ 2019-07-17 23:57 Jack Jiang 阅读(135) | 评论 (0)编辑 收藏

     摘要: 本文由DCloud 公司创始人王安原创发布于CSDN,原题《小程序技术演进史》,即时通讯网收录时有改动,感谢原作者。1、引言微信的成功,并非特定于某个具体的功能,微信的成功实际上是一大批创新技术和体验的成功合集,这也是它为何如此难此被超越的根本原因。作为微信这个超级社交应用中最为亮眼的技术之一——微信小程序,俨然已成历移动端小程序的代名词,很多人一提起“小程序&...  阅读全文

posted @ 2019-07-04 12:02 Jack Jiang 阅读(22) | 评论 (0)编辑 收藏

     摘要: 本文原题“《NIO 入门》,作者为“Gregory M. Travis”,他是《JDK 1.4 Tutorial》等书籍的作者。1、引言Java NIO是Java 1.4版加入的新特性,虽然Java技术日新月异,但历经10年,NIO依然为Java技术领域里最为重要的基础技术栈,而且依据现实的应用趋势,在可以预见的未来,它仍将继续在Java技术领域占据重要位置。网...  阅读全文

posted @ 2019-06-29 22:17 Jack Jiang 阅读(522) | 评论 (0)编辑 收藏

1、引言

很多初涉网络编程的程序员,在研究Java NIO(即异步IO)和经典IO(也就是常说的阻塞式IO)的API时,很快就会发现一个问题:我什么时候应该使用经典IO,什么时候应该使用NIO?

在本文中,将尝试用简明扼要的文字,阐明Java NIO和经典IO之间的差异、典型用例,以及这些差异如何影响我们的网络编程或数据传输代码的设计和实现的。

本文没有复杂理论,也没有像网上基它文章一样千篇一律的复制粘贴,有的只是接地气的通俗易懂,希望能给你带来帮助。

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

2、相关文章

3、Java NIO和IO的主要区别

下表总结了Java NIO和IO之间的主要区别。我将在表格后面的部分中详细介绍每个区别。

3.1 Stream Oriented vs. Buffer Oriented

Java NIO和IO之间的第一个重要区别是IO是面向流的,其中NIO是面向缓冲区的。那么,这意味着什么?

面向流的Java IO意味着您可以从流中一次读取一个或多个字节。你对读取的字节做什么取决于你。它们不会缓存在任何地方。此外,您无法在流中的数据中前后移动。如果需要在从流中读取的数据中前后移动,则需要先将其缓存在缓冲区中。

Java NIO的面向缓冲区的方法略有不同。数据被读入缓冲区,稍后处理该缓冲区。你可以根据需要在缓冲区中前后移动。这使你在处理过程中具有更大的灵活性。但是,你还需要检查缓冲区是否包含完整处理所需的所有数据。并且,你需要确保在将更多数据读入缓冲区时,不要覆盖尚未处理的缓冲区中的数据。

3.2 Blocking vs. Non-blocking IO

Java IO的各种流都是blocking的。这意味着,当线程调用read()或write()时,该线程将被阻塞,直到有一些数据要读取,或者数据被完全写入,在此期间,该线程无法执行任何其他操作。

Java NIO的非阻塞模式允许线程请求从通道读取数据,并且只获取当前可用的内容,或者根本没有数据,如果当前没有数据可用。线程可以继续使用其他内容,而不是在数据可供读取之前保持阻塞状态。

非阻塞写入也是如此,线程可以请求将某些数据写入通道,但不要等待它完全写入。然后线程可以继续并在同一时间做其他事情。

线程在IO调用中没有阻塞时花费空闲时间,通常在此期间在其他通道上执行IO。也就是说,单个线程现在可以管理多个输入和输出通道。

4、Selectors

Java NIO的选择器允许单个线程监视多个输入通道。你可以使用选择器注册多个通道,然后使用单个线程“选择”具有可用于处理的输入的通道,或者选择准备写入的通道。这种选择器机制使单个线程可以轻松管理多个通道。

5、NIO和经典IO如何影响应用程序的设计?

选择NIO或IO作为IO工具包可能会影响应用程序设计的以下方面:

1)API调用NIO或IO类;

2)处理数据;

3)用于处理数据的线程数。

5.1 API调用

当然,使用NIO时的API调用看起来与使用IO时不同。这并不奇怪。而不是仅仅从例如InputStream读取字节的数据字节,必须首先将数据读入缓冲区,然后从那里进行处理。

5.2 数据处理

使用纯NIO设计与IO设计时,数据处理也会受到影响。

在IO设计中,您从InputStream或Reader中读取字节的数据字节。想象一下,您正在处理基于行的文本数据流。

例如:

Name: Anna

Age: 25

Email: [url=mailto:anna@mailserver.com]anna@mailserver.com[/url]

Phone: 1234567890

这个文本行流可以像这样处理:

InputStream input = ... ; // get the InputStream from the client socket


BufferedReader reader = newBufferedReader(newInputStreamReader(input));


String nameLine   = reader.readLine();

String ageLine    = reader.readLine();

String emailLine  = reader.readLine();

String phoneLine  = reader.readLine();

注意处理状态是如何,由程序执行的程度决定的。换句话说,一旦第一个reader.readLine()方法返回,您就确定已经读取了整行文本。readLine()会阻塞直到读取整行,这就是原因。您还知道此行包含名称。同样,当第二个readLine()调用返回时,您知道此行包含年龄等。

正如您所看到的,只有当有新数据要读取时,程序才会进行,并且对于每个步骤,您都知道该数据是什么。一旦执行的线程已经超过读取代码中的某个数据片段,该线程就不会在数据中向后移动(通常不会)。

此图中还说明了此原则:

▲ Java IO:从阻塞流中读取数据

NIO的实现看起来会有所不同,这是一个简化的例子:

ByteBuffer buffer = ByteBuffer.allocate(48);

intbytesRead = inChannel.read(buffer);

注意第二行从通道读取字节到ByteBuffer。当该方法调用返回时,您不知道所需的所有数据是否都在缓冲区内。你只知道缓冲区包含一些字节,这使得处理更加困难。

想象一下,在第一次读取(缓冲)调用之后,是否所有读入缓冲区的内容都是半行。例如,“姓名:An”。你能处理这些数据吗?并不是的。在完成任何数据的处理之前,您需要等待至少一整行数据进入缓冲区。

那么你怎么知道缓冲区是否包含足够的数据来处理它?好吧,你没有。找出的唯一方法是查看缓冲区中的数据。结果是,在您知道所有数据是否存在之前,您可能需要多次检查缓冲区中的数据。这既低效又可能在程序设计方面变得混乱。

例如:

ByteBuffer buffer = ByteBuffer.allocate(48);

intbytesRead = inChannel.read(buffer);

while(! bufferFull(bytesRead) ) {

    bytesRead = inChannel.read(buffer);

}

bufferFull()方法必须跟踪读入缓冲区的数据量,并返回true或false,具体取决于缓冲区是否已满。换句话说,如果缓冲区已准备好进行处理,则认为它已满。

bufferFull()方法扫描缓冲区,但必须使缓冲区保持与调用bufferFull()方法之前相同的状态。如果不是,则可能无法在正确的位置读入读入缓冲区的下一个数据。这不是不可能的,但这是另一个需要注意的问题。

如果缓冲区已满,则可以对其进行处理。如果它不满,您可能能够部分处理那里的任何数据,如果这在您的特定情况下是有意义的。在许多情况下,它没有。

这个图中说明了is-data-in-buffer-ready循环:

▲ Java NIO:从通道读取数据,直到所有需要的数据都在缓冲区中

6、什么时候该用NIO?什么时候该用经典IO?

NIO允许您仅使用一个(或几个)线程来管理多个通道(网络连接或文件),但成本是解析数据可能比从阻塞流中读取数据时更复杂。

如果您需要同时管理数千个打开的连接,每个只发送一些数据,例如聊天服务器,在NIO中实现服务器可能是一个优势。同样,如果您需要与其他计算机保持大量开放连接,例如在P2P网络中,使用单个线程来管理所有出站连接可能是一个优势。

此图中说明了这一个线程,多个连接设计:

▲ Java NIO:管理多个连接的单个线程

如果您拥有较少带宽的连接,一次发送大量数据,那么可能最经典的IO服务器实现可能是最合适的。

此图说明了经典的IO服务器设计:

▲ Java IO:经典的IO服务器设计 - 由一个线程处理的一个连接

7、更简化的理解

以众所周之的数据读取过程为例,我们来一个更简化的理解。

对于数据读取,就读取速度来说:CPU > 内存 > 硬盘。

I- 就是从硬盘到内存

O- 就是从内存到硬盘

第一种方式:从硬盘读取数据,然后程序一直等,数据读完后,继续你的操作。这种方式是最简单的,叫阻塞IO(也就是经典IO)。

第二种方式:从硬盘读取数据,然后程序继续向下执行,等数据读取完后,通知当前程序读取完成(对硬件来说叫中断,对程序来说叫回调),然后此程序可以立即处理读取的数据,也可以执行完当前操作后再对读取完的数据进行操作。

8、总而言之

还是以数据读取为例,操作系统是按块Block(块)从硬盘拿数据,就如同一个大脸盆,一下子就放入了一盆水。但是,当 Java 使用的时候,旧的 IO(经典IO)确实基于 流 Stream的,也就是虽然操作系统给我了一脸盆水,但是我得用吸管慢慢喝。

由于经典IO的重重落后理念,于是,NIO 横空出世。。。

附录:更多NIO异步网络编程资料

Java新一代网络编程模型AIO原理及Linux系统AIO介绍
有关“为何选择Netty”的11个疑问及解答
开源NIO框架八卦——到底是先有MINA还是先有Netty?
选Netty还是Mina:深入研究与对比(一)
选Netty还是Mina:深入研究与对比(二)
NIO框架入门(一):服务端基于Netty4的UDP双向通信Demo演示
NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示
NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战
NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战
Netty 4.x学习(一):ByteBuf详解
Netty 4.x学习(二):Channel和Pipeline详解
Netty 4.x学习(三):线程模型详解
Apache Mina框架高级篇(一):IoFilter详解
Apache Mina框架高级篇(二):IoHandler详解
MINA2 线程原理总结(含简单测试实例)
Apache MINA2.0 开发指南(中文版)[附件下载]
MINA、Netty的源代码(在线阅读版)已整理发布
解决MINA数据传输中TCP的粘包、缺包问题(有源码)
解决Mina中多个同类型Filter实例共存的问题
实践总结:Netty3.x升级Netty4.x遇到的那些坑(线程篇)
实践总结:Netty3.x VS Netty4.x的线程模型
详解Netty的安全性:原理介绍、代码演示(上篇)
详解Netty的安全性:原理介绍、代码演示(下篇)
详解Netty的优雅退出机制和原理
NIO框架详解:Netty的高性能之道
Twitter:如何使用Netty 4来减少JVM的GC开销(译文)
绝对干货:基于Netty实现海量接入的推送服务技术要点
Netty干货分享:京东京麦的生产级TCP网关技术实践总结
新手入门:目前为止最透彻的的Netty高性能原理和框架架构解析
写给初学者:Java高性能NIO框架Netty的学习方法和进阶策略
少啰嗦!一分钟带你读懂Java的NIO和经典IO的区别
>> 更多同类文章 ……

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

posted @ 2019-06-25 16:32 Jack Jiang 阅读(359) | 评论 (0)编辑 收藏

     摘要: 1、引言对于即时通讯网来说,所有的技术文章和资料都在围绕即时通讯这个技术方向进行整理和分享,这一次也不例外。对于即时通讯系统(包括IM、消息推送系统等)来说,MQ消息中件间是非常常见的基础软件,但市面上种类众多、各有所长的MQ消息中件间产品,该怎么去选择?这是个问题!对于很多经验不足的开发者来说,一个公司内部用的IM聊天系统,总用户量也不过百十来人,动辄就是Kafka、MongoDB,美其名曰为了...  阅读全文

posted @ 2019-06-21 15:01 Jack Jiang 阅读(46) | 评论 (0)编辑 收藏

     摘要: 本文引用了作者“ ConardLi”的《用JS开发跨平台桌面应用,从原理到实践》一文部分内容,原文链接:segmentfault.com/a/1190000019426512,感谢原作者的无私分享。1、引言现在开发IM应用动不动就要求多端——即Android端、iOS端、PC端、Web端等,Android端和iOS端作为两种不同的移动端技术,单独开发...  阅读全文

posted @ 2019-06-14 11:11 Jack Jiang 阅读(35) | 评论 (0)编辑 收藏

     摘要: 本文引用了“蔷薇Nina”的“Nginx 相关介绍(Nginx是什么?能干嘛?)”一文部分内容,感谢作者的无私分享。1、引言Nginx(及其衍生产品)是目前被大量使用的服务端反向代理和负载均衡方案,从某种意义上来讲,Nginx几乎是低成本、高负载Web服务端代名词。如此深入人心的Nginx,很多人也想当然的认为,在IM或消息推送等场景下是否也能使用N...  阅读全文

posted @ 2019-06-07 21:33 Jack Jiang 阅读(42) | 评论 (0)编辑 收藏

     摘要: 1、引言相信看到这个标题,很多人的第一反应就是:对数据库进行分库分表啊!但是实际上,数据库层面的分库分表到底是用来干什么的,其不同的作用如何应对不同的场景,我觉得很多同学可能都没搞清楚。本篇文章我们一起来学习一下,对于一个支撑日活百万用户的高并发系统,数据库架构应该如何设计呢?本文的讨论和分享,将用一个创业公司的发展作为背景引入,方便大家理解。(本文同步发布于:http://www.52im.ne...  阅读全文

posted @ 2019-05-15 14:39 Jack Jiang 阅读(73) | 评论 (0)编辑 收藏

     摘要: 【来源申明】本文原文来自:微信公众号“鲜枣课堂”,官方网站:xzclass.com,原题为:《中国通信的百年沉浮》,本文引用时已征得原作者同意。为了更好的内容呈现,即时通讯网在收录时内容有稍许调整,转载时请注明原文来源信息,请尊重原作者的劳动。1、系列文章引言1.1 适合谁来阅读?本系列文章尽量使用最浅显易懂的文字、图片来组织内容,力求通信技术零基础的人群也能看懂。但个人建...  阅读全文

posted @ 2019-05-05 15:40 Jack Jiang 阅读(40) | 评论 (0)编辑 收藏

     摘要: 1、引言关于“负载均衡”的解释,百度词条里:负载均衡,英文叫Load Balance,意思就是将请求或者数据分摊到多个操作单元上进行执行,共同完成工作任务。负载均衡(Load Balance)建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。负载均衡有两方面的含义:1)首先,大量的并...  阅读全文

posted @ 2019-04-29 14:39 Jack Jiang 阅读(56) | 评论 (0)编辑 收藏

     摘要: 一、引言WebSocket是一种比较新的协议,它是伴随着html5规范而生的,虽然还比较年轻,但大多主流浏览器都已经支持。它使用方面、应用广泛,已经渗透到前后端开发的各种场景中。对http一问一答中二式流程(就是从所周之的“长轮询”技要啦)的不满,催生了支持双向通信的WebSocket诞生。WebSocket是个不太干净协议。本文将从8个常见的疑问入手,为还不了解WebSo...  阅读全文

posted @ 2019-04-25 14:27 Jack Jiang 阅读(69) | 评论 (0)编辑 收藏

     摘要: 本文由百度技术团队“蔡锐”原创发表于“百度App技术”公众号,原题为《百度App网络深度优化系列《二》连接优化》,感谢原作者的无私分享。一、前言在《百度APP移动端网络深度优化实践分享(一):DNS优化篇》里大家了解到网络优化一般会首选优化DNS,而接下来的HTTP协议成为优化的重点,一般优化者会选择协议切换,合并请求,精简数据包大小等手段来对HTT...  阅读全文

posted @ 2019-04-24 16:25 Jack Jiang 阅读(47) | 评论 (0)编辑 收藏

     摘要: 本文由百度技术团队“蔡锐”原创发表于“百度App技术”公众号,原题为《百度App网络深度优化系列《一》DNS优化》,感谢原作者的无私分享。一、前言网络优化是客户端几大技术方向中公认的一个深度领域,所以百度App给大家带来网络深度优化系列文章。本系列文章目录如下:《百度APP移动端网络深度优化实践分享(一):DNS优化篇》(* 本文)《百度APP移动端...  阅读全文

posted @ 2019-04-22 13:51 Jack Jiang 阅读(45) | 评论 (0)编辑 收藏

     摘要: 1、引言我,Scott,一家创业公司的 CTO。从业6年却很少写文章,近一年来接触了几十个刚毕业的前端新人,也面试了100多个前端工程师和Nodejs工程师,对于前端发展的这个职业算是有些感触吧,打算陆续写一些从业经验也好,技术分享也好,对自己前6年的经历做一些文字上的沉淀。此篇文章谨献给工作0 ~ 3年的前端工程师,内容都是我的亲身经历,不精彩但接地气。(本文同步发布于:http://www.5...  阅读全文

posted @ 2019-04-15 11:45 Jack Jiang 阅读(78) | 评论 (0)编辑 收藏

     摘要: 1、引言在文章《理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程》中,我们学会了用wireshark来分析TCP的“三次握手,四次挥手”,非常好用。这就是传说中的锤子,拿着 锤子,看什么都像 钉子!在这本文中,我对将准 HTTP这颗钉子,狠狠地砸下去。。。为了对网络数据包的“流转”有更加深刻的理解,我在docker(远程)上部署...  阅读全文

posted @ 2019-04-13 11:27 Jack Jiang 阅读(47) | 评论 (0)编辑 收藏

     摘要: 1、引言HTTPS(全称: Hypertext Transfer Protocol Secure,超文本传输安全协议),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。本文,就来深入介绍下其原理。补充:限于篇幅,本文对于https的相关技术要点的介绍尽量简明扼要,如想要详细了解HTTPS的方方面面,请阅读《即时通讯安全篇(七):如果这样来理解HTTPS,一篇就够了》。(本文同步发布于:ht...  阅读全文

posted @ 2019-04-08 11:48 Jack Jiang 阅读(44) | 评论 (0)编辑 收藏

     摘要: 1、系列文章引言1.1 适合谁来阅读?本系列文章尽量使用最浅显易懂的文字、图片来组织内容,力求通信技术零基础的人群也能看懂。但个人建议,至少稍微了解过网络通信方面的知识后再看,会更有收获。如果您大学学习过《计算机网络》这门课,那么一定不要错过本系列文章。特别推荐即时通讯开发者来阅读,因为针对移动弱网的问题,确实可以找到很多有价值的答案。友情提示:本系列文章可能涉及以下通信技术范畴,如您有兴趣,也可...  阅读全文

posted @ 2019-04-02 13:06 Jack Jiang 阅读(46) | 评论 (0)编辑 收藏

1、引言

沟通是人类的最基本需求,复杂多变的沟通内容、沟通方式,正是人类文明之所以如此璀璨的关键所在。

在自然界中,要完成一件事情的沟通,我们可以直接通过声音传递给对方,这是再平常不过的事了(靠“吼”就能解决)。

随着计算机的普及,互联网改变了我们的生活,甚至改变了我们的沟通方式。现在,“有什么事微信或QQ上找我”已经是很多的人口头禅了。

那么,作为不懂技术的普通人,有没有想过,你每次使用QQ或微这种IM聊天应用时,你所发送的消息,是如何被计算机送达给对方的?(这显然不可能靠“吼”解决 ^_^)

本文将从非技术人员的视角,为你讲解一下IM聊天应用中的聊天消息是怎么发送的。

学习交流:

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

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

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

2、关于作者

巩鹏军:专注移动开发十多年,热爱即时通讯技术。个人微信公众号:“巩鹏军”。

3、阅读对象

本文适合非技术背景的读者阅读,如您喜欢本文,则下列文章您也可能喜欢:

技术往事:微信估值已超5千亿,雷军曾有机会收编张小龙及其Foxmail

QQ和微信凶猛成长的背后:腾讯网络基础架构的这些年

闲话即时通讯:腾讯的成长史本质就是一部QQ成长史

腾讯开发微信花了多少钱?技术难度真这么大?难在哪?

技术往事:史上最全QQ图标变迁过程,追寻IM巨人的演进历史

开发往事:深度讲述2010到2015,微信一路风雨的背后

开发往事:记录微信3.0版背后的故事(距微信1.0发布9个月时)

微信七年回顾:历经多少质疑和差评,才配拥有今天的强大

前创始团队成员分享:盘点微信的前世今生——微信成功的必然和偶然

QQ的成功,远没有你想象的那么顺利和轻松

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

QQ和微信止步不前,意味着即时通讯社交应用创业的第2春已来?

那些年微信开发过的鸡肋功能,及其带给我们的思考

为什么说即时通讯社交APP创业就是一个坑?

即时通讯创业必读:解密微信的产品定位、创新思维、设计法则等

老罗最新发布了“子弹短信”这款IM,主打熟人社交能否对标微信?

盘点和反思在微信的阴影下艰难求生的移动端IM应用

QQ现状深度剖析:你还认为QQ已经被微信打败了吗?

那些年微信开发过的鸡肋功能,及其带给我们的思考

渐行渐远的人人网:十年亲历者的互联网社交产品复盘和反思

中国互联网社交二十年:全民见证的互联网创业演义

IM热门功能讨论:为什么微信里没有消息“已读”功能?

读懂微信:从1.0到7.0版本,一个主流IM社交工具的进化史

王欣回应微信封禁,解释为何取名“马桶MT”

同为IM社交产品中的王者,QQ与微信到底有什么区别

还原真实的腾讯:从最不被看好,到即时通讯巨头的草根创业史

如果您是专业技术人员,则跟本文相关的专业技术知识等,可以以下文章中找到:

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

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

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

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

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

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

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

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

好了,费话不多说,我们开始正文部分。。。

4、在微信里,我们发送一条聊天消息是如此简单

李雷在手机上打开微信(IM客户端),在聊天输框中输入“Hello!”,点击发送。几乎是瞬间,韩梅梅手机上的微信(IM客户端)就会显示李雷的头像后面跟着“Hello!”。

整个过程如下图所示:

▲ 一条聊天消息发送的全过程

从上面的图示可以看到,整个过程涉及三大部分:

1)李雷手机上的IM客户端(微信);

2)IM服务端;

3)韩梅梅手机上的IM客户端(微信)。

下面,我们逐一介绍每个部分的具体工作原理。

5、消息发送者:发送端是怎么工作的?

先看看发送端,李雷手机上的IM客户端中发生了什么?

从上图可以看出,发送一条信息经过三个步骤:

1)消息编辑:

李雷操作键盘输入要发送的文字,点击“发送”按钮。这一切都发生在IM客户端的界面模块中。类似用笔在信纸上写信,键盘就是笔,聊天框就是信纸;

2)消息入库:

IM客户端中的数据模块会先将聊天内容“Hello!”加上谁发给谁等信息,按标准格式打包为一条IM消息,并存入本地数据库。这类似信纸装入信封,填写地址,投入邮箱的过程。一条IM消息就是一封信,本地数据库就是李雷家的邮箱;

3)消息发送:

IM客户端中的网络模块通过长连接将IM消息发给IM服务端。这类似邮递员将信件汇总发往邮政局。网络模块就是邮递员,IM服务端就是邮政局。(长连接是IM客户端跟IM服务端一直保持的网络链路)。

6、消息“中转站”:IM服务端是怎么工作的?

担负“邮政局”职责的IM服务端是IM世界中全知全能的神,它认识所有人,经手所有消息,跟每个人都一直保持联系(长连接)。

每条消息在IM服务端中都要至少经过以下处理:

1)消息接收:

长连接服务从和李雷的长连接接收到“Hello!”的IM消息。IM服务端跟所有登录的IM客户端保持长连接(一条一直活跃的网络链路,每个客户端一条),长连接上定时会有心跳消息来监测客户端的在线离线状态,心跳消息就像邮递员每天都会在邮政局和邮箱之间巡回一样;

2)消息验证:

用户服务查询IM消息的目标人韩梅梅,以及发送人李雷和目标人韩梅梅是否好友关系,确保韩梅梅是真实存在而非虚构的,并且韩梅梅愿意接收李雷的消息,否则会给李雷退信。(一般IM服务端会将IM消息的副本存入数据库中备份);

3)消息转发:

在长连接服务中找到跟韩梅梅手机上IM客户端保持的长连接,并将消息发送给韩梅梅。

7、消息接收者:接收端又是怎么工作的呢?

下面看看韩梅梅手机上发生了什么?

韩梅梅手机上的IM客户端和李雷(发送者)的是一样的,但处理步骤是不同的:

1)消息接收:

网络模块通过跟IM服务端保持的长连接接收IM消息;

2)消息入库:

网络模块会将IM消息存入本地数据库,即信件投入了韩梅梅家的邮箱。网络模块就是邮递员,本地数据库就是韩梅梅家的邮箱;

3)消息展示:

界面模块获取发送人头像,和消息内容一起显示在聊天界面上。

经过上述过程,韩梅梅在自己手机上就看到了李雷发过来的“Hello!”,因为李雷和韩梅梅都是一直和服务器保持长连接,所以上述过程是瞬间完成的,李雷和韩梅梅感觉就像面对面聊天一样方便。这也是Instant Messaging名字的来历。

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

posted @ 2019-04-01 18:22 Jack Jiang 阅读(35) | 评论 (0)编辑 收藏

     摘要: 【来源申明】本文原文来自:微信公众号“鲜枣课堂”,官方网站:xzclass.com,原题为:《通信交换的百年沧桑(上)》,本文引用时已征得原作者同意。为了更好的内容呈现,即时通讯网在收录时内容有稍许调整,转载时请注明原文来源信息,请尊重原作者的劳动。1、本系列文章目录《IM开发者的零基础通信技术入门(一):通信交换技术的百年发展史(上)》(* 本文)《IM开发者的零基础通信...  阅读全文

posted @ 2019-03-26 12:08 Jack Jiang 阅读(36) | 评论 (0)编辑 收藏

     摘要: 本文来自公众号“玩不好就别玩”原创分享,原文链接:mp.weixin.qq.com/s/x5_OfICU2ijsxwMuVpqojg。文章内容为个人真实经历,虽平凡无奇,但感同身受。1、点评本文来自公众号“玩不好就别玩”原创分享。本次文章内容为个人真实经历,记录了作者个人离职鹅厂前最后一个月工作交接过程中的心理变化历程。内容虽平凡无奇,但同为程序员的...  阅读全文

posted @ 2019-03-01 18:25 Jack Jiang 阅读(52) | 评论 (0)编辑 收藏

     摘要: 本文为原创分享,转载请注明出处。1、引言即时通讯IM应用中的聊天消息时间显示是个再常见不过的需求,现在都讲究用户体验,所以时间显示再也不能像传统软件一样简单粗地暴显示成“年/月/日 时:分:秒”这样。所以,市面上几乎所有的IM都会对聊天消息的时间显示格化做人性化处理,从而提升用户体验(使用感受会明显友好)。这两天正在继续开发RainbowChat-Web产品,所以正需要这样...  阅读全文

posted @ 2019-02-23 16:54 Jack Jiang 阅读(75) | 评论 (0)编辑 收藏

     摘要: 本文原文内容引用自高可用架构公众号,内容有整理和修订。1、引言大家对下面这个排队的场景应该非常熟悉,这个是小米手机抢购的用户排队交互图,大家看到这些排队的兔子时,说明也有很多用户在同一时间向小米抢购系统提交了购买请求。▲ 小米手机抢购排队中...小米抢购系统后端服务面临巨大的压力,下图可以反映小米抢购系统面临的瞬间峰值压力。这张图截取自某年米粉节大秒服务后端其中一组LB(负载均衡层)的...  阅读全文

posted @ 2019-01-24 20:27 Jack Jiang 阅读(92) | 评论 (0)编辑 收藏

     摘要: 本文来自网易云音乐音视频实验室负责人刘华平在LiveVideoStackCon 2017大会上的分享,并由LiveVideoStack根据演讲内容整理而成(本次演讲PPT文稿,请从文末附件下载)。1、引言大家好,我是刘华平,从毕业到现在我一直在从事音视频领域相关工作,也有一些自己的创业项目,曾为早期Google Android SDK多媒体架构的构建作出贡献。就音频而言,无论是算法多样性,Code...  阅读全文

posted @ 2019-01-18 22:02 Jack Jiang 阅读(55) | 评论 (0)编辑 收藏

     摘要: 本文由爱奇艺技术团队原创分享,原题《爱奇艺Android客户端启动优化与分析》。1、引言互联网领域里有个八秒定律,如果网页打开时间超过8秒,便会有超过70%的用户放弃等待,对Android APP而言,要求更加严格,如果系统无响应时间超过5秒,便会出现ANR,APP可能会被强制关闭,因此,启动时间作为一个重要的性能指标,关系着用户的第一体验。爱奇艺安卓APP非常重视启动速度的优化,本文将从启动过程...  阅读全文

posted @ 2019-01-14 11:53 Jack Jiang 阅读(50) | 评论 (0)编辑 收藏

     摘要: 1、点评互联网发展至今已经高度发达,而对于互联网应用(尤其即时通讯技术这一块)的开发者来说,网络编程是基础中的基础,只有更好地理解相关基础知识,对于应用层的开发才能做到游刃有余。对于Android程序员来说,如果您觉得本文内容稍显枯燥,可以看看即时通讯网之前整理过的一篇类似文章《迈向高阶:优秀Android程序员必知必会的网络基础》,该文内容更偏向于知识点的概括。如果您希望更系统地学习网络编程方面...  阅读全文

posted @ 2019-01-10 11:15 Jack Jiang 阅读(48) | 评论 (0)编辑 收藏

     摘要: 本文来自腾讯QQ技术团队工程师许灵锋、周海发的技术分享。一、引言自 2015 年春节以来,QQ 春节红包经历了企业红包(2015 年)、刷一刷红包(2016 年)和 AR 红包(2017 年)几个阶段,通过不断创新玩法,活跃度节节攀升,成为春节一大玩点,给火红的春节带来一抹亮色。2017 年除夕,AR 红包、刷一刷红包再创新高,抢红包用户数达 3.42 亿,共刷出红包 37.77 亿个。那么,QQ...  阅读全文

posted @ 2019-01-07 12:10 Jack Jiang 阅读(77) | 评论 (0)编辑 收藏

     摘要: 本文原作者“minminaya”,作者网站:minminaya.cn,为了提升文章品质,即时通讯网对内容作了幅修订和改动,感谢原作者。1、引言对于IM应用和消息推送服务的开发者来说,在Android机型上的后台保活是个相当头疼的问题。老板一句:“为什么微信、QQ能收到消息,而你写的APP却不行?”,直接让人崩溃,话说老板你这APP要是整成微信、APP...  阅读全文

posted @ 2018-12-27 15:08 Jack Jiang 阅读(135) | 评论 (0)编辑 收藏

Jack Jiang的 Mail: jb2011@163.com, 联系QQ: 413980957, 微信: hellojackjiang