消息队列高手课
李玥
京东零售技术架构部资深架构师
立即订阅
8426 人已学习
课程目录
已完结 41 讲
0/4登录后,你可以任选4讲全文学习。
课前必读 (2讲)
开篇词 | 优秀的程序员,你的技术栈中不能只有“增删改查”
免费
预习 | 怎样更好地学习这门课?
基础篇 (8讲)
01 | 为什么需要消息队列?
02 | 该如何选择消息队列?
03 | 消息模型:主题和队列有什么区别?
04 | 如何利用事务消息实现分布式事务?
05 | 如何确保消息不会丢失?
06 | 如何处理消费过程中的重复消息?
07 | 消息积压了该如何处理?
08 | 答疑解惑(一) : 网关如何接收服务端的秒杀结果?
进阶篇 (21讲)
09 | 学习开源代码该如何入手?
10 | 如何使用异步设计提升系统性能?
11 | 如何实现高性能的异步网络传输?
12 | 序列化与反序列化:如何通过网络传输结构化的数据?
13 | 传输协议:应用程序之间对话的语言
14 | 内存管理:如何避免内存溢出和频繁的垃圾回收?
加餐 | JMQ的Broker是如何异步处理消息的?
15 | Kafka如何实现高性能IO?
16 | 缓存策略:如何使用缓存来减少磁盘IO?
17 | 如何正确使用锁保护共享数据,协调异步线程?
18 | 如何用硬件同步原语(CAS)替代锁?
19 | 数据压缩:时间换空间的游戏
20 | RocketMQ Producer源码分析:消息生产的实现过程
21 | Kafka Consumer源码分析:消息消费的实现过程
22 | Kafka和RocketMQ的消息复制实现的差异点在哪?
23 | RocketMQ客户端如何在集群中找到正确的节点?
24 | Kafka的协调服务ZooKeeper:实现分布式系统的“瑞士军刀”
25 | RocketMQ与Kafka中如何实现事务?
26 | MQTT协议:如何支持海量的在线IoT设备?
27 | Pulsar的存储计算分离设计:全新的消息队列设计思路
28 | 答疑解惑(二):我的100元哪儿去了?
案例篇 (7讲)
29 | 流计算与消息(一):通过Flink理解流计算的原理
30 | 流计算与消息(二):在流计算中使用Kafka链接计算任务
31 | 动手实现一个简单的RPC框架(一):原理和程序的结构
32 | 动手实现一个简单的RPC框架(二):通信与序列化
33 | 动手实现一个简单的RPC框架(三):客户端
34 | 动手实现一个简单的RPC框架(四):服务端
35 | 答疑解惑(三):主流消息队列都是如何存储消息的?
测试篇 (2讲)
期中测试丨10个消息队列热点问题自测
免费
期末测试 | 消息队列100分试卷等你来挑战!
结束语 (1讲)
结束语 | 程序员如何构建知识体系?
消息队列高手课
登录|注册

13 | 传输协议:应用程序之间对话的语言

李玥 2019-08-20
你好,我是李玥。
经过前面几课的学习,我们已经可以实现高性能的结构化数据传输了。不过,应用程序之间要想互相通信,一起配合来实现业务功能,还需要有一套传输协议来支持。
传输协议就是应用程序之间对话的语言。设计传输协议,并没有太多规范和要求,只要是通信双方的应用程序都能正确处理这个协议,并且没有歧义就好了。
这节课,我们就来说一下设计高性能传输协议的一些方法和技巧。

如何“断句”?

