当前位置: 首页> 文旅> 艺术 > DangerWind-RPC-framework---七、序列化算法

DangerWind-RPC-framework---七、序列化算法

时间:2025/8/23 22:48:32来源:https://blog.csdn.net/m0_60424152/article/details/140420488 浏览次数:0次

        客户端与服务端的在交互过程中需要互相发送交换数据,这就需要对传输对象进行序列化与反序列化操作,此过程涉及到序列化算法的使用。本RPC框架支持多种序列化算法,通过SPI机制进行扩展。

       比如客户端在向服务端发送数据时,首先是客户端的序列化操作:

   Serializer serializer = ExtensionLoader.getExtensionLoader(Serializer.class).getExtension(codecName);bodyBytes = serializer.serialize(rpcMessage.getData());

       服务端接收到数据后要进行反序列化操作:

   Serializer serializer = ExtensionLoader.getExtensionLoader(Serializer.class).getExtension(codecName);if (messageType == RpcConstants.REQUEST_TYPE) {RpcRequest tmpValue = serializer.deserialize(bs, RpcRequest.class);rpcMessage.setData(tmpValue);} else {RpcResponse tmpValue = serializer.deserialize(bs, RpcResponse.class);rpcMessage.setData(tmpValue);}

       本次主要支持三种序列化算法,分别是Kryo、Hessian、ProtoStuff,首先是Kryo序列化算法:

    private final ThreadLocal<Kryo> kryoThreadLocal = ThreadLocal.withInitial(() -> {Kryo kryo = new Kryo();// 注册类是一种优化手段,可以提高序列化和反序列化的效率kryo.register(RpcResponse.class);kryo.register(RpcRequest.class);return kryo;});@Overridepublic byte[] serialize(Object obj) {try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();Output output = new Output(byteArrayOutputStream)) {Kryo kryo = kryoThreadLocal.get();// Object->byte:将对象序列化为byte数组kryo.writeObject(output, obj);kryoThreadLocal.remove();return output.toBytes();} catch (Exception e) {throw new SerializeException("Serialization failed");}}@Overridepublic <T> T deserialize(byte[] bytes, Class<T> clazz) {try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);Input input = new Input(byteArrayInputStream)) {Kryo kryo = kryoThreadLocal.get();// byte->Object:从byte数组中反序列化出对对象Object o = kryo.readObject(input, clazz);kryoThreadLocal.remove();return clazz.cast(o);} catch (Exception e) {throw new SerializeException("Deserialization failed");}}

       Kryo序列化算法性能较好,但是是线程不安全的,因此需要进行线程隔离,通过ThreadLocal为每个线程维护一个Kryo对象,使用完毕后就remove掉,之后需要使用时再次在threadLocal中初始化一个Kryo对象,这也是withInitial懒加载的过程。

      接下来是Hessian序列化算法:

    @Overridepublic byte[] serialize(Object obj) {try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {HessianOutput hessianOutput = new HessianOutput(byteArrayOutputStream);hessianOutput.writeObject(obj);return byteArrayOutputStream.toByteArray();} catch (Exception e) {throw new SerializeException("Serialization failed");}}@Overridepublic <T> T deserialize(byte[] bytes, Class<T> clazz) {try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes)) {HessianInput hessianInput = new HessianInput(byteArrayInputStream);Object o = hessianInput.readObject();return clazz.cast(o);} catch (Exception e) {throw new SerializeException("Deserialization failed");}}

       最后是ProtoStuff序列化算法:

    private static final LinkedBuffer BUFFER = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);@Overridepublic byte[] serialize(Object obj) {Class<?> clazz = obj.getClass();Schema schema = RuntimeSchema.getSchema(clazz);byte[] bytes;try {bytes = ProtostuffIOUtil.toByteArray(obj, schema, BUFFER);} finally {BUFFER.clear();}return bytes;}@Overridepublic <T> T deserialize(byte[] bytes, Class<T> clazz) {Schema<T> schema = RuntimeSchema.getSchema(clazz);T obj = schema.newMessage();ProtostuffIOUtil.mergeFrom(bytes, obj, schema);return obj;}

        BUFFER可以避免每次序列化时重新申请缓冲区空间,提高序列化的效率。三种序列化算法的实现过程中,主要是需要对线程不安全的隐患进行处理,比如进行隔离等操作,以保证序列化操作的正确执行。

 

关键字:DangerWind-RPC-framework---七、序列化算法

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: