Framework sequence alignment and selection

Ranking communication

Converting the byte array object, the object is to facilitate the transmission network. In the communication network, different computers communicate with each other is the primary data stream transmitted from one machine to another computer, the common transport protocols include TCP, UDP, HTTP and the like, comprising a main network io manner with aio, bio, nio three ways.

When the client will need to request data on the need for a good package is converted to a binary format and then converted to transport stream, when the server receives the stream and then parses the data into a binary format the content, then in accordance with the agreed-upon protocol processing resolution. The most common scenario is when rpc remote call processing for sending data and receiving data time.

Below we look at each of the more common now introduce several serialization technology framework.

jdk serialization

jdk itself will function with serialization, Java serialization API allows us to convert an object into the stream, and sent over the network, or to a file or stored in a database for future use, sucked deserialized stream into an object the actual process of Java objects used in the program.

Let's look at the actual code case

First we create a Person class-based testing

package com.sise.test;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @author linhao
 * @date 2019/8/15
 * @Version V1.0
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Person implements Serializable {
    private static final long serialVersionUID = 3829252771168681281L;

    private Integer id;

    private String username;

    private String tel;
}

 

If some special fields do not wish to be serialized how to deal with?

If there is a corresponding attribute is not desired, then the sequence of operation, transient keyword can be modified, e.g. tel desirable properties not wishing to be serialized, this can be changed to:

  private transient String tel;

 

After this case, the object deserialization out a result, the corresponding attribute value will be null.

Why define serialVersionUID?

When the sequence of operation, the system will serialVersionUID current class declaration file is written to the serialization, deserialization time for the system to detect serialVersionUID file, determines whether it is consistent with the current class serialVersionUID, if it shows agreement serialization class version with the current version of the class is the same, can deserialize success, or failure.

If you do not define serialVersionUID

When implementing the current class is not explicitly defined in a variable time serialVersionUID, Java serialization mechanism for automatically generating a serialVersionUID serialized version of the compiler according to comparative Class, in this case, if the class information is modified, will lead to deserialize when serialVersionUID with the original values ​​can not match, deserialization fails.

Its corresponding serialization and deserialization code serialization case jdk elevated

package com.sise.test.jdk;


import com.sise.test.Person;

import java.io.IOException;

/**
 * @author idea
 * @date 2019/8/15
 * @Version V1.0
 */
public class SerializationTest {

    /**
     *
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, ClassNotFoundException {

        long begin = System.currentTimeMillis();
        for (int i = 0; i < 2000; i++) {
            String fileName = "test-person.txt";
            Person person = new Person();
            person.setId(1);
            person.setTel("99562352");
            person.setUsername("idea");
            SerializationUtil.serialize(person, fileName);
            Person newPerson = (Person) SerializationUtil.deserialize(fileName);
        }
        long end = System.currentTimeMillis();
        System.out.println ( "time-consuming:" + (End - the begin));
    }
}

 

jdk serialization disadvantages

1, can not be cross-language

This shortcoming is almost fatal injuries, for service calls cross-process, often need to take into account the different languages ​​of the mutual compatibility of calling time, and this sequence of operations for jdk but it can not be done. This is because the jdk serialization operation is the use of internal java language private agreement, there will be serious obstacles in time to other languages ​​deserialized.

2, after the code sequence of flow a large

Byte array generated after jdk serialized encoded large amount of storage memory space is high, which results in a corresponding higher bandwidth stream in the network transmission time, relatively poor performance compared to the case.

Hessian framework sequences

Hessian is a technical framework for supporting multiple languages ​​in the sequence of operation, after the code stream generated is small while performing the serialization, the data processing performance far beyond the built java jdk serialization.

Code-related cases:

package com.sise.test.hessian;

import com.caucho.hessian.io.HessianInput;
import com.caucho.hessian.io.HessianOutput;
import com.sise.test.Person;

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

/**
 * @author idea
 * @date 2019/8/15
 * @Version V1.0
 */
public class HessianTest {

    /**
     *
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        long begin = System.currentTimeMillis();
        for (int i = 0; i < 2000; i++) {
            Person person = new Person();
            person.setId(1);
            person.setUsername("idea");
            person.setTel("99562352");
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            HessianOutput ho = new HessianOutput(os);
            ho.writeObject(person);
            byte[] userByte = os.toByteArray();
            IS A ByteArrayInputStream = new new A ByteArrayInputStream (userByte);
             // the Hessian deserialized object to be read 
            HessianInput Hi = new new HessianInput (IS);
            Person newPerson = (Person) hi.readObject();
        }
        long end = System.currentTimeMillis();
        System.out.println ( "time-consuming:" + (End - the begin));
    }
}

 

Hessian source inside the core is mainly com.caucho.hessian.io inside the code, AbstractSerializer Hessian is inside the core sequence of classes, when we look carefully at the source of the time you will find hessian feature a variety of serialization and de-serialization classes of different types of data processing. (I'm using hessian4.0, so the corresponding class will be a lot more)

Framework sequence alignment and selection


In SerializerFactory there getSerializer getDefaultSerializer and function of these sequences dedicated to the extraction and deserialization tools, to avoid when using this tool or the like, again, examples of these tools will be stored to a different ConcurrentHashMap go inside.

 

Framework sequence alignment and selection


ps: For hessian3.0 time Serializer / Derializer realize the function does not take into account the sequence of treatment for abnormal information, so if you encounter problems corresponding hessian friends can consider version upgrade to 3.1.5 above.

Kryo serialization technology

Kryo is a very mature sequence of implementation, has been in widespread use Twitter, Groupon, Yahoo and more well-known open source projects (such as Hive, Storm), its performance in every way than hessian2 to some excellent, so dubbo the latter also began gradually introduced a way to use Kryo be serialized.

For kryo, we take a look at the code accordingly:

First, we introduce the corresponding dependence:

    <dependency>
            <groupId>com.esotericsoftware</groupId>
            <artifactId>kryo-shaded</artifactId>
            <version>3.0.3</version>
        </dependency>

 

然后就是基础的序列化和反序列化代码操作了

package com.sise.test.kryo;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.sise.test.Person;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

/**
 * @author idea
 * @date 2019/8/15
 * @Version V1.0
 */
public class KryoTest {

