Jack Jiang

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

2018年5月23日

     摘要: 一、引言要实现一整套能用于大用户量、高并发场景下的IM群聊,技术难度远超IM系统中的其它功能,原因在于:IM群聊消息的实时写扩散特性带来了一系列技术难题。举个例子:如一个2000人群里,一条普通消息的发出问题,将瞬间写扩散为2000条消息的接收问题,如何保证这些消息的及时、有序、高效地送达,涉及到的技术问题点实在太多,更别说个别场景下万人大群里的炸群消息难题了更别说个别场景下万人大群里的炸群消息难...  阅读全文

posted @ 2018-10-17 14:31 Jack Jiang 阅读(21) | 评论 (0)编辑 收藏

本文引用了阿豪的微信公众号文章分享,感谢原作者的分享。

1、前言

随着社会的发展、互联网技术的进步,以前的大型机服务端架构很显然由于高成本、难维护等原因渐渐地变得不再那么主流了,替代它的就是当下最火的互联网分布式架构。

从若干年前大行其道的传统大型机到如今的分布式架构,技术发展已经经历了好几个阶段,我们只有弄明白典型互联网架构在各个阶段的演进,才能更好地理解和体会分布式架构的好处,从而有助于我们序设计适合于自已公司、产品或项目的架构(也包括设计即时通讯网专注的IM和消息推送这类系统,因为技术思路的原理都是一脉相承的)。那么本文我们就来聊聊分布式架构的演进过程,希望能给大家带来眼前一亮的感觉。

点评:即时通讯网作为IM和推送技术研究、学习和分享的社区,整理了大量的跟IM和推广技术有关的基础技术资料(比如网络基础、通信理论、架构基础等),本文内容虽然看起来跟IM和推送技术没有直接的关联性,但因为设计IM和推送系统的技术思路和原理跟典型大型互联网分布式架构都是一脉相承的,因而读懂本文内容对于IM和推送系统的架构设计同样大有裨益。

学习交流:

- 即时通讯开发交流3群:185926912[推荐]

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

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

2、相关文章

如果你已完全掌握本文的相关知识,请移步继续阅读即时通讯网整理的另一篇:《腾讯资深架构师干货总结:一文读懂大型分布式系统设计的方方面面》,该文适合对互联网架构知识有一定了解的程序员阅读和学习,都是不可能多得的技术干货。

3、技术背景说明

我们都知道一个成熟的大型网站的系统架构并非一开始就设计的非常完美,也没有一开始就具备高性能、高并发、高可用、安全性等特性,而是随着用户量的增加、业务功能的扩展逐步演变过来的,慢慢的完善的。 在这个过程中,开发模式、技术架构等都会随着迭代发生非常大的变化。 而针对不同业务特征的系统,各自都会有自己的侧重点,例如像淘宝这类的网站,要解决的重点问题就是海量商品搜索、下单、支付等问题; 像腾讯这类的网站,要解决的是数亿级别用户的实时消息传输;而像百度这类的公司所要解决的又是海量数据的搜索。每一个种类的业务都有自己不同的系统架构。

为了方便展开本文要讲解的内容,我们来简单模拟一个架构演变过程: 我们以 javaweb 为例,来搭建一个简单的电商系统,从这个系统中来看系统的演变过程。要注意的是接下来的演示模型, 关注的是数据量、访问量提升,网站结构的变化, 而不关注具体业务的功能点。其次,这个过程是为了让大家能更好的了解网站演进过程中的一些问题和应对策略。

假如我们要设计的互联网系统需要具备以下功能:

1)用户模块:用户注册和管理;

2)商品模块:商品展示和管理;

3)交易模块:创建交易及支付结算。

请带着上述3个技术点,继续深入阅读本文的正文内容。干货马上开始了。。。

4、架构演进阶段一:单应用架构

如上图所示,这个阶段是网站的初期,也可以认为是互联网发展的早期,系统架构如上图所示。我们经常会在单台服务器上运行我们所有的程序和软件。 把所有软件和应用都部署在一台机器上,这样就完成一个简单系统的搭建,这个阶段的讲究的是效率。效率决定生死。

5、架构演进阶段二:应用服务器和数据库服务器分离

随着网站的上线,访问量逐步上升,服务器的负载慢慢提高,我们应该在服务器还没有超载的时候就做好规划、提升网站的负载能力。假若此时已经没办法在代码层面继续优化提高,那么在单台机器的性能遇到瓶颈的时候,增加机器是一个比较简单好用的方式,投入产出比相当高。这个阶段增加机器的主要目的是将 web 服务器和 数据库服务器拆分开来,这样做的话不仅提高了单机的负载能力,也提高了整个系统的容灾能力。

这个阶段的系统架构如上图所示,应用服务器和数据库服务器完全隔离开来,相互互不影响,大大减少了网站宕机的风险,此阶段我们已经开始关注到应用服务器的管理了。 

6、架构演进阶段三:应用服务器集群

这个阶段,随着访问量的继续不断增加,单台应用服务器已经无法满足我们的需求。 假设我的数据库服务器还没有遇到性能问题,那我们可以通过增加应用服务器的方式来将应用服务器集群化,这样就可以将用户请求分流到各个服务器中,从而达到继续提升系统负载能力的目的。此时各个应用服务器之间没有直接的交互,他们都是依赖数据库各自对外提供服务。

系统架构发展到这个阶段,各种问题也会接踵而至:

1)用户请求交由谁来转发到具体的应用服务器上(谁来负责负载均衡);

2)用户如果每次访问到的服务器不一样,那么如何维护session,达到session共享的目的。

那么此时,系统架构又会变成如下方式:

负载均衡又可以分为软负载和硬负载。软负载我们可以选择Nginx、Apache等,硬负载我们可以选择F5等。而session共享问题我们可以通过配置tomcat的session共享解决。

7、架构演进阶段四:数据库压力变大,数据库读写分离

架构演变到上面的阶段,并不是终点。通过上面的设计,应用层的性能被我们拉上来了, 但数据库的负载也在逐渐增大,那如何去提高数据库层面的性能呢?有了前面的设计思路以后,我们自然也会想到通过增加服务器来提高性能。但假如我们单纯的把数据库一分为二,然后对于数据库的请求,分别负载到两台数据库服务器上,那必定会造成数据库数据不统一的问题。 

所以我们一般先考虑将数据库读写分离,如下图所示。

这个架构设计的变化会带来如下几个问题:

1)主从数据库之间的数据需要同步(可以使用 mysql 自带的 master-slave 方式实现主从复制 );

2)应用中需要根据业务进行对应数据源的选择( 采用第三方数据库中间件,例如 mycat )。

8、架构演进阶段五:使用搜索引擎缓解读库的压力

我们都知道数据库常常对模糊查找效率不是很高,像电商类的网站,搜索是非常核心的功能,即使是做了读写分离,这个问题也不能得到有效解决。那么这个时候我们就需要引入搜索引擎了,使用搜索引擎能够大大提升我们系统的查询速度,但同时也会带来一 些附加的问题,比如维护索引的构建、数据同步到搜索引擎等。

9、架构演进阶段六:引入缓存机制缓解数据库的压力

然后,随着访问量的持续不断增加,逐渐会出现许多用户访问同一内容的情况,那么对于这些热点数据,没必要每次都从数据库重读取,这时我们可以使用到缓存技术,比如 redis、memcache 来作为我们应用层的缓存。

另外在某些场景下,如我们对用户的某些 IP 的访问频率做限制, 那这个放内存中就又不合适,放数据库又太麻烦了,那这个时候可以使用 Nosql 的方式比如 mongDB 来代替传统的关系型数据库。

10、架构演进阶段七:数据库的水平/垂直拆分

我们的网站演进的变化过程,交易、商品、用户的数据都还在同一 个数据库中,尽管采取了增加缓存,读写分离的方式,但是随着数 据库的压力持续增加,数据库的瓶颈仍然是个最大的问题。因此我 们可以考虑对数据的垂直拆分和水平拆分。

垂直拆分:把数据库中不同业务数据拆分到不同的数据库;

水平拆分:把同一个表中的数据拆分到两个甚至更多的数据库中,水平拆分的原因是某些业务数据量已经达到了单个数据库的瓶颈,这时可以采取将表拆分到多个数据库中。

11、架构演进阶段八:应用的拆分

随着业务的发展,业务量越来越大,应用的压力越来越大。工程规模也越来越庞大。这个时候就可以考虑将应用拆分,按照领域模型将我们的用户、商品、交易拆分成多个子系统。

这样拆分以后,可能会有一些相同的代码,比如用户操作,在商品和交易都需要查询,所以会导致每个系统都会有用户查询访问相关操作。这些相同的操作一定是要抽象出来,否则就是一个坑。所以通过走服务化路线的方式来解决。

那么服务拆分以后,各个服务之间如何进行远程通信呢? 通过 RPC 技术,比较典型的有:dubbo、webservice、hessian、http、RMI 等等。前期通过这些技术能够很好的解决各个服务之间通信问题,但是, 互联网的发展是持续的,所以架构的演变和优化也还在持续。

12、本文小结

通过本文,我们通过一个电商的案例,就了解到了分布式架构的演进过程,一环套一环,环环紧密相扣。都是通过业务量和访问量的提升来考虑重构架构设计,以便能够适应当前的环境。不可一蹴而就,也急不来,初创企业必须稳扎稳打,一步一个脚印的走出一条专属自己的路。

本文主要针对的是零基础初学者,如果您想深入了解相关知识,请继续阅读《腾讯资深架构师干货总结:一文读懂大型分布式系统设计的方方面面》。

附录:更多架构方面的技术文章

浅谈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聊天消息序列号生成实践(容灾方案篇)

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

>> 更多同类文章 ……

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

posted @ 2018-10-15 10:57 Jack Jiang 阅读(30) | 评论 (0)编辑 收藏

     摘要: 1、点评对于IM系统来说,如何做到IM聊天消息离线差异拉取(差异拉取是为了节省流量)、消息多端同步、消息顺序保证等,是典型的IM技术难点。就像即时通讯网整理的以下IM开发干货系列一样:《IM消息送达保证机制实现(一):保证在线实时消息的可靠投递》《IM消息送达保证机制实现(二):保证离线消息的可靠投递》《如何保证IM实时消息的“时序性”与“一致性”?...  阅读全文

posted @ 2018-10-10 15:16 Jack Jiang 阅读(20) | 评论 (0)编辑 收藏

     摘要: 1、引言特别说明:本文内容仅用于即时通讯技术研究和学习之用,请勿用于非法用途。如本文内容有不妥之处,请联系JackJiang进行处理!我司有关部门为了获取黑产群的动态,有同事潜伏在大量的黑产群(QQ群、微信群)中,干起了无间道的工作。随着黑产群数量的激增,同事希望能自动获取黑产群的聊天信息,并交付风控引擎进行风险评估。于是,这个工作就交给我了,是时候表现一波了……针对同事的...  阅读全文

