消息队列高手课
李玥
京东零售技术架构部资深架构师
立即订阅
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讲)
结束语 | 程序员如何构建知识体系?
消息队列高手课
登录|注册

12 | 序列化与反序列化:如何通过网络传输结构化的数据?

李玥 2019-08-17
你好,我是李玥。
最近有一些同学留言说,感觉这几节课讲的内容和消息关系不大。这里我解释一下,因为我们课程其中的一个目的,是让同学们不仅会使用消息队列,还可以通过对消息队列的学习,在代码能力上有一个提升,具备“造轮子”的能力。这样,你对消息队列的理解才能足够的深入,而不只是浮于表面。如果你细心可能也会发现,很多大厂在面试时,提到消息队列的问题,也不会仅仅局限在消息队列的使用上,他更多的会考察“你为什么这么实现”。
所以在进阶篇的上半部分,我会把开发一个消息队列需要用到的一些底层的关键技术给大家讲解清楚,然后我们再来一起分析消息队列的源代码。
在上节课中,我们解决了如何实现高性能的网络传输的问题。那是不是程序之间就可以通信了呢?这里面还有一些问题需要解决。
我们知道,在 TCP 的连接上,它传输数据的基本形式就是二进制流,也就是一段一段的 1 和 0。在一般编程语言或者网络框架提供的 API 中,传输数据的基本形式是字节,也就是 Byte。一个字节就是 8 个二进制位,8 个 Bit,所以在这里,二进制流和字节流本质上是一样的。
那对于我们编写的程序来说,它需要通过网络传输的数据是什么形式的呢?是结构化的数据,比如,一条命令、一段文本或者是一条消息。对应到我们写的代码中,这些结构化的数据是什么?这些都可以用一个类(Class)或者一个结构体(Struct)来表示。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《消息队列高手课》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(31)

  • 👻 小二
    尝试回答一下问题:
    内存里存的东西,不通用, 不同系统, 不同语言的组织可能都是不一样的, 而且还存在很多引用, 指针,并不是直接数据块。
    序列化, 反序列化, 其实是约定一种标准吧, 大家都按这个标准去弄, 就能跨平台 , 跨语言。

    作者回复: 这个总结好,简单明确,赞!

    2019-08-20
    38
  • a、
    1.因为应用程序里的对象,除了属性和属性值以外,还有一些其他的信息,比如jdk编译的版本,类的全限定名,类继承的父类和实现的接口等信息。如果服务端是jdk1.8编译的对象,发给客户端,客户端用的是jdk1.7,肯定会报错。
    2.这些其他的信息是多余的,传输中会增加网络负担
    2019-08-17
    16
  • 游弋云端
    需要面临的问题:
    1、网络字节序与主机字节序问题,业务要感知和处理大小端问题;
    2、平台差异,各平台对基本数据类型的长度定义不一致、结构体对齐策略不一致,无法实现平台兼容;
    3、连续内存问题,一个对象可能引用,指向其他对象,指针就是一个地址,传输后在另外的设备上是无效值;

    如果解决这些问题了,也变相的实现了自己的序列化框架了。
    2019-08-17
    15
  • ly
    个人对今天的内容进行简单的描述:
    1. 序列化:是一种规则,它定义了数据表达的规则;
    2. 反序列化:依靠给定的规则,还原数据。
    3. 今天的问题:
    内存中的对象数据应该具有语言独特性,例如表达相同业务的User对象(id/name/age字段),Java和PHP在内存中的数据格式应该不一样的,如果直接用内存中的数据,可能会造成语言不通。通常两个服务之间没有严格要求语言必须一致,只要对序列化的数据格式进行了协商,任何2个语言直接都可以进行序列化传输、接收。

    作者回复: 👍👍👍

    2019-08-19
    5
  • 许童童
    内存在每个平台的分布都是不一样的,一个对象不光有用户定义的属性,还包括平台定义的属性,如果不经过序列化就传输过去,一方面会浪费大量的带宽,另一方面还可能因为平台不同等问题导致不兼容,从而无法解析。
    2019-08-17
    4
  • 星愿
    Jmq用的啥序列化框架呢

    作者回复: 和其它的MQ的实现是类似的,自身的命令用的专用序列化,消息本身如何序列化是由业务代码决定的。

    2019-10-21
    1
  • Switch
    在内存中,存放的对象也是有相应的结构的。如果直接保存,直接读取,那么也需要有相应的转换器,将数据转换为内存中的对象。而且这样的对象,不通用,换一种语言或者实现就不能通用了,并且这样的对象不一定是最节省空间的。
    我们损失一部分性能,换取跨语言性、节省存储空间也是一种两者取较好的选择。
    2019-10-12
    1
  • 楚翔style
    序列化:把对象转成通用格式数据(byte json)
    反序列化:通用格式转成服务端能认的对象,比如json->Java Object
    2019-08-30
    1
  • godtrue
    课后思考及问题
    1:课后,你可以想一下这个问题:在内存里存放的任何数据,它最基础的存储单元也是二进制比特,也就是说,我们应用程序操作的对象,它在内存中也是使用二进制存储的,既然都是二进制,为什么不能直接把内存中,对象对应的二进制数据直接通过网络发送出去,或者保存在文件中呢?为什么还需要序列化和反序列化呢?
    非常赞,老师的这个问题太经典了,可以拓宽认知边界。
    具有细节,我不清楚,不过大概知道原因,比如:
    1-1:JAVA说01表示TRUE,PHP说01表示我是世界上最好的语言
    1-2:Mac说01表示1,Windows说10表示1
    1-3:虽然0/1在计算机的世界里,可以组合表示万事万物,比如:文字、图片、音频、视频、数据、指令等等,但是不同的语言、操作系统、硬件体系并没有被一个唯一的皇帝统一,他们的标准和存储方式都是有差异性的。所以,字符集有N多种就是这样,同样一个字符0在不同王国有不同的含义。

    2:看了老师的讲解,感觉自己也能自定义一个序列化和反序列化的框架,可能性能、通用性待优化。我的问题是,如果我想自己实现一个这样的框架,该怎么思考才能实现的更好?Jd自研的是怎么思考的?或者换个问法,老师在自研时是怎么考虑和设计的,有什么坑没?性能如何?关键想知道怎么自研的?

    作者回复: 近期会发一个加餐来解答你的问题。

    2019-08-23
    1
    1
  • 南辕北辙
    个人理解,序列化与反序列化的通用思想和通信协议挺类似的,只要通信双方约好什么样的格式去定义数据,想怎么玩就怎么玩。
    2019-08-21
    1
  • Kylin

    03 | 08 7a 68 61 6e 67 73 61 6e | 17 | 01
    User | z h a n g s a n | 23 | true
    类似erlang的序列化方式
    2019-11-26
  • 业余爱好者
    从语义上理解序列化与反序列化,序列化就是把内存中结构化的对象转化为跨平台的可以在网络上传输的二进制“流”。关键词是流,也就是说,它是一个线性的数据结构。而在内存中的数据是结构化的,非线性的,而且各个平台,各种语言的存在方式还不一样。

    序列化就是把要传输的信息从专用的表示方式转换为通用的二进制流的表示方式。反序列化的过程刚好相反。

    虽然都是二进制,不过信息的编码方式不同。
    2019-11-24
  • 淡定的、王先森
    想问下老师,在项目开发中,什么时候需要显式的实现对象的序列化,或者用到序列化?感觉日常开发中并没有涉及,或者应用的框架给做了我并没有察觉到? 大多数项目都是怎么设计序列化的呢?请老师提示或指教下,不胜感激

    作者回复: 你在使用消息队列的时候,发消息之前就需要对消息进行序列化,收到消息再反序列化。

    可能你日常发送的都是String类型的消息,没有意识到?

    比如,你要通过消息发送一个有结构的对象到对端,就需要把这个对象序列化。

    2019-10-27
  • 布小丫学编程
    不知道是什么类型的数据,每个程序对字段的解析规则都不一样。二进制解析都需要自定义好协议后才可以解析的,比如协议头编码格式等等都不一样。
    2019-09-16
  • 毛露
    想到了tcp报文。。
    2019-08-21
  • 青莲
    序列化和反序列化前提条件是,以什么样的格式或约定的协议对内容进行解析,内存中的二进制具有特定语方的协议,只在当前运行的应用环境有效;
    2019-08-20
  • humor
    内存中的对象并不是独立存在的,他们会有各种引用关系,直接存储的话,可能存储的很多都是内存地址吧
    2019-08-19
  • leslie
    打卡:没太想明白,不过问题记在大脑里总归会想出点东西。
    2019-08-19
  • oscarwin
    虽然都是二进制的数据,但是序列化的二进制数据是通过一定的协议将数据字段进行拼接。第一个优势是:不同的语言都可以遵循这种协议进行解析,实现了跨语言。第二个优势是:这种数据可以直接持久化到磁盘,从磁盘读取后也可以通过这个协议解析出来。如果是内存中的数据不能直接存盘的,直接存盘后再读出来我们根本无法辨识这是个什么数据。

    作者回复: 👍

    2019-08-19
  • 💪😊
    内存数据要搭配元数据定义,这个定义在不同语言平台等兼容非常难通用。拿内存本身也不是特别容易的事情
    2019-08-19
收起评论
31
返回
顶部