Several ways of Java serialization and the role of serialization

What is object serialization?

 Serialization is the process of converting the state information of an object into a form that can be stored or transmitted. 
 This is the description of Baidu Encyclopedia, which is also very easy to understand. For example, I have a java object that I want to transmit to the remote end How to transmit the nibble of the program? 
 Java provides a serialization interface. As long as the Serializable interface is implemented, the java object can be serialized into bytes, then transmitted in the form of a stream, and then deserialized into an object at the remote end. This achieves The purpose of transmitting messages. 
 However, there are some defects in this serialization. 1. It cannot be cross-language. 2. The serialization volume is large. 
 Therefore, in order to support cross-language, improve sequence efficiency, and reduce the size of the code stream during transmission, many companies or great gods have developed There are various serialization libraries, hession, protostuff, kryo, jackson, xml, etc. For example, json can be regarded as a serialization method, and it is also the most widely used one at present, but json is not strictly a serialization. , it is just a general information description method, a set of json information, which may correspond to different object modes. For example, you can convert a set of json into a java bean object or into a map, the form is uncertain. So the general Remote calls will not use json as the serialization implementation.

sequence type Is it cross-language Advantages and disadvantages
hession support Cross-language, small size and fast after serialization
protostuff support Cross-language, small size and fast after serialization, but requires Schema, which can be dynamically generated
jackson support Cross-language, small size, fast speed and uncertainty after serialization
kryo support Cross-language support is difficult, the serialization is small, and the speed is fast
jdk not support After serialization, the volume is large and the speed is fast

What can serialization do?

As mentioned in the first section, object serialization can be used to transmit messages and transmit them in the form of streams to improve transmission efficiency. Use scenarios such as remote service calling rpc

Comparison of various serialization libraries

0. Prepare dependencies

        <!-- protostuff -->
        <dependency>
            <groupId>com.dyuproject.protostuff</groupId> <artifactId>protostuff-core</artifactId> <version>1.0.8</version> </dependency> <dependency> <groupId>com.dyuproject.protostuff</groupId> <artifactId>protostuff-runtime</artifactId> <version>1.0.8</version> </dependency> <!-- objenesis(support protostuff,可以使用无参构造方法) --> <dependency> <groupId>org.objenesis</groupId> <artifactId>objenesis</artifactId> <version>2.1</version> </dependency> <!-- hessian --> <dependency> <groupId>com.caucho</groupId> <artifactId>hessian</artifactId> <version>4.0.38</version> </dependency> <!-- jackson --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.4</version> </dependency> <!-- kryo --> <dependency> <groupId>com.esotericsoftware</groupId> <artifactId>kryo</artifactId> <version>4.0.0</version> </dependency>

 

1. Write the serialization interface

public interface Serializer {

    <T> byte[] serialize(T obj);
    <T> Object deserialize(byte[] bytes, Class<T> clazz);
}

 

2. Implement the interface

hession implementation

public class HessianSerializer implements Serializer { @Override public <T> byte[] serialize(T obj){ ByteArrayOutputStream os = new ByteArrayOutputStream(); HessianOutput ho = new HessianOutput(os); try { ho.writeObject(obj); } catch (IOException e) { throw new IllegalStateException(e.getMessage(), e); } return os.toByteArray(); } @Override public <T> Object deserialize(byte[] bytes, Class<T> clazz) { ByteArrayInputStream is = new ByteArrayInputStream(bytes); HessianInput hi = new HessianInput(is); try { return hi.readObject(); } catch (IOException e) { throw new IllegalStateException(e.getMessage(), e); } } }

 

jackson implementation

public class JacksonSerializer implements Serializer { private final static ObjectMapper objectMapper = new ObjectMapper(); @Override public <T> byte[] serialize(T obj) { try { return objectMapper.writeValueAsBytes(obj); } catch (JsonProcessingException e) { throw new IllegalStateException(e.getMessage(), e); } } @Override public <T> Object deserialize(byte[] bytes, Class<T> clazz) { try { return objectMapper.readValue(bytes, clazz); } catch (JsonParseException e) { throw new IllegalStateException(e.getMessage(), e); } catch (JsonMappingException e) { throw new IllegalStateException(e.getMessage(), e); } catch (IOException e) { throw new IllegalStateException(e.getMessage(), e); } } }

 

prostfuff implementation