posted @ 2018-10-08 11:33 Jack Jiang 阅读(38) | 评论 (0)编辑 收藏

     摘要: 1、概述本文来自腾讯视频云终端技术总监rexchang(常青)技术分享,内容分别介绍了微信小程序视音视频和WebRTC的技术特征、差异等,并针对两者的技术差异分享和总结了微信小程序视音视频和WebRTC互通的实现思路以及技术方案。希望能带给你启发。学习交流:- 即时通讯开发交流3群:185926912[推荐]- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》(本文同步发布于:ht...  阅读全文

posted @ 2018-09-29 11:05 Jack Jiang 阅读(19) | 评论 (0)编辑 收藏

     摘要: 1、引言消息是互联网信息的一种表现形式,是人利用计算机进行信息传递的有效载体,比如即时通讯网坛友最熟悉的即时通讯消息就是其具体的表现形式之一。消息从发送者到接收者的典型传递方式有两种:1)一种我们可以称为即时消息:即消息从一端发出后(消息发送者)立即就可以达到另一端(消息接收者),这种方式的具体实现就是平时最常见的IM聊天消息;2)另一种称为延迟消息:即消息从某端发出后,首先进入一个容器进行临时存...  阅读全文

posted @ 2018-09-26 14:52 Jack Jiang 阅读(45) | 评论 (0)编辑 收藏

1、MMKV简介

腾讯微信团队于2018年9月底宣布开源 MMKV ,这是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,主打高性能和稳定性。近期也已移植到 Android 平台,一并对外开源。

MMKV 是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。从 2015 年中至今,在 iOS 微信上使用已有近 3 年,其性能和稳定性经过了时间的验证。近期也已移植到 Android 平台,一并开源。

MMKV最新源码托管地址:https://github.com/Tencent/MMKV

2、MMKV 源起

在微信客户端的日常运营中,时不时就会爆发特殊文字引起系统的 crash(请参见文章:《微信团队分享:iOS版微信是如何防止特殊字符导致的炸群、APP崩溃的?》、《微信团队分享:iOS版微信的高性能通用key-value组件技术实践》),文章里面设计的技术方案是在关键代码前后进行计数器的加减,通过检查计数器的异常,来发现引起闪退的异常文字。在会话列表、会话界面等有大量 cell 的地方,希望新加的计时器不会影响滑动性能;另外这些计数器还要永久存储下来——因为闪退随时可能发生。

这就需要一个性能非常高的通用 key-value 存储组件,我们考察了 SharedPreferences、NSUserDefaults、SQLite 等常见组件,发现都没能满足如此苛刻的性能要求。考虑到这个防 crash 方案最主要的诉求还是实时写入,而 mmap 内存映射文件刚好满足这种需求,我们尝试通过它来实现一套 key-value 组件。

3、MMKV 原理

内存准备:

通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。

数据组织:

数据序列化方面我们选用 protobuf 协议,pb 在性能和空间占用上都有不错的表现。

写入优化:

考虑到主要使用场景是频繁地进行写入更新,我们需要有增量更新的能力。我们考虑将增量 kv 对象序列化后,append 到内存末尾。

空间增长:

使用 append 实现增量更新带来了一个新的问题,就是不断 append 的话,文件大小会增长得不可控。我们需要在性能和空间上做个折中。

更详细的设计原理参考MMKV 原理

4、iOS 指南

安装引入(推荐使用 CocoaPods):

安装CocoaPods

打开命令行,cd到你的项目工程目录, 输入pod repo update让 CocoaPods 感知最新的 MMKV 版本;

打开 Podfile, 添加pod 'MMKV'到你的 app target 里面;

在命令行输入pod install;

用 Xcode 打开由 CocoaPods 自动生成的.xcworkspace文件;

添加头文件#import <MMKV/MMKV.h>,就可以愉快地开始你的 MMKV 之旅了。

更多安装指引参考iOS Setup

快速上手:

MMKV 的使用非常简单,无需任何配置,所有变更立马生效,无需调用synchronize:

MMKV *mmkv = [MMKV defaultMMKV];    [mmkvsetBool:YESforKey:@"bool"];BOOL bValue = [mmkvgetBoolForKey:@"bool"];    [mmkvsetInt32:-1024forKey:@"int32"];int32_t iValue = [mmkvgetInt32ForKey:@"int32"];    [mmkvsetObject:@"hello, mmkv"forKey:@"string"];NSString *str = [mmkvgetObjectOfClass:NSString.classforKey:@"string"];

更详细的使用教程参考iOS Tutorial

性能对比:

循环写入随机的int1w 次,我们有如下性能对比:

更详细的性能对比参考iOS Benchmark

5、Android 指南

安装引入:

推荐使用 Maven:

dependencies{implementation'com.tencent:mmkv:1.0.10'// replace"1.0.10"with any available version}

更多安装指引参考Android Setup

快速上手:

MMKV 的使用非常简单,所有变更立马生效,无需调用sync、apply。 在 App 启动时初始化 MMKV,设定 MMKV 的根目录(files/mmkv/),例如在 MainActivity 里:

protectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);    String rootDir = MMKV.initialize(this);    System.out.println("mmkv root: "+ rootDir);//……}

MMKV 提供一个全局的实例,可以直接使用:

importcom.tencent.mmkv.MMKV;//……MMKV kv = MMKV.defaultMMKV();kv.encode("bool",true);booleanbValue = kv.decodeBool("bool");kv.encode("int", Integer.MIN_VALUE);intiValue = kv.decodeInt("int");kv.encode("string","Hello from mmkv");String str = kv.decodeString("string");

MMKV 支持多进程访问,更详细的用法参考Android Tutorial

性能对比:

循环写入随机的int1k 次,我们有如下性能对比:

更详细的性能对比参考Android Benchmark

posted @ 2018-09-22 11:20 Jack Jiang 阅读(33) | 评论 (0)编辑 收藏

     摘要: 本文引用了公众号纯洁的微笑作者奎哥的技术文章,感谢原作者的分享。1、前言老于网络编程熟手来说,在测试和部署网络通信应用(比如IM聊天、实时音视频等)时,如果发现网络连接超时,第一时间想到的就是使用Ping命令Ping一下服务器看看通不通。甚至在有些情况下通过图形化的Ping命令工具对目标网络进行长测(比如:《两款增强型Ping工具:持续统计、图形化展式网络状况 [附件下载]》、《网络测试:Andr...  阅读全文

posted @ 2018-09-21 18:12 Jack Jiang 阅读(46) | 评论 (0)编辑 收藏

     摘要: 本文来自知乎官方技术团队的“知乎技术专栏”,感谢原作者陈鹏的无私分享。1、引言知乎存储平台团队基于开源Redis 组件打造的知乎 Redis 平台,经过不断的研发迭代,目前已经形成了一整套完整自动化运维服务体系,提供很多强大的功能。本文作者陈鹏是该系统的负责人,本次文章深入介绍了该系统的方方面面,值得互联网后端程序员仔细研究。(本文同步发布于:http://www.52im...  阅读全文

posted @ 2018-09-18 12:31 Jack Jiang 阅读(42) | 评论 (0)编辑 收藏

     摘要: 1、前言网络通信一直是Android项目里比较重要的一个模块,Android开源项目上出现过很多优秀的网络框架,从一开始只是一些对HttpClient和HttpUrlConnection简易封装使用的工具类,到后来Google开源的比较完善丰富的Volley,再到如今比较流行的Okhttp、Retrofit。要想理解他们之间存在的异同(或者具体点说,要想更深入地掌握Android开发中的网络通信技...  阅读全文

posted @ 2018-09-17 10:44 Jack Jiang 阅读(36) | 评论 (0)编辑 收藏

     摘要: 本文原文内容来自InfoQ的技术分享,本次有修订、勘误和加工,感谢原作者的分享。1、前言自从2018年8月20日子弹短信在锤子发布会露面之后(详见《老罗最新发布了“子弹短信”这款IM,主打熟人社交能否对标微信?》),关于它的讨论不绝于耳,7 天融资 1.5 亿的传闻更是将它推到了风口浪尖(请见《[资讯] “子弹短信”发布一周即融得1.5亿资金》)。&...  阅读全文

posted @ 2018-09-14 13:50 Jack Jiang 阅读(36) | 评论 (0)编辑 收藏

     摘要: 本文来自“人人都是产品经理”公众号作者栗栗粥的原创分享。1、前言移动端的时代里,微信占据了社交领域的半壁江山,不得不让人想起曾经PC时代里的王者“QQ”,微信的爆发和QQ的停滞让很多人认为微信已经彻底将QQ打败,QQ已经不再适合这个时代了。前不久看到一句有意思的分享说:“与其说微信为什么能打败QQ,不如说QQ为什么没有被微信打败。R...  阅读全文

posted @ 2018-09-11 14:58 Jack Jiang 阅读(54) | 评论 (0)编辑 收藏

     摘要: 本文原作者:李越,由银杏财经原创发布,本次内容改动。1、前言上线一周完成1.5亿元融资,上线10天总激活用户数超400万,8月29日单日新增用户超100万,这是子弹短信交出的最新成绩单(详见《[资讯] “子弹短信”发布一周即融得1.5亿资金》)。▲ 老罗的“子弹短信”这个牛逼,又可以吹很久了这样的数据,几乎就要接近移动互联网时代APP最快...  阅读全文

posted @ 2018-09-09 21:02 Jack Jiang 阅读(24) | 评论 (0)编辑 收藏

     摘要: 1、前言随着互联网的发展,面对海量用户高并发业务,传统的阻塞式的服务端架构模式已经无能为力。本文(和下篇《高性能网络编程(六):一文读懂高性能网络编程中的线程模型》)旨在为大家提供有用的高性能网络编程的I/O模型概览以及网络服务进程模型的比较,以揭开设计和实现高性能网络架构的神秘面纱。限于篇幅原因,请将本文与《高性能网络编程(六):一文读懂高性能网络编程中的线程模型》连起来读,这样会让知识更连贯。...  阅读全文

posted @ 2018-09-06 21:09 Jack Jiang 阅读(114) | 评论 (0)编辑 收藏

     摘要: 本文来自公众号“傅老师”(ID:fustory)的原创分享,感谢作者。1、引言如果QQ是一个人,看似风光,其实从出生到成长,过程饱经错荡,堪算坎坷。它的人生历程确实也够励志的了。学习交流:- 即时通讯开发交流3群:185926912 [推荐]- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》(本文同步发布于:http://www.52im.net...  阅读全文

posted @ 2018-09-05 17:07 Jack Jiang 阅读(42) | 评论 (0)编辑 收藏

本文由达达京东到家Java工程师季炳坤原创分享。

1、前言

达达-京东到家作为优秀的即时配送物流平台,实现了多渠道的订单配送,包括外卖平台的餐饮订单、新零售的生鲜订单、知名商户的优质订单等。为了提升平台的用户粘性,我们需要兼顾商户和骑士的各自愿景:商户希望订单能够准时送达,骑士希望可以高效抢单。那么在合适的时候提升订单定制化的曝光率,是及时送物流平台的核心竞争力之一。

本文将描述“达达-京东到家”的订单即时派发系统从无到有的系统演进过程,以及方案设计的关键要点,希望能为大家在解决相关业务场景上提供一个案例参考。

关于“达达-京东到家”:

达达-京东到家,是同城速递信息服务平台和无界零售即时消费平台。达达-京东到家创始人兼首席执行官蒯佳祺;

公司旗下,目前已覆盖全国400 多个主要城市,服务超过120万商家用户和超 5000万个人用户;

2018年8月,达达-京东到家正式宣布完成最新一轮5亿美元融资,投资方分别为沃尔玛和京东。

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

2、关于作者

季炳坤:“达达-京东到家”Java工程师,负责“达达-京东到家”的订单派发、订单权限、合并订单等相关技术工作的实现。

3、订单即时派发架构的演进

在公司发展的初期,我们的外卖订单从商户发单之后直接出现在抢单池中,3公里之内的骑士能够看到订单,并且从订单卡片中获取配送地址、配送时效等关键信息。这种暴力的显示模式,很容易造成骑士挑选有利于自身的订单进行配送,从而导致部分订单超时未被配送。这样的模式,在一定程度上导致了商户的流失,同时也浪费了骑士的配送时间。

从上面的场景可以看出来,我们系统中缺少一个订单核心调度者。有一种方案是选择区域订单的订单调度员,由调度员根据骑士的接单情况、配送时间、订单挤压等实时情况来进行订单调度。这种模式,看似可行,但是人力成本投入太高,且比较依赖个人的经验总结。

核心问题已经出来了:个人的经验总结会是什么呢?

1) 骑士正在配送的订单的数量,是否已经饱和;

2) 骑士的配送习惯是什么;

3) 某一阶段的订单是否顺路,骑士是否可以一起配送;

4) 骑士到店驻留时间的预估;

