RPC框架底层为什么不使用Java序列化框架?

最近在学习RPC相关的知识,既然是远程过程调用,就会涉及到在网络上传输的问题,发现常见的RPC框架并没有使用java原生的序列化机制。这里就来记录一下Java序列话的缺点。

一、Java序列序列化的缺点

缺点一:无法跨语言

这是一个比较致命的问题,当服务提供者或者调用这使用其他语言开发时,需要和相应的java进程进行交互时,由于java序列化后的字节数组,别的语言无法进行反序列化,这严重阻碍了它的应用。

缺点二:序列化后的码流太大

下面通过代码来证明java序列话之后,码流比较大

public class UserInfo implements Serializable {
    private static final long serialVersionUID = 1L;

    private String userName;
    private int userID;

    public UserInfo() {
    }

    public UserInfo(String userName, int userID) {
        this.userName = userName;
        this.userID = userID;
    }

    public UserInfo buildUserName(String userName) {
        this.userName = userName;
        return this;
    }

    public UserInfo buildUserID(int userID) {
        this.userID = userID;
        return this;
    }

    public final String getUserName() {
        return userName;
    }

    public final void setUserName(String userName) {
        this.userName = userName;
    }

    public final int getUserID() {
        return userID;
    }

    public final void setUserID(int userID) {
        this.userID = userID;
    }

    // 对UserInfo进行编码,编码的结果为字节数组
    public byte[] codeC() {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        byte[] value = this.userName.getBytes();
        buffer.putInt(value.length);
        buffer.put(value);
        buffer.putInt(this.userID);
        buffer.flip();
        value = null;
        byte[] result = new byte[buffer.remaining()];
        buffer.get(result);
        return result;
    }
}

测试Java序列化字节数组和使用codeC()方法后字节数组的大小比较

 public static void main(String[] args) throws IOException {
        UserInfo info = new UserInfo();
        info.buildUserID(100).buildUserName("Welcome to Netty");
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream os = new ObjectOutputStream(bos);
        os.writeObject(info);
        os.flush();
        os.close();
        byte[] b = bos.toByteArray();
        System.out.println("the jdk serializable length is : " + b.length);
        bos.close();
        System.out.println("--------------------------------");
        System.out.println("The byte array serializable length is : " + info.codeC().length);
    }

输出结果 通过结果发现,差距还是比较大的。
RPC框架底层为什么不使用Java序列化框架?_第1张图片

缺点三:序列化性能太低

这里做个试验,利用java序列化和不使用java序列化的数组进行比较其性能。
不使用java序列化

// 对象序列化成字节数组
public byte[] code(ByteBuffer buffer) {
        buffer.clear();
        byte[] value = this.userName.getBytes();
        buffer.putInt(value.length);
        buffer.put(value);
        buffer.putInt(this.userID);
        buffer.flip();
        value = null;
        byte[] result = new byte[buffer.remaining()];
        buffer.get(result);
        return  result;
    }

进行测试

// 比较性能的差异
    public static void testPerformance() throws IOException {
        UserInfo info = new UserInfo();
        info.buildUserID(100).buildUserName("Welcome to Netty");
        int loop = 1000000;
        ByteArrayOutputStream bos = null;
        ObjectOutputStream os = null;
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < loop; i++) {
            bos = new ByteArrayOutputStream();
            os = new ObjectOutputStream(bos);
            os.writeObject(info);
            os.flush();
            os.close();
            byte[] b = bos.toByteArray();
            bos.close();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("The jdk serializable cost time is : " + (endTime - startTime) + "ms");
        System.out.println("--------------------------------");
        ByteBuffer buffer = ByteBuffer.allocate(1034);
        startTime = System.currentTimeMillis();
        for (int i = 0; i < loop; i++ ) {
            byte[] b = info.code(buffer);
        }
        endTime = System.currentTimeMillis();
        System.out.println("The byte array serializable cost time is : " + (endTime - startTime) + " ms");
    }

输出结果:可以发现java序列话的性能比较差
RPC框架底层为什么不使用Java序列化框架?_第2张图片可以看出,无论是序列话后的码流大小,还是序列化的性能,JDK默认的序列化机制都表现的很差。因此,通常一般不会选择java序列化作为RPC框架的编解码机制。通常选用的序列化框架有:谷歌的 protobuf、Facebook的Thrift等等。

你可能感兴趣的:(JAVA)