    public static void main(String[] args) throws FileNotFoundException {
        Kryo kryo=new Kryo();
        Output output = new Output(new FileOutputStream("person.txt"));
        Person person=new Person();
        person.setId(1);
        person.setUsername("idea");
        kryo.writeObject(output, person);
        output.close();
        Input input = new Input(new FileInputStream("person.txt"));
        Person person1 = kryo.readObject(input, Person.class);
        input.close();
        System.out.println(person1.toString());
        assert "idea".equals(person1.getUsername());
    }
}

 

ps:这里我们需要注意,Kryo不支持没有无参构造函数的对象进行反序列化,因此如果某个对象希望使用Kryo来进行序列化操作的话,需要有相应的无参构造函数才可以。

由于Kryo不是线程安全,因此当我们希望使用Kryo构建的工具类时候,需要在实例化的时候注意线程安全的问题。代码案例:

package com.sise.test.kryo;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.sise.test.Person;

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

/**
 * @author idea
 * @data 2019/8/17
 */
public class KryoUtils {


    public byte[] serialize(Object obj){
        Kryo kryo = kryos.get();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        Output output = new Output(byteArrayOutputStream);
        kryo.writeClassAndObject(output, obj);
        output.close();
        return byteArrayOutputStream.toByteArray();
    }

    public <T> T deserialize(byte[] bytes) {
        Kryo kryo = kryos.get();
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        Input input = new Input(byteArrayInputStream);
        input.close();
        return (T) kryo.readClassAndObject(input);
    }


    private static final ThreadLocal<Kryo> kryos=new ThreadLocal<Kryo>(){
        @Override
        protected Kryo initialValue(){
            Kryo kryo=new Kryo();
            return kryo;
        }

    };


    public static void main(String[] args) {
        KryoUtils kryoUtils=new KryoUtils();
        for(int i=0;i<1000;i++){
            Person person=new Person(1,"idea");
            byte[] bytes=kryoUtils.serialize(person);
            Person newPerson=kryoUtils.deserialize(bytes);
            System.out.println(newPerson.toString());
        }
    }
}

 

XStream实现对象的序列化

在使用XStream进行序列化技术的实现过程中,类中的字符串组成了 XML 中的元素内容,而且该对象还不需要实现 Serializable 接口。XStream不关心被序列化/反序列化的类字段的可见性,该对象也不需要有getter/setter方法和默认的构造函数。

引入的依赖:

<dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.9</version>
        </dependency>

 

通过使用XStream来对对象进行序列化和反序列化操作:

package com.sise.test.xstream;


import com.sise.test.Person;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

/**
 * @author idea
 * @date 2019/8/15
 * @Version V1.0
 */
public class XStreamTest {


    private static XStream xStream;

    static {
        xStream = new XStream(new DomDriver());
        /*
         * 使用xStream.alias(String name, Class Type)为任何一个自定义类创建到类到元素的别名
         * 如果不使用别名,则生成的标签名为类全名
         */
        xStream.alias("person", Person.class);
    }

    //xml转java对象
    public static Object xmlToBean(String xml) {
        return xStream.fromXML(xml);
    }

    //java对象转xml
    public static String beanToXml(Object obj) {
        return "<?xml version="1.0" encoding="UTF-8"?>n" + xStream.toXML(obj);
    }

    /**
     *
     * @param args
     */
    public static void main(String[] args) {
        long begin = System.currentTimeMillis();
        for (int i = 0; i < 2000; i++) {
            Person person = new Person();
            person.setId(1);
            person.setUsername("idea");
            String xml = XStreamTest.beanToXml(person);
            Person newPerson = (Person) XStreamTest.xmlToBean(xml);
        }
        long end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - begin));
    }
}

 

google的Protobuf

google protobuf is a flexible, efficient protocol for serializing data. Compared XML and JSON format, protobuf smaller, faster and more convenient. google protobuf is a cross-language, and comes with a compiler (protoc), just use it to compile, can be compiled into Java, python, C ++, C #, Go and other code, and can be used directly, you do not need to write other code, comes with parsing code.
protobuf with respect kryo for more efficient performance and flexibility, it can be in practical use, when the object is serialized + field, still in normal use deserialization time out. (This kryo not support)

Summary of the different framework sequences

Framework sequence alignment and selection

At present, there are a lot of serialization framework is not mentioned in the text, if encountered in the future when development can be summarized appropriate, comparison between the characteristics of the various serialization framework.

Guess you like

Origin www.cnblogs.com/javazhiyin/p/11375553.html