5) ...

理清核心问题的答案,我们的系统派单便成为了可能。

基于以上的原理,订单派发模式就可以逐渐从抢单池的订单显示演变成系统派单:

我们将会:

1)记录商户发单行为;

2)骑士配送日志及运行轨迹等信息。

并且经过数据挖掘和数据分析:

1)获取骑士的画像;

2)骑士配送时间的预估;

3)骑士到店驻留时间的预估等基础信息;

4)使用遗传算法规划出最优的配送路径;

5)...

经过上述一系列算法,我们将在骑士池中匹配出最合适的骑士,进而使用长连接(Netty)不间断的通知到骑士。

随着达达业务的不断迭代,订单配送逐渐孵化出基于大商户的驻店模式:基于商户维护一批固定的专属骑士,订单只会在运力不足的时候才会外发到抢单池中,正常情况使用派单模式通知骑士。

4、订单派发模型的方案选型

订单派发可以浅显的认为是一种信息流的推荐。在订单进入抢单池之前,我们会根据每个城市的调度情况,先进行轮询N次的派单。

大概的表现形式如下图:

举例:有笔订单需要进行推送,在推送过程中,我们暂且假设一直没有骑士接单,那么这笔订单会每间隔N秒便会进行一次普通推荐,然后进入抢单池。

从订单派发的流程周期上可以看出来,派发模型充斥着大量的延迟任务,只要能解决订单在什么时候可以进行派发,那么整个系统 50% 的功能点就能迎刃而解。

我们先了解一下经典的延迟方案,请继续往下读。。。

4.1 方案1:数据库轮询

通过一个线程定时的扫描数据库,获取到需要派单的订单信息。

优点:开发简单,结合quartz即可以满足分布式扫描;

缺点:对数据库服务器压力大,不利于项目后续发展。

4.2 方案2:JDK的延迟队列 - DelayQueue

DelayQueue是Delayed元素的一个无界阻塞队列,只有在延迟期满时才能从中提取元素。队列中对象的顺序按到期时间进行排序。

优点:开发简单,效率高,任务触发时间延迟低;

缺点:服务器重启后,数据会丢失,要满足高可用场景,需要hook线程二次开发;宕机的担忧;如果数据量暴增,也会引起OOM的情况产生。

4.3 方案3:时间轮 - TimingWheel

时间轮的结构原理很简单,它是一个存储定时任务的环形队列,底层是由数组实现,而数组中的每个元素都可以存放一个定时任务列表。列表中的每一项都表示一个事件操作单元,当时间指针指向对应的时间格的时候,该列表中的所有任务都会被执行。 时间轮由多个时间格组成,每个时间格代表着当前实践论的跨度,用tickMs代表;时间轮的个数是固定的,用wheelSize代表。

整个时间轮的跨度用interval代表,那么指针转了一圈的时间为:

interval = tickMs * wheelSize

如果tickMs=1ms,wheelSize=20,那么便能计算出此时的时间是以20ms为一转动周期,时间指针(currentTime)指向wheelSize=0的数据槽,此时有5ms延迟的任务插入了wheelSize=5的时间格。随着时间的不断推移,指针currentTime不断向前推进,过了5ms之后,当到达时间格5时,就需要将时间格5所对应的任务做相应的到期操作。

如果此时有个定时为180ms的任务该如何处理?很直观的思路是直接扩充wheelSize?这样会导致wheelSize的扩充会随着业务的发展而不断扩张,这样会使时间轮占用很大的内存空间,导致效率低下,因此便衍生出了层级时间轮的数据结构。

180ms的任务会升级到第二层时间轮中,最终被插入到第二层时间轮中时间格#8所对应的TimerTaskList中。如果此时又有一个定时为600ms的任务,那么显然第二层时间轮也无法满足条件,所以又升级到第三层时间轮中,最终被插入到第三层时间轮中时间格#1的TimerTaskList中。注意到在到期时间在[400ms,800ms)区间的多个任务(比如446ms、455ms以及473ms的定时任务)都会被放入到第三层时间轮的时间格#1中,时间格#1对应的TimerTaskList的超时时间为400ms。

随着时间轮的转动,当TimerTaskList到期时,原本定时为450ms的任务还剩下50ms的时间,还不能执行这个任务的到期操作。便会有个时间轮降级的操作,会将这个剩余时间50ms的定时任务重新提交到下一层级的时间轮中,所以该任务被放到第二层时间轮到期时间为 [40ms,60ms) 的时间格中。再经历了40ms之后,此时这个任务又被触发到,不过还剩余10ms,还是不能立即执行到期操作。所以还要再一次的降级,此任务会被添加到第一层时间轮到期时间为[10ms,11ms)的时间格中,之后再经历10ms后,此任务真正到期,最终执行相应的到期操作。

优点:效率高,可靠性高(Netty,Kafka,Akka均有使用),便于开发;

缺点:数据存储在内存中,需要自己实现持久化的方案来实现高可用。

5、订单派发方案的具体实现

结合了上述的三种方案,最后决定使用redis作为数据存储,使用timingWhell作为时间的推动者。这样便可以将定时任务的存储和时间推动进行解耦,依赖Redis的AOF机制,也不用过于担心订单数据的丢失。

kafka中为了处理成千上万的延时任务选择了多层时间轮的设计,我们从业务角度和开发难度上做了取舍,只选择设计单层的时间轮便可以满足需求。

1)时间格和缓存的映射维护:

假设当前时间currentTime为11:49:50,订单派发时间dispatchTime为11:49:57,那么时间轮的时间格#7中会设置一个哨兵节点(作为是否有数据存储在redis的依据 )用来表示该时间段是否会时间事件触发,同时会将这份数据放入到缓存中(key=dispatchTime+ip), 当7秒过后,触发了该时间段的数据,便会从redis中获取数据,异步执行相应的业务逻辑。最后,防止由于重启等一些操作导致数据的丢失,哨兵节点的维护也会在缓存中维护一份数据,在重启的时候重新读取。

2)缓存的key统一加上IP标识:

由于我们的时间调度器是依附于自身系统的,通过将缓存的key统一加上IP的标识,这样就可以保证各台服务器消费属于自身的数据,从而防止分布式环境下的并发问题,也可以减轻遍历整个列表带来的时间损耗(时间复杂度为O(N))。

3)使用异步线程处理时间格中对应的数据:

使用异步线程,是考虑到如果上一个节点发生异常或者超时等情况,会延误下一秒的操作,如果使用异常可以改善调度的即时性问题。

我们在设计系统的时候,系统的完善度和业务的满足度是互相关联影响的,单从上述的设计看,是会有些问题的,比如使用IP作为缓存的key,如果集群发生变更便会导致数据不会被消费;使用线程池异步处理也有概率导致数据不会被消费。这些不会被消费的数据会进入到抢单池中。从派单场景的需求来看,这些场景是可以被接受的,当然了,我们系统会有脚本来进行定期的筛选,将那些进入抢单池的订单进行再次派单。

* 思考:为什么不使用ScheduledThreadPoolExecutor来定时轮询redis?

原因是即便这样可以完成业务上的需求,获取定时触发的任务,但是带来的空查询不但会拉高服务的CPU,redis的QPS也会被拉高,可能会导致redis的慢查询会显著增多。

6、结语

我们在完成一个功能的时候,往往需要一些可视化的数据来确定业务发展的正确性。因此我们在开发的时候,也相应的记录了一些订单与骑士的交互动作。从每天的报表数据可以看出来,90% 以上的订单是通过派单发出并且被骑士认可接单。

订单派发的模式是提升订单曝光率有效的技术手段,我们一直结合大数据、人工智能等技术手段希望能更好的做好订单派发,能提供更加多元化的功能,将达达打造成更加一流的配送平台。

附录:更多相关技术文章

伪即时通讯:分享滴滴出行iOS客户端的演进过程

iOS的推送服务APNs详解:设计思路、技术原理及缺陷等

信鸽团队原创:一起走过 iOS10 上消息推送(APNS)的坑

Android端消息推送总结:实现原理、心跳保活、遇到的问题等

扫盲贴:认识MQTT通信协议

一个基于MQTT通信协议的完整Android推送Demo

IBM技术经理访谈:MQTT协议的制定历程、发展现状等

求教android消息推送:GCM、XMPP、MQTT三种方案的优劣

移动端实时消息推送技术浅析

扫盲贴:浅谈iOS和Android后台实时消息推送的原理和区别

绝对干货:基于Netty实现海量接入的推送服务技术要点

移动端IM实践:谷歌消息推送服务(GCM)研究(来自微信)

为何微信、QQ这样的IM工具不使用GCM服务推送消息?

极光推送系统大规模高并发架构的技术实践分享

从HTTP到MQTT:一个基于位置服务的APP数据通信实践概述

魅族2500万长连接的实时消息推送架构的技术实践分享

专访魅族架构师:海量长连接的实时消息推送系统的心得体会

深入的聊聊Android消息推送这件小事

基于WebSocket实现Hybrid移动应用的消息推送实践(含代码示例)

一个基于长连接的安全可扩展的订阅/推送服务实现思路

实践分享:如何构建一套高可用的移动端消息推送系统?

Go语言构建千万级在线的高并发消息推送系统实践(来自360公司)

