深入学习Motan系列(五)—— 序列化与编码协议
一、序列化
1.什么是序列化和反序列化?
序列化:将对象变成有序的字节流,里面保存了对象的状态和相关描述信息。
反序列化:将有序的字节流恢复成对象。
一句话来说,就是对象的保存与恢复。
为什么需要这个东西。它的作用呢,就是持久化(比如讲内容保存在计算机上)和进程间传递。因为计算机是二进制的,网络间传输东西也是通过二进制来传递的,所以需要将对象变成bytes再进行传递。
2.序列化的使用
使用序列化的demo,我不写了,网上一堆。里面用到的ObjectOutputStream很重要,我们看看它的介绍(当然去看JDK的文档了,最权威)
地址如下:https://docs.oracle.com/javase/8/docs/api/
中文版:https://blog.fondme.cn/apidoc/jdk-1.8-google/
只用继承了Serializable接口的类才能被写进字节流中(进行序列化),序列化编码时包含的内容有:类名,类签名,对象字段的值和数组,以及初始化对象引用的closure(汉语没想到怎么表达它)。默认的序列化机制可以写入对象,类签名,所有non-transient和non-static的字段。
默认的序列化机制使用:继承Serializable接口,就可以使用了;若是想自定义序列化机制(出于信息安全和效率的目的),需要实现下面的方法:readObject() writeObject()
readObjectNoData()。实现Externalizable接口可以完全控制对象序列化内容和格式(目前,我没见过Externalizable接口,稍后,尝试分析hession序列化协议,看看里面是否会有这个接口)。
3.序列化步骤
序列化算法步骤如下:
◆将对象实例相关的类元数据输出。【元数据】
◆递归地输出类的超类描述直到不再有超类。【超类描述】
◆类元数据完了以后,开始从最顶层的超类开始输出对象实例的实际数据值。【超类-类的实际数据值】
◆从上至下递归输出实例的数据【实例数据值】
(序列化步骤这部分,摘自https://blog.csdn.net/suyebiubiu/article/details/78780941)
4.序列化协议之间比较
推荐文章:https://tech.meituan.com/serialization_vs_deserialization.html
(上面这篇文章写的确实非常好,此外,自己没有用过那么多的序列化协议,它们之间的好坏,无法做出衡量判断。每篇博文的记录,可以看作是知识的分享,更重要的是记录自己学习的脚印)
5.Hession序列化方式
Motan中使用的是Hession协议进行序列化的。接下来,走一遍,看看Hession的使用和里面的东西。
 public class Demo {
     public static void main(String args[]) throws IOException, InstantiationException, IllegalAccessException {
             UserInfo user = new UserInfo();
             user.setUsername("hello world");
             user.setPassword("buzhidao");
             user.setAge(21);
             ByteArrayOutputStream os = new ByteArrayOutputStream();
             //Hessian的序列化输出
             HessianOutput ho = new HessianOutput(os);
         // 关键内容在下面这一行中
             ho.writeObject(user);
             byte[] userByte = os.toByteArray();
             ByteArrayInputStream is = new ByteArrayInputStream(userByte);
             //Hessian的反序列化读取对象
             HessianInput hi = new HessianInput(is);
             UserInfo u = (UserInfo) hi.readObject();
             System.out.println("姓名:" + u.getUsername());
             System.out.println("年龄:" + u.getAge());
     }
      }
ho.writeObject(user);
public void writeObject(Object object)
throws IOException
{
if (object == null) {
writeNull();
return;
} Serializer serializer;
10 // 这里是一个工厂方法,依据被序列化内容的不同(是int,还是String,是long,还是其他Object,.etc)来选择合适的序列化器
// 最后经过一系列的处理,返回UnsafeSerializer
serializer = _serializerFactory.getSerializer(object.getClass()); serializer.writeObject(object, this);
}
然后,来到下面的处理(中间过程代码有省略)
protected void writeObject10(Object obj, AbstractHessianOutput out)
throws IOException
{
for (int i = 0; i < _fields.length; i++) {
// 利用前面初始化时,已经确认的字段对应的序列化器,分别对字段的值进行序列化
// 比如,String类型的字段,用StringFieldSerializer序列化器来处理
Field field = _fields[i]; out.writeString(field.getName()); _fieldSerializers[i].serialize(out, obj);
} out.writeMapEnd();
}
到这里,基本算是完成序列化的过程。我们看到的很简单,其实,内部的对底层的处理比较复杂,比如,序列化时,如何生成体积更小的byte,到底为什么速度更快等。这些问题,不在本文讨论范围内。
6.问题
在网上看到一个小列子,代码跟上文中的Demo 代码一样,区别在与:父类有三个属性,子类有一个同名属性。
 public class UserInfo extends User {     private String username ;
 }
 public class User implements Serializable {
     private String username ;
     private String password;
     private Integer age;
 }
这样的话,用demo例子进行序列化与反序列化的时候,发现发序列化之后,demo中21行,u.getUsername()的值为null。这个原因不是出在序列化这里,而是由于java内部机制,具体原因正在调查中,有知道的,望前辈赐教。
二、Motan编码协议
首先,复习一下基础知识:
字     word 
字节  byte 
位     bit 
字长是指字的长度
1字节=8位(1 byte = 8bit)           一个字节的字长是8
1字=2字节(1 word = 2 byte)      一个字的字长为16
 -----------------------------------------------------------------------------------
数据协议= 协议头 + 协议体
header:  16个字节 
 0-15 bit     :  magic(魔法数字)
16-23 bit    :  version (版本号)
24-31 bit    :  extend flag , 其中: 29-30 bit: event 可支持4种event,比如normal, exception等,  31 bit : 0 is request , 1 is response 
32-95 bit    :  request id
96-127 bit  :  body content length
body部分就是利用序列化协议将request变成bytes[]
最后,head+body,两者进行结合,通过Netty进行传输。
深入学习Motan系列(五)—— 序列化与编码协议的更多相关文章
- UFLDL深度学习笔记 (五)自编码线性解码器
		UFLDL深度学习笔记 (五)自编码线性解码器 1. 基本问题 在第一篇 UFLDL深度学习笔记 (一)基本知识与稀疏自编码中讨论了激活函数为\(sigmoid\)函数的系数自编码网络,本文要讨论&q ... 
- 深入学习Motan系列(二)——服务发布
		闯关经验: 袋鼠走过了第一关,顺利搭建出了Demo,信心爆棚.不过之后,心想怎么去研究这个框架呢.查了一下,官方文档,好像没什么东西可以研究啊.后来,又搜了搜博客,因为这是微博的框架嘛,所以搜索时用百 ... 
- 深入学习Motan系列(一)——入门及知识zookeeper储备
		背景以及说明: 最近逮到个RPC框架,打算深入学习,框架千千万,只有懂得内部原理,才能应对复杂的业务,进行自定义化系统. 这个系列的Motan文章也是自己慢慢摸索的轨迹,将这个过程记录下来,一是提升自 ... 
- 深入学习Motan系列(四)—— 客户端
		困惑的袋鼠,对框架的把握有些茫然,但是仍然一步步向前,行动总比一直迷茫停止不前要好,您说呢,各位客官? 这篇开始客户端的分析.有些地方的代码,就不每段都标出了,中间有跳跃的地方,请自己对照代码来看.鄙 ... 
- 深入学习Motan系列(三)——服务发布
		袋鼠回头看了看文章,有些啰嗦,争取语音简练,不断提高表达力!袋鼠奋起直追! 注:此篇文章,暂时为了以后时间线排序的需要,暂时发表出来,可是仍然有许多地方需要改写.自己打算把服务端发布,客户端订阅都搞定 ... 
- Windows-universal-samples学习笔记系列五:Custom user interactions
		Custom user interactions Basic input Complex inking Inking Low latency input Simple inking Touch key ... 
- 小白学习Spark系列五:scala解析多级json格式字符串
		一.背景 处理json格式的字符串,key值一定为String类型,但value不确定是什么类型,也可能嵌套json字符串,以下是使用 JSON.parseFull 来解析多层json. 二.实例代码 ... 
- 步步为营 SharePoint 开发学习笔记系列总结
		转:http://www.cnblogs.com/springyangwc/archive/2011/08/03/2126763.html 概要 为时20多天的sharepoint开发学习笔记系列终于 ... 
- scrapy爬虫学习系列五:图片的抓取和下载
		系列文章列表: scrapy爬虫学习系列一:scrapy爬虫环境的准备: http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_00 ... 
随机推荐
- ( 转) Awesome Image Captioning
			Awesome Image Captioning 2018-12-03 19:19:56 From: https://github.com/zhjohnchan/awesome-image-capti ... 
- R语言环境变量的设置 环境设置函数为options()
			环境设置函数为options(),用options()命令可以设置一些环境变量,使用help(options)可以查看详细的参数信息. 1. 数字位数的设置,options(digits=n),n一般 ... 
- Harbor私有仓库中如何彻底删除镜像释放存储空间?
			简介: Harbor私有仓库运行一段时间后,仓库中存有大量镜像,会占用太多的存储空间.直接通过Harbor界面删除相关镜像,并不会自动删除存储中的文件和镜像.需要停止Harbor服务,执行垃圾回收命令 ... 
- 在ionic中使用短信验证码倒计时
			页面上 <button class="code" (click)="getCode()" [disabled]="!verifyCode.dis ... 
- LeetCode--015--三元之和(java)
			给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三元组. ... 
- loj#2059. 「TJOI / HEOI2016」字符串 sam+线段树合并+倍增
			题意:给你一个子串,m次询问,每次给你abcd,问你子串sa-b的所有子串和子串sc-d的最长公共前缀是多长 题解:首先要求两个子串的最长公共前缀就是把反过来插入变成最长公共后缀,两个节点在paren ... 
- ABAP基础一:ALV基础之ALV的整体结构
			很久没摸ECC了,最近看到很多新人在捯饬ALV...中国就喜欢量产垃圾...培训,上岗...没有行业道德... 闲话不多说,开始正事: ALV很常见,在SAP非WEB的项目,没有不用的,它包含了报表和 ... 
- MySQL 排名、分组后组内排名、取各组的前几名 及排名后更新插入数据表中
			一.排名 /*普通排名:从1开始,顺序往下排*/ AS rank ) r ORDER BY score; /*并列排名:相同的值是相同的排名*/ SELECT cs.* , CASE WHEN @p= ... 
- Linux---centos编译安装ffmpeg
			环境 系统环境:CentOS release 6.7 (Final) 需求 编译安装ffmpeg 获取依赖 安装依赖包 yum install -y autoconf automake cmake f ... 
- Python语言:下载上证股票数据程序
			from urllib.request import urlretrieve f = open('SHA.csv', 'r')for line in f: data = line.split(',') ... 