public class ProtostuffSerializer implements Serializer { private static Objenesis objenesis = new ObjenesisStd(true); private static Map<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<Class<?>, Schema<?>>(); private static <T> Schema<T> getSchema(Class<T> cls) { @SuppressWarnings("unchecked") Schema<T> schema = (Schema<T>) cachedSchema.get(cls); if (schema == null) { schema = RuntimeSchema.createFrom(cls); if (schema != null) { cachedSchema.put(cls, schema); } } return schema; } @Override public <T> byte[] serialize(T obj) { @SuppressWarnings("unchecked") Class<T> cls = (Class<T>) obj.getClass(); LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); try { Schema<T> schema = getSchema(cls); return ProtostuffIOUtil.toByteArray(obj, schema, buffer); } catch (Exception e) { throw new IllegalStateException(e.getMessage(), e); } finally { buffer.clear(); } } @Override public <T> Object deserialize(byte[] bytes, Class<T> clazz) { try { T message = (T) objenesis.newInstance(clazz); Schema<T> schema = getSchema(clazz); ProtostuffIOUtil.mergeFrom(bytes, message, schema); return message; } catch (Exception e) { throw new IllegalStateException(e.getMessage(), e); } } } 

 

kryo implementation

public class KryoSerializer implements Serializer { private static final Kryo kryo = new Kryo(); @Override public <T> byte[] serialize(T obj) { try (Output output = new Output(new ByteArrayOutputStream())) { kryo.writeObject(output, obj); byte[] bytes = output.toBytes(); return bytes; } } @Override public <T> Object deserialize(byte[] bytes, Class<T> clazz) { try (Input input = new Input(bytes)) { return kryo.readObject(input, clazz); } } } 

 

jdk implementation

public class JdkSerializer implements Serializer { @Override public <T> byte[] serialize(T obj) { try { ByteArrayOutputStream byteArr = new ByteArrayOutputStream(); ObjectOutputStream out=new ObjectOutputStream(byteArr); out.writeObject(obj); out.flush(); return byteArr.toByteArray(); } catch (IOException e) { e.printStackTrace(); } return null; } @Override public <T> Object deserialize(byte[] bytes, Class<T> clazz) { try { ObjectInputStream input=new ObjectInputStream(new ByteArrayInputStream(bytes)); return input.readObject(); } catch (Exception e) { e.printStackTrace(); } return null; } } 

 

 

3, prepare the sequence object

Serialized objects need to implement Serializable, some need not, some need not, hession needs, and also needs to have the default no-argument constructor jackson needs

public class User  implements Serializable{ private String name; private String address; private Integer age; public User() { super(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public User(String name, String address, Integer age) { super(); this.name = name; this.address = address; this.age = age; } } 

 

4. Serialization speed comparison

public class SerTest {
    public static void main(String[] args) { int len=10; test(new HessianSerializer(), "hession",len); test(new JacksonSerializer(), "jackson",len); test(new ProtostuffSerializer(), "protostu",len); test(new JdkSerializer(),"jdk",len); test(new KryoSerializer(),"kryo",len); } public static void test(Serializer s,String tag,int len){ long cap=0; long sumTime=0; for(int i=0;i<len;i++){ User u=new User("taoyuan"+i, i+"addr", i); long start=System.currentTimeMillis(); byte[] serialize = s.serialize(u); cap+=serialize.length; s.deserialize(serialize, User.class); long cal= System.currentTimeMillis()-start; sumTime+=cal; } System.out.println(tag+"序列总体积大小:"+cap); System.out.println(tag+"序列总消耗时间为:"+sumTime); } } 

 

Results: 
Hession sequence total volume size: 780 
Hession sequence total time consumption: 172 
jackson sequence total volume size: 450 
jackson sequence total time consumption: 166 
protostu sequence total volume size: 190 
protostu sequence total time consumption: 127 
jdk sequence total Volume size: 2140 
jdk sequence total consumption time: 94 
kryo sequence total volume size: 180 
kryo sequence total consumption time: 47

5 Conclusion

From the above results, the overall performance of serialization is better because 
the serialization speed of protostuff and kryo jdk is relatively fast, that is, the sequence volume is large. 
Therefore, when we need to develop a set of rpc services, we can use kryo to serialize objects. , improve the transmission efficiency

Introduction to the simple implementation principle of rpc service

personal understanding

To implement a set of rpc services, first of all we have to understand rpc from its essence  . In
short, rpc is serialization + transmission protocol + call implementation + service management

Serialization is the foundation and also determines whether rpc supports cross-language 
transmission protocols. You can choose tcp, http, udp and other protocols 
to call the implementation, that is, the business implementation of rpc services. 
Service management is the optimized management level, load balancing, and call tracking based on the above. Wait

Once we understand rpc in essence, it is also very simple to write a simple rpc service, and then analyze and optimize the specific business. Each layer is isolated. When optimizing, the changes will not be too big. There are opportunities. Let's write a blog post that teaches you how to implement rpc

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324648839&siteId=291194637