腾讯信鸽技术分享:百亿级实时消息推送的实战经验

百万在线的美拍直播弹幕系统的实时推送技术实践之路

京东京麦商家开放平台的消息推送架构演进之路

了解iOS消息推送一文就够:史上最全iOS Push技术详解

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

解密“达达-京东到家”的订单即时派发技术原理和实践》

>> 更多同类文章 ……

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

posted @ 2018-09-04 10:20 Jack Jiang 阅读(42) | 评论 (0)编辑 收藏

     摘要: 本文参考并引用了部分腾讯游戏学院的相关技术文章内容,感谢原作者的分享。1、前言以现在主流的即时通讯应用形态来讲,一个完整的即时通讯IM应用其实是即时通信(英文简写:IM=Instant messaging)和实时通信(英文简写:RTC=Real-time communication)2种技术组合在一起的一整套网络通信系统。之所以以IM这个简写代称整个即时通讯软件,其实是历史原因了(因为早期的诸如I...  阅读全文

posted @ 2018-08-29 18:21 Jack Jiang 阅读(28) | 评论 (0)编辑 收藏

1、引言

2018年8月20日,锤子科技在北京召开了夏季新品发布会。除了新手机,发布会上还正式推出了主打语音功能的即时通讯IM聊天工具:子弹短信。这款工具此前今年早些时候在「鸟巢」发布会上初次亮相,在经历了几个月的测试后,如今终于正式上线了(想要尝鲜的可以去官网下载:https://im.smartisan.com/,细节上坑还比较多,请自行体验)。

▲ 锤子科技2018夏季新品发布会
▲ “子弹短信”的多端效果图

从“子弹短信”官网上的效果图来看,这款IM目前至少支持iOS、Android、Web PC 3个端,还算是比较主流。在IM这片被巨头们早已稳固的红海,已经很久没有出现足够引起关注的产品了,老罗真是勇气可佳。自从2013年阿里的来往和网易的易信发布以来,这个市场鲜有触碰者。

▲ 2013年有两款IM新品问市(本图来自《史上最全即时通讯软件简史(精编大图版)[附件下载]》)

那么,老罗的“子弹短信”到底有什么特色?能否对标熟人社交的标杆产品微信呢?我们继续往下看。。。

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

2、「语音转文字」是“子弹短信”的核心特色

与其他同类工具最大的一点区别是,子弹短信把「语音转文字」放在了最重要的位置。进入聊天界面,按下蓝色的麦克风发送语音,子弹短信会自动将语音转换成文字。默认设置下,子弹短信会同时发送语音和文字消息,你也可以根据需要进行调整。

这样的好处是发送信息的一方可以根据自己的习惯来输入信息,但接受信息的一方在收到通知时可以直接看到文字,而不用打开应用来查看。相信有不少微信的用户会遇到收到一堆通知显示「语音」的情况,这种问题在子弹短信上就得到了解决。 

当然,要想实现好这一点,「语音转文字」必须要有足够高的成功率。在我们的测试中,子弹短信大部分情况下都能很好地完成转换。虽然偶尔也会出现识别的问题,好在你还可以通过听语音的方式再次确认。

另外,如果你向通讯录里的好友发送子弹短信,但对方当前没有下载子弹短信的话,信息会自动以手机短信的形式发送,这样即便对方不是子弹短信的用户也能收到信息。

3、“子弹短信”的原则:一切都为了「更快一步」

「快如闪电」子弹短信的广告语。为了达成这个目的,子弹短信做了很多工作。首先是全局的悬浮球功能。打开后你可以直接通过按住悬浮球来录入语音,然后选择联系人即可发送。

进入 App 后,点击消息列表的右侧的麦克风按钮可以直接回复消息,消息列表可同时查看多条未读消息,这些功能降低了用户点击进入对话的频率。 

如果你正在使用 Smartisan 手机的话,你还可以配合「闪念胶囊」来直接把胶囊当作文字信息进行发送。

总之,这些设计都是为了能让用户「更快一步」地发送和回复消息。「效率」一直是锤子科技产品的主打特色,而子弹短信在功能上的侧重也应证了这一点。

随着 Android 和 iOS 系统支持锁屏界面通知回复,越来越多的用户开始习惯不进入 App 直接回复消息。如果子弹短信将来能实现直接在锁屏界面录入语音发送,相信回复效率还能再提升一步。

4、「人性化」的小功能

锤子科技的产品从来都不缺乏一些有趣又实用的小功能,子弹短信这次也不例外。例如,你可以将任何信息设置为稍后处理,方便你标记出那些你需要回复和处理的信息。如果你平时习惯在聊天工具里处理工作的话,这样一个随手可用的「暂存箱」是非常有必要的。 

另外子弹短信还支持「引用回复」功能,在多人聊天的情况下很实用。长按某一条消息点击「引用并回复」,你就可以针对这一条消息进行回复,避免意义不明的问题。

还有一个有趣的功能叫「这是谁来着?」。我们有时会遇到因为跟对方不经常联系导致一换头像就不认识了的尴尬。在子弹短信里,点击联系人信息可以看到好友的历史头像。如果你觉得还是记不起来的话,可以点击底部的「这是谁来着?」,应用会显示与该好友第一次的对话记录,帮你回想起来这是谁。

更多子弹短信的功能,可以看看这篇《有点特别的聊天工具——子弹短信》。

5、小结一下

子弹短信是一款追求「快」的IM聊天工具。从语音出发,在功能设计的各个节点上想办法给用户带来「更快一步」的体验,从这个方面来说,它有着自己很鲜明的特色。

不过,在目前这个大环境下,想要找到自己的位置,子弹短信还需要回答一个核心问题:已经有微信这样强大IM,我们为什么还需要另一款聊天工具?

聊天工具的本质是用来连接人的社交关系,而子弹短信的各种功能相比于微信来说更适合于工作场景。如果你觉得微信在工作交流上不够好用,想尝试一下把自己的工作和生活进行区分,并且有能力自己选择工具,或许子弹短信是一个值得一试的选择。

不过,要想跟微信对标,哪有那么容易,你以为微信的成功是个偶然吗?请看看下面的文章:

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

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

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

好了,即时通讯产品真的没有那么容易成功:《为什么说即时通讯社交APP创业就是一个坑?》。不过,但愿“子弹短信”是个例外。

附录:更多文章

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

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

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

2017微信数据报告:日活跃用户达9亿、日发消息380亿条

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

技术往事:创业初期的腾讯——16年前的冬天,谁动了马化腾的代码》 

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

技术往事:“QQ群”和“微信红包”是怎么来的?》 

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

开发往事:微信千年不变的那张闪屏图片的由来》 

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

一个微信实习生自述:我眼中的微信开发团队

首次揭秘:QQ实时视频聊天背后的神秘组织

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

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

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

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

>> 更多同类文章 ……

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

posted @ 2018-08-22 19:47 Jack Jiang 阅读(59) | 评论 (0)编辑 收藏

     摘要: 1、前言可能有初学者会问,即时通讯应用的通信安全,不就是对Socket长连接进行SSL/TLS加密这些知识吗,干吗要理解HTTPS协议呢。这其实是个误解:当今主流的移动端IM数据通信,总结下来无外乎就是长连接+短连接的方式,长连接就是众所周之的TCP、UDP、WebSocket(WebSocket的本质还是TCP),而短连接就是HTTP/HTTPS了。即时通讯IM应用中,短连接的安全跟长连接相比,...  阅读全文

posted @ 2018-08-20 18:24 Jack Jiang 阅读(56) | 评论 (0)编辑 收藏

     摘要: 1、前言跨平台一直是老生常谈的话题,cordova、ionic、react-native、weex、kotlin-native、flutter等跨平台框架的百花齐放,颇有一股推倒原生开发者的势头。为什么我们需要跨平台开发? 本质上,跨平台开发是为了增加代码复用,减少开发者对多个平台差异适配的工作量,降低开发成本,提高业务专注的同时,提供比web更好的体验。嗯~通俗了说就是:省钱、偷懒。目...  阅读全文

posted @ 2018-08-13 10:51 Jack Jiang 阅读(142) | 评论 (0)编辑 收藏

     摘要: 本文内容由公众号“格友”原创分享。1、引言(不羁的大神,连竖中指都这么帅)因为LINUX操作系统的流行,Linus 已经成为地球人都知道的名人。虽然大家可能都听过钱钟书先生的名言:“假如你吃个鸡蛋觉得味道不错,又何必认识那个下蛋的母鸡呢?” 但是如果真是遇到一个“特别显赫”的鸡蛋,很多人还是想看看能生出这颗神蛋的母鸡的,或者想...  阅读全文

posted @ 2018-08-09 16:32 Jack Jiang 阅读(70) | 评论 (0)编辑 收藏

     摘要: 1、引言本文来自新浪微博视频转码平台技术负责人李成亚在LiveVideoStackCon 2017上的分享,由LiveVideoStack整理成文。李成亚分享了微博短视频如何提升用户体验、降低成本的思路与实践,包括提升短视频发布速度,降低长视频转码时间,通过新的Codec减少带宽成本等。本文的短视频技术跟IM的单聊、群聊、朋友圈里的小视频是类似的东西,文中针对短视频的相关优化实践可以为您的IM小视...  阅读全文

posted @ 2018-08-06 16:34 Jack Jiang 阅读(28) | 评论 (0)编辑 收藏

     摘要: 1、前言对于广大Android开发者来说,Android O(即Android 8.0)还没玩热,Andriod P(即Andriod 9.0)又要来了。下图上谷歌官方公布的Android P发布路线图:Android P的最后一个开发者预览版(即DP5)已如期发布于2018年7月26日,根据上面这张发布路线图,相信Android P的正式版将很快到来。对于Andriod开发者来说,不管Andri...  阅读全文

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

     摘要: 本文内容由“微信多媒体团队”整理发布。1、引言广州TIT创意园,这里是腾讯在广州的研发团队所在地,LiveVideoStack采访了微信多媒体内核中心音视频算法高级工程师梁俊斌(Denny)。从华为2012实验室到腾讯,过去十余年梁俊斌一直专注在音频技术。他告诉LiveVideoStack:音频技术还有许多难点需要解决,而作为技术人也延展到应用场景,关注用户需求。本文整理了...  阅读全文

posted @ 2018-07-31 15:25 Jack Jiang 阅读(37) | 评论 (0)编辑 收藏

     摘要: 1、前言本文要分享的消息推送指的是当iOS端APP被关闭或者处于后台时,还能收到消息/信息/指令的能力。这种在APP处于后台或关闭情况下的消息推送能力,通常在以下场景下非常有用:1)IM即时通讯聊天应用:聊天消息通知、音视频聊天呼叫等,典型代表有:微信、QQ、易信、米聊、钉钉、Whatsup、Line;2)新闻资讯应用:最新资讯通知等,典型代码有:网易新闻客户端、腾讯新闻客户端;3)SNS社交应用...  阅读全文