既然传输协议也是一种语言,那么在应用程序之间“通话”的过程中,与我们人类用自然语言沟通有很多相似之处,但是需要处理的问题却又不同。
现代语言,无论是汉语还是英语,都是通过标点符号来分隔句子的,这个叫“断句”。古代汉语是没有标点符号的,断句全靠上下文,但这种断句方式有的时候会出现歧义,比如很著名的那个段子“下雨天留客天天留我不留”,不同的断句方式,意思完全不一样。
我们在传输数据的的时候,首先要解决的就是断句问题。对于传输层来说,收到的数据是什么样的?就是一段一段的字节,但是,因为网络的不确定性,你收到的分段并不一定是我们发出去的分段。比如我们发送的数据是这样的:
下雨天 留客天 天留 我不留
这样断句,意思就是,作为主人我不想让你在我这儿住。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《消息队列高手课》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(32)

  • 滴流乱转小胖子
    没想到老师居然是个相声演员,通俗易懂,点赞
    2019-08-20
    19
  • chon
    第一篇的内容质量很高,第二篇的目前这几篇文章的内容实在是太基础了。不用动脑,跳着看
    2019-08-20
    1
    11
  • Switch
    用 netty 实现了,使用了多种 序列化方式实现,差异还是很大的。写出来和知道怎么做,差距还是非常大的,当完整的写完练习,确实把老师讲到的这些知识点都串起来了。序列化框架的选型及接口设计、通讯协议设计、编解码设计、 netty 服务端客户端的处理。

    代码在该目录下:https://github.com/Switch-vov/mq-learing/tree/master/src/main/java/com/switchvov/network/chat

    整个实现下来,不同的序列化框架,性能差异还是很大的。用 protostuff 性能是最好的。

    麻烦老师看看,哪些地方还能再优化。

    - fastjson
      - 遍历10000次,花费:1400ms
      - 遍历100000次,花费:7272ms
      - 遍历1000000次,花费:86840ms
    - protostuff
      - 遍历10000次,花费:1224ms
      - 遍历100000次,花费:5381ms
      - 遍历1000000次,花费:51677ms
    - kryo
      - 遍历10000次,花费:1307ms
      - 遍历100000次,花费:6774ms
      - 遍历1000000次,花费:102819ms

    作者回复: 代码结构很清晰,值得大家学习。

    优化的建议:可以采用专用序列化方式,另外,你在做测试的时候有没有关闭控制台的打印输出?这个对性能的影响是很大的。

    2019-10-13
    4
  • 刘天鹏
    https://gist.github.com/liutianpeng/85ce524452c8206396c94ab93506deda
    一个"胡同"做中转 两个"大爷"TCP连接到胡同
    我这个版本的胡同效率有点低 大爷相遇1万次就用了 3.8s

    作者回复: 赞分享代码的同学👍👍👍

    2019-08-20
    4
  • 许童童
    跟着老师把这些基础知识打牢,很喜欢老师这种讲课节奏。
    2019-08-20
    4
  • Switch
    看了加餐之后,重构了下执行逻辑。更改一问一答交互为 主客户端同时发送消息。主客户端根据消息类型答复相应内容。

    另外,老师,专用化序列方式在哪能找到借鉴的地方呢?

    是的,没关闭输出。关闭输出后,重新测试后的结果如下:

    - 关闭打印
      - fastjson
        - 遍历10000次,花费:555ms
        - 遍历100000次,花费:2740ms
        - 遍历1000000次,花费:28418ms
      - protostuff
        - 遍历10000次,花费:440ms
        - 遍历100000次,花费:2599ms
        - 遍历1000000次,花费:23991ms
      - kryo
        - 遍历10000次,花费:522ms
        - 遍历100000次,花费:2805ms
        - 遍历1000000次,花费:28130ms
    - 没关闭打印
      - fastjson
        - 遍历10000次,花费:1400ms
        - 遍历100000次,花费:7272ms
        - 遍历1000000次,花费:86840ms
      - protostuff
        - 遍历10000次,花费:1224ms
        - 遍历100000次,花费:5381ms
        - 遍历1000000次,花费:51677ms
      - kryo
        - 遍历10000次,花费:1307ms
        - 遍历100000次,花费:6774ms
        - 遍历1000000次,花费:102819ms

    老师加餐中给的示例代码,在我电脑上 10W 次,在 [8,12]s 这个区间

    代码在该目录下:https://github.com/Switch-vov/mq-learing/tree/master/src/main/java/com/switchvov/network/chat

    作者回复: 可以参考一下加餐这节课中的序列化代码。

    2019-10-14
    1
    2
  • 夜空中最亮的星(华仔)
    京味十足,😄
    2019-08-26
    2
  • oldman
    老师,我理解的双工通信,是不是说不管是客户端还是服务端建立好链接之后,双方都可以基于该socket进行收发消息就好了,而不是说服务器只能accept到message之后再做一些处理。

    作者回复: 是这样的。

    2019-08-23
    2
  • A9
    看了直播,没想到老师你是这样的人 所以,到底谁快?

    作者回复: 同学当然是你最快呀!😏

    2019-08-20
    2
  • 晴空
    老师请教个问题,tcp协议中已经协商好了最大报文长度,应用协议为什么又要设置一下报文长度呢,期待老师帮忙解惑

    作者回复: 需要注意的是,在OSI七层网络协议栈中,tcp协议是四层(传输层)协议,而我们设计的传输协议都是七层(应用层)协议,下层协议对上层来说是透明的。

    通俗的说,tcp包的长度和我们协议中一条消息的长度是完全没有关系的,一个tcp包可能包含n条完整的消息,也可能包含半条消息,或者前后2个半条消息加上中间n条完整的消息,这都是不一定的。

    2019-09-04
    1
  • 宋晓明
    老师,昨天您的直播我看了 但心中一直有个疑问:一般架构师coding能力非常强,尤其是java,现在很多招聘要求都是java架构师,目前本人擅长的语言是python和go,说实话 java虽好,但本人很不喜欢,是不是我与架构师就无缘了??

    作者回复: 跟语言关系不大,其实各种编程语言背后的实现原理都是差不多的。一般的大厂的架构师职位对语言也没有强要求,而且很多架构师都是掌握多门编程语言的。

    2019-08-21
    1
  • linqw
    课后习题用netty做,耗时大致3秒左右,使用LengthFieldBasedFrameDecoder。
    学习完这篇也写下自己的理解,字节流就像流水,为此我们在接收和发送字节流的时候,需要对此进行编码和解码,常见的几种形式1、定长,比如指定固定的长度,解析的时候获取固定的长度为一个完整的语句2、分隔符,比如在发送时,对字节流中使用分隔符分隔完整的语句。3、最常用的一种就是在发送的字节流中,有固定的字节表示长度
    有个疑问,在接收的过程中接收到半包,如何处理了,等待剩余的接收完成么?老师帮忙解答下哦

    作者回复: 是需要等待的,如果你使用Netty,这个问题Netty会帮你处理好。

    2019-08-20
    1
  • 知己逢知遇
    多线程下异步处理一次会话的结果消息体,除了对这次会话的结果消息进行编号,是否也要对分割的消息体进行顺序编号?
    电驴,迅雷,p2p这种软件的消息协议大概是什么样的呢?是不是部分协议跟今天老师讲的情况类似?
    我是不是可以理解为,在双全功下,我和一个网站就可以建立一条长链接,然后所有的资源请求都通过这条链接进行交换,只要协议正确,就可以保证数据的完整性,正常访问并解析打开的该网站的所有页面。
    多线程,异步的io操作,是不是也有自己的协议?

    作者回复: 你需要了解,协议是分层的,就像我们发快递,我发给你的可能是个手机,对于快递小哥来说,这就是个小包裹,他不关心里面是什么,总之我保证给你把包裹安全的送到站点儿就行了。包裹到了站点儿会分拣装箱,然后用小货车运到机场,对于小货车司机来说,它也不关心车里装的是什么,只要把车安全开到机场就行了。

    对于协议来说已是这样在发送的时候一层一层的封装,然后接收的时候再一层一层解封,对于每一层协议来说,他是不知道底层是什么协议的,也不知道上层协议是如何封装的(送件的快递小哥不知道也不关心这个件是怎么到配送站的,也不知道包裹里到底装的啥),只在自己的协议层完成处理即可。

    2019-08-20
    1
  • 冰激凌的眼泪
    看到过tlv的说法: tag length value
    2019-08-20
    1
  • Hurt
    继续 打卡
    2019-08-20
    1
  • 亚洲舞王.尼古拉斯赵四
    老师,因为不是很懂java socket编程,所以想问一下,如果是java实现的话,这个作业是一定用socket或者netty才能写吗?

    作者回复: 不一定非得用netty,使用的语言也不是只能用Java,我在后面《加餐 | JMQ的Broker是如何异步处理消息的?》这节课中,对这个作业,给出了一个用Golang的参考实现,你可以看一下。

    2019-11-07
  • Pitcher
    https://gist.github.com/mrpanc/de206c835abb6a5e9b78c6555b46976d 交一波作业。同步模式,10万次7.463167328s

    作者回复: 👍👍👍

    2019-09-26
  • Pitcher
    老师,请问三个消息是否可以合并到一个请求里面呢?在通信的时候增加一个消息数量,服务端就可以正确解包,然后批量回复了。

    作者回复: 就我们这个题来说,不可以的。

    2019-09-20
  • 颖儿
    老师的课程很生动 为老师打call
    2019-09-02
  • godtrue
    打卡,已经习惯打卡
    这节明白没问题,不过给我的感受是还是基础最重要。
    如果计算机组成原理、操作系统原理、计算机网络原理、数据结构与算法、编译原理这几门课我的基础打的更牢靠一些,极客时间的一些课程就不用买了,至少有些课程听起来就简单多啦!
    这些基础知识才是构建计算机知识大厦的根基。
    总是,感谢玥哥的分享,突然想到为啥公司内部JMQ分享没听过你的呢?
    2019-08-23
收起评论
32
返回
顶部