IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 快来手写RPC S2 序列化探究 -> 正文阅读

[网络协议]快来手写RPC S2 序列化探究

SOA

面向服务的架构(SOA)是伴随着互联网快速发展产生的 一种系统架构方法。而面向服务是一种设计范式,用于创建解决方案的逻辑单元,这些逻辑单元可组合、可复用,以支持实现面向服务计算的特定战略目标和收益。
(感觉实际上就是微服务
由于拆分了很多小的服务模块,模块之间的通信就特别重要,单纯的信息传递可以用MQ,而复杂方法调用则必须要健壮的RPC支持。
在实际生产中,我们不可能再像上一课中那样,仅凭借“线下互相问服务名方法名”的方式来运行我们的RPC功能,我们必须要有完成的系统来保证服务健康。其中至少要有以下部分:

  1. 服务注册中心
  2. 服务提供方及相关的心跳检测机制
  3. 更加严格的消费方调用、传参、异常处理机制
  4. 限流策略
  5. 轮询策略等等

则相应的,整体服务流程则应该是:

  • 服务提供端启动服务,将服务提供者信息注册到服务注册中心,服务提供者信息 一般包括服务主机地址、端口、服务接口信息等。
  • 服务消费端将服务提供者信息从服务注册中心获取到本地缓存,同时将服务消费
    者信息上报到服务注册中心。
  • 服务消费端根据某种软负载策略选择某一个服务提供者发起服务调用,服务调用 首先采用某种数据序列化方案,将调用数据序列化为可以在网络传输的字节数组,采用某种NIO框架(如 Netty、 Mina、 Grizzy)完成调用。
  • 服务治理(健康监测、限流降级、轮询等等)

序列化与反序列化

让我们从最基本的概念开始。

序列化

序列化( Serialization)是将对象的状态信息转换为可存储或传输的形式过程 。 简言之,把对象转换为字节序列的过程称为对象的序列化。

反序列化

反序列化( Deserialization)是序列化的逆过程。将字节数组反序列化为对象,把字节序列恢复为对象的过程称为对象的反序列化。

sd的必要性

  1. 使得不共享内存通过网络连接的系统之间能够能够进行对象的传输。
  2. 保证传输内容不失真

序列化须知

  • 序列化时,只对对象的状态进行保存,而不管对象的方法。
  • 当一个父类实现序列化,子类自动实现序列化,不需要显式实现 Serializable接口。
  • 叫一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列 化。
  • 当某个字段被声明为transient后,默认序列化机制就会忽略该字段。
  • 对于上述己被声明为transient的宇段,可以在类中添加私有方法writeObject()与readObject()两个方法来进行序列化 。

常见序列化方案

模仿Java的原生序列化


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * @Desc
 **/
public class MineSerializer {

    public <T> byte[] serialize(T obj) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(obj);
            objectOutputStream.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return byteArrayOutputStream.toByteArray();
    }

    @SuppressWarnings("unchecked")
    public <T> T deserialize(byte[] data, Class<T> clazz) {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
        try {
            ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
            return (T) objectInputStream.readObject();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

XML和JSON序列化

JSON序列化使用阿里的fastjson,google的gson均可,不多介绍。这里介绍XML序列化:

<dependencies>
        <!-- https://mvnrepository.com/artifact/com.thoughtworks.xstream/xstream -->
    <dependency>
        <groupId>com.thoughtworks.xstream</groupId>
        <artifactId>xstream</artifactId>
        <version>1.4.19</version>
    </dependency>

</dependencies>

代码:


import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

import java.nio.charset.StandardCharsets;

/**
 * @Desc
 **/
public class MineXmlSerialize {

    private static final XStream X_STREAM =new XStream(new DomDriver()) ;

    public <T> byte[] serialize(T obj) {
        return X_STREAM.toXML(obj).getBytes(StandardCharsets.UTF_8);
    }

    @SuppressWarnings("unchecked")
    public <T> T deserialize(byte[] data, Class<T> clazz) {
        String xml = new String(data);
        return (T) X_STREAM.fromXML(xml);
    }
}

Hessian序列化

是一个跨语言的二进制序列化协议,性能强且易用,最主要是跨语言。

<!-- https://mvnrepository.com/artifact/com.caucho/hessian -->
<dependency>
    <groupId>com.caucho</groupId>
    <artifactId>hessian</artifactId>
    <version>4.0.66</version>
</dependency>

代码:


import com.caucho.hessian.io.HessianInput;
import com.caucho.hessian.io.HessianOutput;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

/**
 * @Desc
 **/
public class MineHessianSerialize {

    public byte[] serialize(Object obj) {
        if (obj == null) {
            throw new NullPointerException();
        }
        try {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            HessianOutput ho = new HessianOutput(os);
            ho.writeObject(obj);
            return os.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @SuppressWarnings("unchecked")
    public <T> T deserialize(byte[] data, Class<T> clazz) {
        if (data == null) {
            throw new NullPointerException();
        }
        try {
            ByteArrayInputStream is = new ByteArrayInputStream(data);
            HessianInput hi = new HessianInput(is);
            return (T) hi.readObject();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

Thrift序列化

伴随RPC框架的配套序列化。
XML文件:

<dependency>
    <groupId>org.apache.thrift</groupId>
    <artifactId>libfb303</artifactId>
    <version>0.9.3</version>
</dependency>
<dependency>
    <groupId>org.apache.thrift</groupId>
    <artifactId>libthrift</artifactId>
    <version>0.9.3</version>
</dependency>

代码


import org.apache.thrift.TBase;
import org.apache.thrift.TDeserializer;
import org.apache.thrift.TSerializer;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TBinaryProtocol.Factory;

/**
 * @Desc
 **/
public class MineThriftSerialize {

    public <T> byte[] serialize(T obj) {
        try {
            if (!(obj instanceof TBase)) {
                throw new UnsupportedOperationException("not support");
            }
            TSerializer serializer = new TSerializer(new Factory());
            return serializer.serialize((TBase) obj);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public <T> T deserialize(byte[] data, Class<T> clazz) {
        try {
            if (!TBase.class.isAssignableFrom(clazz)) {
                throw new UnsupportedOperationException("not support");
            }
            TBase o = (TBase) clazz.newInstance();
            TDeserializer tDeserializer = new TDeserializer(new TBinaryProtocol.Factory());
            tDeserializer.deserialize(o, data);
            return (T) o;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

其他

还有谷歌的protobuf,不过用起来很麻烦基本没有大项目用

序列化方案选择

  1. 性能标尺(二进制的基本比xml和json快)
  2. 易用标尺(好不好学)
  3. 跨语言/平台标尺(比如go-nodejs-java-python架构)
  4. 长期支持性(母公司倒闭了…)
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-07-04 23:19:41  更:2022-07-04 23:20:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 13:46:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码