posted @ 2018-07-30 10:51 Jack Jiang 阅读(48) | 评论 (0)编辑 收藏

     摘要: 1、关于作者余果:腾讯社交用户体验设计部(ISUX)高级UI工程师,前端开发组负责人,熟悉前端开发、iOS开发、PHP开发和Ruby开发等;曾独立开发iOS APP(撸大师)和CMS(33PU);翻译有《众妙之门: 网站重新设计之道》和《响应式Web设计全流程解析》,著有《Web全栈工程师的自我修养》;平时喜欢编程、写作、演讲、摄影和英语等,希望自己能做一个终生学习者。关于腾讯ISUX:腾讯ISU...  阅读全文

posted @ 2018-07-27 12:32 Jack Jiang 阅读(40) | 评论 (0)编辑 收藏

     摘要: 1、引言我们常常会听说,某个互联网应用的服务器端系统多么牛逼,比如QQ、微信、淘宝。那么,一个大型互联网应用的服务器端系统,到底牛逼在什么地方?为什么海量的用户访问,会让一个服务器端系统变得更复杂?本文结合作者多年的互联网系统设计实践经验,从最基本的技术概念开始,带你探寻服务器端系统架构的方方面面。本文适合有过几年工作经验、正处于技术上升期的程序员阅读,内容少有浮夸,多为实践经验总结,希望能为您的...  阅读全文

posted @ 2018-07-25 17:13 Jack Jiang 阅读(64) | 评论 (0)编辑 收藏

     摘要: 1、引言图片通常是移动端应用流量耗费最多的部分,并且占据着重要的视觉空间。以大家最常用的即时通讯IM应用为例,应用中存在大量的图片数据往来(比如图片消息、用户相册、用户头像等等)。合理的图片格式选用和优化不仅能减小图片传递过程中的数据量、提升视觉效果,还能显著降低服务端的带宽、计算资源等基础设施成本,一举多得。本文我们一起全面分析学习目前主流和新兴的几种图片格式的特点、性能、调优等,以及相关开源库...  阅读全文

posted @ 2018-07-23 15:36 Jack Jiang 阅读(38) | 评论 (0)编辑 收藏

     摘要: 1、引言微信小程序自2017年1月9日正式对外公布以来,越来越受到关注和重视,小程序上的各种技术体验也越来越丰富。而音视频作为高速移动网络时代下增长最快的应用形式之一,在微信小程序中也当然不能错过。本文来自腾讯视频云终端技术总监rexchang(常青)的技术分享,讲述的是微信小程序中音视频技术构思、设计和实现等方方面的内容,希望能为你的音视频技术实践带来启发。如果您能微信小程序开发没什么了解,可以...  阅读全文

posted @ 2018-07-21 20:50 Jack Jiang 阅读(46) | 评论 (0)编辑 收藏

     摘要: 本文原作者阮一峰,作者博客:ruanyifeng.com。1、前言新一代HTTP/2 协议的主要目的是为了提高网页性能(有关HTTP/2的介绍,请见《从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路》)。HTTP/2以前版的头信息(header)是直接传输文本,现在是压缩后传输。原来是同一个 TCP 连接里面,上一个回应(response)发送完了,服务器才能发送下一个,...  阅读全文

posted @ 2018-07-19 16:18 Jack Jiang 阅读(38) | 评论 (0)编辑 收藏

     摘要: 本文作者:陈裕发, 腾讯系统测试工程师,由腾讯WeTest整理发表。1、引言开发iOS系统中的Push推送,通常有以下3种情况:1)在线Push:比如QQ、微信等IM界面处于前台时,聊天消息和指令都会通过IM自建的网络长连接通道推送过来,这种Push在本文中暂且称为“在线Push”;2)本地Push:这种就是最常见的iOS系统通知(作用相当于传统PC端的提示窗口,在iOS1...  阅读全文

posted @ 2018-07-16 14:45 Jack Jiang 阅读(390) | 评论 (1)编辑 收藏

     摘要: 1、引言每年的3、4月份都是求职高峰时期,目前已进入6、7月份了,你已经成功换工作了吗?这次我们想聊的,就是程序员跳槽这件事儿,我打算从三个方面来说:1)程序员什么时候该跳槽?2)跳槽前你需要做的准备工作?3)到哪里找跳槽机会?学习交流:- 即时通讯开发交流3群:185926912[推荐]- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》(本文同步发布于:http://www.5...  阅读全文

posted @ 2018-07-13 14:13 Jack Jiang 阅读(834) | 评论 (0)编辑 收藏

     摘要: 本文原作者:“竹千代”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动。 1、前言无论是即时通讯应用还是传统的信息系统,Http协议都是我们最常打交道的网络应用层协议之一,它的重要性可能不需要再强调(有鉴于此,即时通讯网整理了大量的有关http协议的文章,如有必要可从...  阅读全文

posted @ 2018-07-11 14:49 Jack Jiang 阅读(42) | 评论 (0)编辑 收藏

1、引言

MIT TR 35(MIT Technology Review 35 Innovators Under 35)——“全球 35 位 35 岁以下科技创新青年”榜单,是全球最权威的青年科技创新人才榜单之一。从1999年开始,《麻省理工科技评论》(MIT Technology Review,简称MIT TR)每年会在全球范围内寻觅最有可能改变世界、极具才华和创新精神的年轻技术人才、创新者或企业家。该榜单从影响力、创新力、进取力、未来潜力、沟通力五个维度评估,涵盖 IT(计算机、通信、网络)、生物医药、商业等领域,最终选出35位科技创新精英。

作为全球最权威的青年科技创新人才榜单之一,TR35挖掘的新人大都极具创新性,不少还在后来成为风云人物,包括谷歌的联合创始人拉里•佩奇和谢尔盖•布林、Facebook的创始人马克•扎克伯格、雅虎创始人杨致远、苹果公司的首席设计师乔纳森•艾维等。

美国时间6月27日,《麻省理工科技评论》正式对外发布“2018年度全球35位35岁以下的科技创新青年“全球榜单,其中蚂蚁金服国际事业群技术负责人许寄(花名:红雪)因“他参与创建的支付系统可以让金融服务更普及”而成功入选该榜单。

▲ “MIT TR 35”获奖评语

他高中毕业,没上大学四处打零工,路边修过自行车,也做过理发店小弟。想学自考混文凭,结果连自考的考试都挂掉了。

学历不是你成功的天花板,你的努力才是。

一位非科班出身、自学成才的人是如何从普通的一线程序员成长为带领近千人的蚂蚁金服国际技术团队的技术+业务大拿?下面让我们一起听听许寄(花名:红雪)的故事。

学习交流:

- 即时通讯开发交流3群:185926912[推荐]

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

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

2、“社会人”

▲ 许寄(花名:红雪)

我是个社会人。因为不喜欢那么多的作业那么多的考试,我尝试过离家打零工找刺激,干了些乱七八糟的事情,修自行车、杀鱼、理发……

撞了一头包后,觉得还是要有一技之长,我就去西安读自考打算混个文凭,学的电子商务。结果一个西安交大来的客座老师一上来就说,电子商务这个东西啊,中国二十年之内都没希望。

一屋子学生凉凉。有同学说,实在念不成书,只好回家继承老爸的工厂了。我一听,心更凉了,我可不能回家,回家也没工厂可继承啊。

那时,我开始痴迷电脑,特喜欢泡在电脑城研究各种硬件、板卡、内存条,帮同学组装电脑,学3D建模。我人生第一本认真从头看到尾的书是谭浩强的C语言。

那时候互联网在中国开始起来了,但程序员还远远不是一份好工作,就像《乘风破浪》里,警察询问小马什么职业,小马说编程的,警察说,嗯,那就是无业。

2001年春节快到来时,正经的电子商务学业几乎全荒废了,考试眼看就要挂掉,没脸回家过年,心理压力特别大。活了十几年还找不到人生目标的沮丧感。

那时,有一个同乡邀请我去他们学校玩,在宿舍里,他給我看了他的毕业设计,用VB写了一套图书管理系统。我当时脑袋像是被砸到了一样,当即决定转专业,管他将来能不能找到工作,这至少是我确定想学的。

人生前十几年浑浑噩噩、毫无目标的状态算是告了一个段落。2003年毕业后,我留在西安工作,一个月挣一千多块钱,大部分钱继续花在各种软件培训班上。

那时的学习状态,就像老鼠掉进了米缸,每天一下班就去学习,每天睡不了几个小时,但是不觉得累。

编者语:

很难想象这个带领着近千“学霸+海归”技术人的他,居然自称为“没上过大学的社会人”。曾经拒绝高中繁重的学业和备考,他尝试过离家打零工找刺激,修自行车、杀鱼、理发……很难想象,这些些“乱七八糟”的事情他都曾干过。后来他从痴迷电脑开始,帮同学组装电脑,学3D建模。他人生第一本认真从头看到尾的书是谭浩强的C语言。在这种学霸专属的“MIT TR 35”榜单上,这个自学成才的计算机怪才略显“骨骼清奇”。

3、初入阿里巴巴带给我的“燃烧感 ”

2007年,我接到一封邮件,邀请我去面试一下阿里巴巴。

我当时都分不清淘宝和支付宝。和阿里的面试官聊完,几个感觉印象特别深刻。

首先,他们从头到尾没有问我学历;第二,他们没问我会不会这个,会不会那个,感觉特别被尊重;第三,招聘专场上挂着一句话:If not me, who? If not now, when?

当时立马被这种燃烧感击中,一种找到组织,确认他们就是自己人的感觉。

去杭州报到,第一件事情是办手续,HR要給大家建档,好多人用塑料袋装了一堆毕业证书和等级认证什么的,就我两手空荡荡的,后来发现班上还有一个同学也是两手空空。

我当时暗想,阿里真是不拘一格招人才啊。那位同学花名阿玺,也是个80后,现在是蚂蚁副CTO,阿里巴巴最年轻合伙人。

培训完被师傅领去工位,隔壁就坐着鲁肃(现蚂蚁金服CTO)和老苗(现支付宝事业群总裁)。当时鲁肃正在工位上吭哧吭哧写代码,站起来很客气地跟我握了个手。我当时也搞不清这个人是干嘛的。

我很快发现,在这里,我遇到高手了。

鲁肃和老苗这些技术大神两根烟就抽明白的事情,我可能要花两个礼拜还没搞明白。我不懂就问,跟大家一起通宵,困了和大家一起到楼道抽口烟,边吃行政妹子送来的豆浆油条。

一个很强烈的感觉是,我的人生被这帮像打了鸡血一样的人一头撞开了一扇窗。我爸要是当时看到我像海绵一样的学习状态肯定也会吓一跳,毕竟早已习惯儿子学渣好多年了。

4、入职责阿里巴巴背后的故事

当时HR为了吸引许寄加入支付宝,还给出了三点理由。第一,杭州工作离许寄的安徽老家更近,更方便回家。第二,杭州的物价水平比深圳低。第三,杭州的工作强度肯定没有深圳强。

再后来,许寄就以P5的层级加入了支付宝,那一年他23岁。加入支付宝后,他经历了支付宝核心系统架构的演进过程,参与了几乎所有重大项目的建设,带领团队规划建设了支付宝三代统一支付平台、会计核算平台等,完成了支付平台向高可用、可持续性伸缩的架构转型,支撑了支付业务的高速发展。

现在再提及他加入公司之初的那一段经历,许寄笑称自己当时是受骗了:“说是杭州离家近,但事实上每年回家也就一两次。可能杭州的平均工作强度确实没有深圳高,但这不等于阿里的工作强度不大啊。现在想想自己就是被忽悠过来的。“但是真正加入支付宝之后,大家往往都乐在其中,没有人会去想工作强度这回事。

他也分享说,刚加入公司的那几年是他最纯粹的做技术的时光。彼时支付宝技术团队加起来只有六七十号人,作为一个新人他得以和团队的每个人“拜码头“。入职第一天他的师父就带他见老苗(倪行军,花名苗人凤,现支付宝事业群总裁,大家叫他老苗)、鲁肃(程立,花名鲁肃,现蚂蚁金服CTO兼国际事业群COO,在蚂蚁金服内部被视为技术传说般的存在)。第一次见到鲁肃时鲁肃还在写代码,许寄回忆道:“鲁肃当时还站起来很客气的跟我握个手,当时我还不清楚大家是干什么的。现在新人入职哪有机会能见到传说中的老苗和鲁肃啊。”

5、“被逼着走出舒适区”

2007年加入支付宝是个幸运的时间节点。

那时候,支付宝用户已经过亿,用户数量还在快速飙升。我们做的任何决策,写的每一行代码,会影响到这么多用户,兴奋的同时深感舞台越大,责任也越大。

蚂蚁“既要……又要……还要”的企业文化,是基因决定的。作为一家金融科技公司,它既要互联网的快速交付,又要敏捷迭代的能力,还要给业务足够低的试错成本,同时在技术上不能出错。

作为底层的技术人员,既要负责交付,又要负责线上灭火,还要负责面向未来的技术储备。

我是社招P5入职的公司,这十几年来经历过不断打碎重建的过程。

曾经负责的一个大项目,足足花了两个月时间,自以为代码写得完美得不得了,结果鲁肃用两个小时,删了我三千行代码。心痛得要命,但又心服口服。

后来慢慢发现,在蚂蚁,所有人都会被逼着走出舒适区。因为我们做的事情,在15年前就走进了无人区。脚下是没路的,谁能舒舒服服地在无人区里活下来?

没想更大的挑战还在后面。2012年,我被扔去带国际业务的技术团队,从零开始创业。

过去三年,我们在9个一带一路沿线国家和地区,与当地合作伙伴一起落地了当地版支付宝,成绩听起来是不错,但其实我们每天都在遇山劈山,遇水搭桥。

编者语:

刚到支付宝的时候,许寄正好赶上一代架构到二代架构全面升级的阶段。几年时间内,他从开始的旁观者、学习者,慢慢的到了一个参与者,最终成长为二代三代时候的主导者。许寄表示:在支付宝工作后,整个人的眼界得到了较大的提升,知道了自己所该承担的责任,同时也变得更加自信。他分享道:“什么事情是会让你一直开心愿意做下去?一是有舞台,你愿意去干,有机会让你去干;二是你所从事的工作你确实很喜欢;三是能够收获别人的认可。”而这三点恰巧在支付宝的工作中都一一契合。


6、“技术出海”

东南亚各国合作伙伴的工程师,会轮番到杭州接受我们的技术培训,他们的宗教信仰、生活习惯我们都要照顾。

比如穆斯林同学过来,我们要订好面朝麦加的培训教室,清真食品,以及空出一天五次的礼拜时间。

我们团队不但要英语好,还要能在各种东南亚口音的英语中自由切换。

大家常常是在不同电话会议上,讲完印度英语,到马来西亚英语,到越南英语,到菲律宾英语……有次一个同学中途接了家人打来的电话,立马从印尼英语切换回东北话。

▲ 蚂蚁工程师在菲律宾与当地小伙伴们一起过生日

我们团队的工程师,是base在飞机上的一群人。

我们现在去东南亚,就跟出浙江省一样,每个人的护照都盖满了戳,根本用不到十年就要换。

我们的旅行箱里,必备几样东西:老干妈,转换插头,东南亚各国的电话卡;当地合作伙伴的工牌,每张都会标清楚哪个国家,哪幢楼,哪一层。每天一早醒来,得先定定神,想想今天自己是在新加坡还是越南。

虽然说起来都是泪,但比起成就感来,这些都算不上什么,真的。

东南亚都是现金大国,我们刚去的时候,钱包里鼓鼓囊囊地要装着各个国家的纸币,三年下来,我们的钱包在变薄变轻。

说白了,我们这一生,要找一个能够谋生的工作很容易,想找一家收入高的公司努力努力也能实现,但找到一个可以和一群非凡的人一起改变世界的舞台,真不多。

编者语:

经过五年的时间,由许寄负责的支付宝三代架构步入正轨。2012年5月,许寄几乎是单枪匹马的被“扔”到了国际业务。那个时候还没有蚂蚁国际事业部,他在这里的工作当于从零开始的创业过程,最开始是从集团电商支付业务开始接手,把集团大大小小的业务给承担起来,支持阿里的跨境电商业务。再后来,蚂蚁金服国际事业部建立,隶属于国际事业部的这支技术团队就变成了蚂蚁整个大技术平台的一个二级团队。随着业务发展的逐步壮大,大家意识到国际事业部的这支技术团队的技术体系和蚂蚁大技术平台的其他团队很不一样,它麻雀虽小但是五脏俱全。如今,许寄带领的国际事业群技术团队人数已接近千人,变成了蚂蚁金服国际事业群的专属团队。

在许寄及其团队的努力下,目前蚂蚁金服已经在9个国家和地区找到合作伙伴开发电子钱包,包括印度、泰国、印尼、韩国、马来西亚、菲律宾、巴基斯坦、中国香港和孟加拉。而这9个本地电子钱包中,做的最早目前也最成熟的是印度的Paytm。从2015年初到现在,Paytm用户从2300万上升为2.5亿,跃升为全球第三大电子钱包。印度用户可以用手机线上线下支付、转账、理财等。

▲ 印度Paytm

就在2018年6月5日,全球首个基于区块链的电子钱包跨境汇款服务在香港上线。港版支付宝AlipayHK的用户可以通过区块链技术向菲律宾钱包Gcash汇款。第一笔汇款由在港工作22年的菲律宾人格蕾丝(Grace)完成,耗时仅3秒,而在以前需要10分钟到几天不等,还要去线下网点排队。

▲ 区块链跨境汇款现场

7、一个技术人最简单的情怀

谈及接下来的工作规划,许寄表示将继续奋战在国际一线战场上。许寄及其团队是base在飞机上的一群人。夸张的时候,许寄几乎每天早上醒来都在与东南亚的不同国家进行本地沟通和支持。这个团队每个人的护照都盖满了戳,根本用不到十年就要换。他们的旅行箱里,必备几样东西:老干妈;转换插头,东南亚各国的电话卡;当地合作伙伴的工牌,每张都会标清楚哪个国家,哪幢楼,哪一层;每天一早醒来,先定定神,想想自己是在新加坡还是越南……

▲ 许寄及团队成员的护照,戳已经盖不下了

最后,许寄引用阿里巴巴合伙人王帅的一句话送给现在的年轻人:“对于年轻人来讲,舞台很重要。要是没有这么广阔的舞台,何处安放我们这么不安于平凡的灵魂?”

附录:更多感悟和思考文章

一个微信实习生自述:我眼中的微信开发团队

微信程序员创业总结:如何提高Android开发效率

如何做一个合格的 iOS Team Leader

程序员中年危机:拿什么拯救你,我的三十五岁

一个魔都程序员的3年:从程序员到CTO的历练

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

致我们再也回不去的 Github ...

一名90后二流大学程序员的自述:我是如何从“菜鸟”到“辣鸡”的

一个魔都程序员的3年:从程序员到CTO的历练

选择比努力更重要:我是如何从流水线工人到程序员的?

程序员的抉择:必须离开帝都——因为除了工作机会,还有什么值得留恋?

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

干了这碗鸡汤:从理发店小弟到阿里P10技术大牛

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

posted @ 2018-07-09 11:52 Jack Jiang 阅读(57) | 评论 (0)编辑 收藏

1、引言

本文接上篇《脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手》,继续脑残式的网络编程知识学习 ^_^。

套接字socket是大多数程序员都非常熟悉的概念,它是计算机网络编程的基础,TCP/UDP收发消息都靠它。我们熟悉的web服务器底层依赖它,我们用到的MySQL关系数据库、Redis内存数据库底层依赖它。我们用微信和别人聊天也依赖它,我们玩网络游戏时依赖它,读者们能够阅读这篇文章也是因为有它在背后默默地支持着网络通信。

本篇文章依然尝试使用动画图片的方式,来对这个知识点进行“脑残式”讲解(哈哈),期望读者们可以更加简单、直观地理解Socket通信的数据读写本质。

友情提示:如果您的网速较慢,加载gif动画可能较慢,请耐心等候哦。

学习交流:

- 即时通讯开发交流3群:185926912[推荐]

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

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

2、关于作者

钱文品(老钱):毕业于华中科技大学计算机科学与技术专业,互联网分布式高并发技术十年老兵,目前任掌阅科技资深后端工程师。熟练使用 Java、Python、Golang 等多种计算机语言,开发过游戏,制作过网站,写过消息推送系统和MySQL 中间件,实现过开源的 ORM 框架、Web 框架、RPC 框架等。

作者的Github: https://github.com/pyloque

3、系列文章

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

脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?》(本文)

4、Socket读写的简单过程理解

当客户端和服务器使用TCP协议进行通信时,客户端封装一个请求对象req,将请求对象req序列化成字节数组,然后通过套接字socket将字节数组发送到服务器,服务器通过套接字socket读取到字节数组,再反序列化成请求对象req,进行处理,处理完毕后,生成一个响应对应res,将响应对象res序列化成字节数组,然后通过套接字将自己数组发送给客户端,客户端通过套接字socket读取到自己数组,再反序列化成响应对象。

通信框架往往可以将序列化的过程隐藏起来,我们所看到的现象就是上图所示,请求对象req和响应对象res在客户端和服务器之间跑来跑去。

也许你觉得这个过程还是挺简单的,很好理解,但是实际上背后发生的一系列事件超出了你们中大多数人的想象。通信的真实过程要比上面的这张图复杂太多。你也许会问,我们需要了解的那么深入么,直接拿来用不就可以了么?

在互联网技术服务行业工作多年的经验告诉我,如果你对底层机制不了解,你就会不明白为什么对套接字socket的读写会出现各种奇奇乖乖的问题,为什么有时会阻塞,有时又不阻塞,有时候还报错,为什么会有粘包半包问题,NIO具体又是什么,它是什么特别新鲜的技术么?对于这些问题的理解都需要你了解底层机制。

5、Socket读写的细节过程分析

为了方便大家对通信底层的理解,我花了些时间做了下面这个动画,它并不能完全覆盖底层细节的全貌,但是对于理解套接字的工作机制已经足够了。请读者仔细观察这个动画,后面的讲解将围绕着这个动画展开。

我们平时用到的套接字其实只是一个引用(一个对象ID),这个套接字对象实际上是放在操作系统内核中。这个套接字对象内部有两个重要的缓冲结构,一个是读缓冲(read buffer),一个是写缓冲(write buffer),它们都是有限大小的数组结构。

当我们对客户端的socket写入字节数组时(序列化后的请求消息对象req),是将字节数组拷贝到内核区套接字对象的write buffer中,内核网络模块会有单独的线程负责不停地将write buffer的数据拷贝到网卡硬件,网卡硬件再将数据送到网线,经过一些列路由器交换机,最终送达服务器的网卡硬件中。

同样,服务器内核的网络模块也会有单独的线程不停地将收到的数据拷贝到套接字的read buffer中等待用户层来读取。最终服务器的用户进程通过socket引用的read方法将read buffer中的数据拷贝到用户程序内存中进行反序列化成请求对象进行处理。然后服务器将处理后的响应对象走一个相反的流程发送给客户端,这里就不再具体描述。

5.1 细节过程:阻塞

我们注意到write buffer空间都是有限的,所以如果应用程序往套接字里写的太快,这个空间是会满的。一旦满了,写操作就会阻塞,直到这个空间有足够的位置腾出来。不过有了NIO(非阻塞IO),写操作也可以不阻塞,能写多少是多少,通过返回值来确定到底写进去多少,那些没有写进去的内容用户程序会缓存起来,后续会继续重试写入。

同样我们也注意到read buffer的内容可能会是空的。这样套接字的读操作(一般是读一个定长的字节数组)也会阻塞,直到read buffer中有了足够的内容(填充满字节数组)才会返回。有了NIO,就可以有多少读多少,无须阻塞了。读不够的,后续会继续尝试读取。

5.2 细节过程:ack

那上面这张图就展现了套接字的全部过程么?显然不是,数据的确认过程(ack)就完全没有展现。比如当写缓冲的内容拷贝到网卡后,是不会立即从写缓冲中将这些拷贝的内容移除的,而要等待对方的ack过来之后才会移除。如果网络状况不好,ack迟迟不过来,写缓冲很快就会满的。

5.3 细节过程:包头

细心的同学可能注意到图中的消息req被拷贝到网卡的时候变成了大写的REQ,这是为什么呢?因为这两个东西已经不是完全一样的了。内核的网络模块会将缓冲区的消息进行分块传输,如果缓冲区的内容太大,是会被拆分成多个独立的小消息包的。并且还要在每个消息包上附加上一些额外的头信息,比如源网卡地址和目标网卡地址、消息的序号等信息,到了接收端需要对这些消息包进行重新排序组装去头后才会扔进读缓冲中。这些复杂的细节过程就非常难以在动画上予以呈现了。

5.4 细节过程:速率

还有个问题那就是如果读缓冲满了怎么办,网卡收到了对方的消息要怎么处理?一般的做法就是丢弃掉不给对方ack,对方如果发现ack迟迟没有来,就会重发消息。那缓冲为什么会满?是因为消息接收方处理的慢而发送方生产的消息太快了,这时候tcp协议就会有个动态窗口调整算法来限制发送方的发送速率,使得收发效率趋于匹配。如果是udp协议的话,消息一丢那就彻底丢了。

网络协议内部实现还有更多复杂的细节有待继续挖掘,留着以后继续分析吧。

附录1:同类文章精选

如果您觉得本系列文章过于基础,您可直接阅读以下系列:

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

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

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

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

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

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

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

《不为人知的网络编程》系列文章为高阶必读,该系列目录如下:

不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)

不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)

不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT

不为人知的网络编程(四):深入研究分析TCP的异常关闭

不为人知的网络编程(五):UDP的连接性和负载均衡

不为人知的网络编程(六):深入地理解UDP协议并用好它

关于移动端网络特性及优化手段的总结性文章请见:

现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障

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

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

附录2:参考资料

TCP/IP详解 - 第11章·UDP:用户数据报协议

TCP/IP详解 - 第17章·TCP:传输控制协议

TCP/IP详解 - 第18章·TCP连接的建立与终止

TCP/IP详解 - 第21章·TCP的超时与重传

通俗易懂-深入理解TCP协议(上):理论基础

通俗易懂-深入理解TCP协议(下):RTT、滑动窗口、拥塞处理

理论经典:TCP协议的3次握手与4次挥手过程详解

理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程

计算机网络通讯协议关系图(中文珍藏版)

高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少

高性能网络编程(二):上一个10年,著名的C10K并发连接问题

高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了

高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索

简述传输层协议TCP和UDP的区别

为什么QQ用的是UDP协议而不是TCP协议?

移动端即时通讯协议选择:UDP还是TCP?

技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)

UDP中一个包的大小最大能多大?

Java新一代网络编程模型AIO原理及Linux系统AIO介绍

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

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

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

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

P2P技术详解(一):NAT详解——详细原理、P2P简介

P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解

P2P技术详解(三):P2P技术之STUN、TURN、ICE详解

通俗易懂:快速理解P2P技术中的NAT穿透原理

>> 更多同类文章 ……

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

posted @ 2018-07-05 14:19 Jack Jiang 阅读(93) | 评论 (0)编辑 收藏

、引言

网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一。很多读者都知道“三次”和“四次”,但是如果问深入一点,他们往往都无法作出准确回答。

本篇文章尝试使用动画图片的方式,来对这个知识点进行“脑残式”讲解(哈哈),期望读者们可以更加简单、直观地理解TCP网络通信交互的本质。

另外,社区里的另两篇文章《理论经典:TCP协议的3次握手与4次挥手过程详解》、《理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程》也是不错的入门文章,有兴趣可一并详读之。

友情提示:因本文gif动画较多,如果您的网速较慢,请耐心等候图片加载完成哦。

学习交流:

- 即时通讯开发交流3群:185926912[推荐]

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

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

2、关于作者

钱文品(老钱):毕业于华中科技大学计算机科学与技术专业,互联网分布式高并发技术十年老兵,目前任掌阅科技资深后端工程师。熟练使用 Java、Python、Golang 等多种计算机语言,开发过游戏,制作过网站,写过消息推送系统和MySQL 中间件,实现过开源的 ORM 框架、Web 框架、RPC 框架等。

作者的Github: https://github.com/pyloque

3、系列文章

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

脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手》(本文)

《脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?》

4、TCP 三次握手:“Say hello !”

TCP 三次握手就好比两个人在街上隔着50米看见了对方,但是因为雾霾等原因不能100%确认,所以要通过招手的方式相互确定对方是否认识自己。

张三首先向李四招手(syn),李四看到张三向自己招手后,向对方点了点头挤出了一个微笑(ack)。张三看到李四微笑后确认了李四成功辨认出了自己(进入estalished状态)。

但是李四还有点狐疑,向四周看了一看,有没有可能张三是在看别人呢,他也需要确认一下。所以李四也向张三招了招手(syn),张三看到李四向自己招手后知道对方是在寻求自己的确认,于是也点了点头挤出了微笑(ack),李四看到对方的微笑后确认了张三就是在向自己打招呼(进入established状态)。

于是两人加快步伐,走到了一起,相互拥抱。

我们看到这个过程中一共是四个动作,张三招手--李四点头微笑--李四招手--张三点头微笑。其中李四连续进行了2个动作,先是点头微笑(回复对方),然后再次招手(寻求确认),实际上可以将这两个动作合一,招手的同时点头和微笑(syn+ack)。于是四个动作就简化成了三个动作,张三招手--李四点头微笑并招手--张三点头微笑。这就是三次握手的本质,中间的一次动作是两个动作的合并。

我们看到有两个中间状态,syn_sent和syn_rcvd,这两个状态叫着「半打开」状态,就是向对方招手了,但是还没来得及看到对方的点头微笑。syn_sent是主动打开方的「半打开」状态,syn_rcvd是被动打开方的「半打开」状态。客户端是主动打开方,服务器是被动打开方。

syn_sent: syn package has been sent

syn_rcvd: syn package has been received

5、握手完成:开始TCP 数据传输

TCP 数据传输就是两个人隔空对话,差了一点距离,所以需要对方反复确认听见了自己的话。

张三喊了一句话(data),李四听见了之后要向张三回复自己听见了(ack)。

如果张三喊了一句,半天没听到李四回复,张三就认为自己的话被大风吹走了,李四没听见,所以需要重新喊话,这就是tcp重传。

也有可能是李四听到了张三的话,但是李四向张三的回复被大风吹走了,以至于张三没听见李四的回复。张三并不能判断究竟是自己的话被大风吹走了还是李四的回复被大风吹走了,张三也不用管,重传一下就是。

既然会重传,李四就有可能同一句话听见了两次,这就是「去重」。「重传」和「去重」工作操作系统的网络内核模块都已经帮我们处理好了,用户层是不用关心的。

张三可以向李四喊话,同样李四也可以向张三喊话,因为tcp链接是「双工的」,双方都可以主动发起数据传输。不过无论是哪方喊话,都需要收到对方的确认才能认为对方收到了自己的喊话。

张三可能是个高射炮,一说连说了八句话,这时候李四可以不用一句一句回复,而是连续听了这八句话之后,一起向对方回复说前面你说的八句话我都听见了,这就是批量ack。但是张三也不能一次性说了太多话,李四的脑子短时间可能无法消化太多,两人之间需要有协商好的合适的发送和接受速率,这个就是「TCP窗口大小」。

网络环境的数据交互同人类之间的对话还要复杂一些,它存在数据包乱序的现象。同一个来源发出来的不同数据包在「网际路由」上可能会走过不同的路径,最终达到同一个地方时,顺序就不一样了。操作系统的网络内核模块会负责对数据包进行排序,到用户层时顺序就已经完全一致了。

6、TCP 四次挥手:“Say goodbye!”

TCP断开链接的过程和建立链接的过程比较类似,只不过中间的两部并不总是会合成一步走,所以它分成了4个动作,张三挥手(fin)——李四伤感地微笑(ack)——李四挥手(fin)——张三伤感地微笑(ack)。

之所以中间的两个动作没有合并,是因为tcp存在「半关闭」状态,也就是单向关闭。张三已经挥了手,可是人还没有走,只是不再说话,但是耳朵还是可以继续听,李四呢继续喊话。等待李四累了,也不再说话了,超张三挥了挥手,张三伤感地微笑了一下,才彻底结束了。

上面有一个非常特殊的状态time_wait,它是主动关闭的一方在回复完对方的挥手后进入的一个长期状态,这个状态标准的持续时间是4分钟,4分钟后才会进入到closed状态,释放套接字资源。不过在具体实现上这个时间是可以调整的。

它就好比主动分手方要承担的责任,是你提出的要分手,你得付出代价。这个后果就是持续4分钟的time_wait状态,不能释放套接字资源(端口),就好比守寡期,这段时间内套接字资源(端口)不得回收利用。

它的作用是重传最后一个ack报文,确保对方可以收到。因为如果对方没有收到ack的话,会重传fin报文,处于time_wait状态的套接字会立即向对方重发ack报文。

同时在这段时间内,该链接在对话期间于网际路由上产生的残留报文(因为路径过于崎岖,数据报文走的时间太长,重传的报文都收到了,原始报文还在路上)传过来时,都会被立即丢弃掉。4分钟的时间足以使得这些残留报文彻底消逝。不然当新的端口被重复利用时,这些残留报文可能会干扰新的链接。

4分钟就是2个MSL,每个MSL是2分钟。MSL就是maximium segment lifetime——最长报文寿命。这个时间是由官方RFC协议规定的。至于为什么是2个MSL而不是1个MSL,我还没有看到一个非常满意的解释。

四次挥手也并不总是四次挥手,中间的两个动作有时候是可以合并一起进行的,这个时候就成了三次挥手,主动关闭方就会从fin_wait_1状态直接进入到time_wait状态,跳过了fin_wait_2状态。

7、本文小结

TCP状态转换是一个非常复杂的过程,本文仅对一些简单的基础知识点进行了类比讲解。关于TCP的更多知识还需要读者去搜寻相关技术文章进入深入学习。如果读者对TCP的基础知识掌握得比较牢固,高级的知识理解起来就不会太过于吃力。

附录1:同类文章精选

如果您觉得本系列文章过于基础,您可直接阅读以下系列:

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

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

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

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

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

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

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

《不为人知的网络编程》系列文章为高阶必读,该系列目录如下:

不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)

不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)

不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT

不为人知的网络编程(四):深入研究分析TCP的异常关闭

不为人知的网络编程(五):UDP的连接性和负载均衡

不为人知的网络编程(六):深入地理解UDP协议并用好它

关于移动端网络特性及优化手段的总结性文章请见:

现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障

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

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

附录2:参考资料

TCP/IP详解 - 第11章·UDP:用户数据报协议

TCP/IP详解 - 第17章·TCP:传输控制协议

TCP/IP详解 - 第18章·TCP连接的建立与终止

TCP/IP详解 - 第21章·TCP的超时与重传

通俗易懂-深入理解TCP协议(上):理论基础

通俗易懂-深入理解TCP协议(下):RTT、滑动窗口、拥塞处理

理论经典:TCP协议的3次握手与4次挥手过程详解

理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程

计算机网络通讯协议关系图(中文珍藏版)

高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少

高性能网络编程(二):上一个10年,著名的C10K并发连接问题

高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了

高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索

简述传输层协议TCP和UDP的区别

为什么QQ用的是UDP协议而不是TCP协议?

移动端即时通讯协议选择:UDP还是TCP?

技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)

UDP中一个包的大小最大能多大?

Java新一代网络编程模型AIO原理及Linux系统AIO介绍

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

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

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

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

P2P技术详解(一):NAT详解——详细原理、P2P简介

P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解

P2P技术详解(三):P2P技术之STUN、TURN、ICE详解

通俗易懂:快速理解P2P技术中的NAT穿透原理

>> 更多同类文章 ……

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

posted @ 2018-07-04 14:49 Jack Jiang 阅读(102) | 评论 (0)编辑 收藏

     摘要: 注:本文原题《微信的操作系统之路》,来自2018年6月23日的创投理想国线下嘉宾陆树燊的分享会总结(原分享四万余字,本文删减至六千字精华),发表于陆树燊的公众号“行者慎思”。1、引言这些年来,中国互联网很少有像微信这样影响巨大的产品。因此,今天我想基于微信发展过程中的关键决策,提供一些思考。我会从四个部分分析它:1)用户在微信发展早期对它的定位:聊天工具;2)本周引发最多讨...  阅读全文

posted @ 2018-07-02 15:28 Jack Jiang 阅读(27) | 评论 (0)编辑 收藏

     摘要: 本文原作者:“水晶虾饺”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动。1、引言好多小白初次接触即时通讯(比如:IM或者消息推送应用)时,总是不能理解Web短连接(就是最常见的HTTP通信了)跟长连接(主要指TCP、UDP协议实现的socket通信,当然HTML5里的Webs...  阅读全文

posted @ 2018-06-29 17:19 Jack Jiang 阅读(591) | 评论 (0)编辑 收藏

     摘要: 本文原作者阮一峰,作者博客:ruanyifeng.com。1、引言HTTP 协议是最重要的互联网基础协议之一,它从最初的仅为浏览网页的目的进化到现在,已经是短连接通信的事实工业标准,最新版本 HTTP/2 更是让它再次成为技术热点。作为即时通讯开发者来说,深刻理解HTTP协议有助于在现今复杂移动网络环境下的优化和最佳实践的开展,本文将通俗易懂的地介绍 HTTP 协议的历史演变和设计思路。学习交流:...  阅读全文

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

     摘要: 本文由腾讯云技术团队原创,感谢作者的分享。1、前言微信小程序提供了一套在微信上运行小程序的解决方案,有比较完整的框架、组件以及 API,在这个平台上面的想象空间很大。腾讯云研究了一番之后,发现微信支持 WebSocket 还是很值得玩味的。这个特性意味着我们可以做一些实时同步或者协作的小程序。这篇文章分享了一个基于WebSocket长连接的微信小程序——简单的剪刀石头布小游...  阅读全文

posted @ 2018-06-25 15:46 Jack Jiang 阅读(62) | 评论 (0)编辑 收藏

     摘要: 原作者:阮一峰(ruanyifeng.com),现重新整理发布,感谢原作者的无私分享。1、引言今天中午,我突然想搞清楚 Unicode 和 UTF-8 之间的关系,就开始查资料。这个问题比我想象的复杂,午饭后一直看到晚上9点,才算初步搞清楚。下面就是我的总结,主要用来整理自己的思路。我尽量写得通俗易懂,希望能对其他朋友有用。毕竟,字符编码是计算机技术的基石,对于程序员来说尤其重要,字符编码的知识是...  阅读全文

posted @ 2018-06-21 16:32 Jack Jiang 阅读(559) | 评论 (0)编辑 收藏

     摘要: 本文引用了刘欣的文章,感谢原作者的分享。1、引言Http协议在现今主流的IM系统中拥有无可替代的重要性(在IM系统中用HTTP发起的连接被大家简称为http短连接),但Http作为传统互联网信息交换技术,一些典型的概念比如:Session、Token,对于新手程序员来说很陌生。很多文章动辄长篇大论、高屋建瓴地从底层协议再到上层分布式应用式的讲解,根本不适合傻白甜程序员,本文的写作目的是以最白话地方...  阅读全文

posted @ 2018-06-19 11:27 Jack Jiang 阅读(477) | 评论 (0)编辑 收藏

     摘要: 本文引用了自简书作者“涤生_Woo”的文章,内容有删减,感谢原作者的分享。1、前言HTTP(全称超文本传输协议,英文全称HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。对于移动端即时通讯(尤其IM应用)来说,现今主流的数据通信总...  阅读全文

posted @ 2018-06-15 17:46 Jack Jiang 阅读(63) | 评论 (0)编辑 收藏

     摘要: 1、前言在IM这种讲究高并发、高消息吞吐的互联网场景下,MQ消息中间件是个很重要的基础设施,它在IM系统的服务端架构中担当消息中转、消息削峰、消息交换异步化等等角色,当然MQ消息中间件的作用远不止于此,它的价值不仅仅存在于技术上,更重要的是改变了以往同步处理消息的思路(比如进行IM消息历史存储时,传统的信息系统作法可能是收到一条消息就马上同步存入数据库,这种作法在小并发量的情况下可以很好的工作,但...  阅读全文

posted @ 2018-06-12 15:13 Jack Jiang 阅读(564) | 评论 (0)编辑 收藏

     摘要: 1、前言有人说 2017 年是 WebRTC 的转折之年,2018 年将是 WebRTC 的爆发之年,这并非没有根据。就在去年(2017年),WebRTC 1.0 标准草案出炉(实际上WebRTC标准草案的早期版本早在2011年就已经发布,WebRTC并非一夜之间就出现的技术),并将于今年正式发布。与此同时,越来越多的浏览器和厂商都开始对它进行广泛的支持,WebRTC 即将成为互联网的基础设施了,...  阅读全文

posted @ 2018-06-04 12:25 Jack Jiang 阅读(50) | 评论 (0)编辑 收藏

     摘要: 本文原作者: 夏之南,感谢原作者的分享。1、前言不知不觉,微信已经诞生七年了。 从第一版到现在,微信的演变史,很像一部创业史,很好地诠释了创业者能经得起多少质疑和差评,才配拥有多大的成功。编者注:微信作为移动端IM的标杆,无论是产品定义还是技术追求(关于微信团队对技术的极致追求,可以在即时通讯网找到很多微信团队分享的文章,从文字中完全可以理解微信团队的技术追求),都值得广大即时通讯技术开发者学习。...  阅读全文

posted @ 2018-05-30 13:27 Jack Jiang 阅读(33) | 评论 (0)编辑 收藏

     摘要: 本文来自七牛云Android 多媒体开发工程师卢俊的技术分享,即时通讯网有改动。1、前言这是由一篇我的演讲稿整理出来的文章,目标读者是对实时音视频开发感兴趣但是又不知道如何下手的初学者们,希望把我的经验分享出来,对大家有所帮助。学习交流:- 即时通讯开发交流3群:185926912[推荐]- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》(本文同步发布于:http://www.5...  阅读全文

posted @ 2018-05-28 12:16 Jack Jiang 阅读(367) | 评论 (0)编辑 收藏

     摘要: 1、前言IM的群聊消息,究竟存1份(即扩散读方式)还是存多份(即扩散写方式)?上一篇文章《IM群聊消息的已读回执功能该怎么实现?》是说,“很容易想到,是存一份”,被网友们骂了,大家争论的很激烈(见下图)。 网友骂的对,任何技术方案,都不是天才般灵感乍现想到的,一定是一个演进迭代,逐步优化的过程。今天就聊一聊,IM群聊消息,为啥只需要存一份。不过,从公开的技术资料来...  阅读全文

posted @ 2018-05-25 12:25 Jack Jiang 阅读(283) | 评论 (0)编辑 收藏

     摘要: 本文引用了架构师之路公众号作者沈剑的文章,内容有改动,感谢原作者。1、前言我们平时在使用即时通讯应用时候,每当发出一条聊天消息,都希望对方尽快看到,并尽快回复,但对方到底有没有真的看到?我却并不知道。一个残酷的现实是,很多时候对方其实是早就已经看到了这条消息,但出出种种原因(大家都懂的),通常都是默默返回——假装没看见。像微信这样的熟人社交工具,在产品的设计理念上,为了保持...  阅读全文

posted @ 2018-05-23 12:49 Jack Jiang 阅读(356) | 评论 (0)编辑 收藏

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