最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

世界简讯:Hessian2序列化支持这一点,让重构dubbo接口更容易了

来源:博客园


(相关资料图)

先看如下Hessian2序列化的测试代码。

import com.alibaba.com.caucho.hessian.io.Hessian2Input;import com.alibaba.com.caucho.hessian.io.Hessian2Output;import com.alibaba.com.caucho.hessian.io.SerializerFactory;import dubbodemo.dto.MyDto;import org.junit.Test;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.util.Base64;public class TestMain {    @Test    public void test() throws IOException {        MyDto MyDto = new MyDto();        MyDto.setNum(1);        byte[] bytes = serialize(MyDto);        /**         * 通过{@link Base64#getEncoder()}把byte数组序列化成base64串。相应地,利用{@link Base64#getDecoder()}进行字符串的反序列化         */        String base64String = Base64.getEncoder().encodeToString(bytes); //new String(serialize, Charsets.UTF_8);        System.out.println("base64串=" + base64String);        MyDto myDto2 = (MyDto) deSerialize(bytes);        System.out.println(myDto2.getNum());    }        @Test    public void test2() throws IOException {        String s = "QxRkdWJib2RlbW8uZHRvLk15RHRvMZMHaW50ZWdlcgRuYW1lAmlkYOFOTg==";        byte[] bytes = Base64.getDecoder().decode(s); //s.getBytes(Charsets.UTF_8);        MyDto myDto2 = (MyDto) deSerialize(bytes);        System.out.println(myDto2.getNum());    }    public static byte[] serialize(Object obj) throws IOException {        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();        Hessian2Output hessian2Output = new Hessian2Output(byteArrayOutputStream);        try {            hessian2Output.setSerializerFactory(new SerializerFactory());            hessian2Output.writeObject(obj);        } finally {            byteArrayOutputStream.close();            hessian2Output.close();        }        return byteArrayOutputStream.toByteArray();    }    public static Object deSerialize(byte[] bytes) throws IOException {        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);        Hessian2Input hessianInput = new Hessian2Input(byteArrayInputStream);        try {            hessianInput.setSerializerFactory(new SerializerFactory());            return hessianInput.readObject();        } finally {            byteArrayInputStream.close();            hessianInput.close();        }    }}@Data@Accessors(chain = true)public class MyDto implements Serializable {    private String id;    private String name;    private Integer num;}

我要说什么呢?我要说的是MyDto的num属性。当num是Integer时,我们得到hessian2序列化结果,然后,修改num为Long,前面的序列化结果可以正常反序列化。反之,num先是Long,然后修改成Integer,亦能正常反序列化。

这一点对我们的工作有什么帮助呢?

我们的系统中,服务商的主属性--服务商id,在不同子系统里,这个id字段的类型不统一,varchar/int/bigint,这就致使程序里对应的这个服务商id属性,有的是String,有的是Integer,有的是Long,这给我们的系统迭代(开发&运维)带来了许多麻烦。系统不断升级迭代,服务越来越多,重构的工作量以及风险就加剧,产生系统熵增。

这几天的北京,市民陆续“阳”起来,我们公司也不例外,2/3的伙伴们都居家养病了。非常时期,一些开发需求就暂缓。我已阳康,趁此机会,take action!决定动手重构一把。

其中,中台通道系统的channel-provider里有一个dubbo服务LevyMerchantRelationService,它依赖一个数据传输对象LevyMerchantRelationDTO,LevyMerchantRelationDTO里的服务商id类型是Integer。从dubbo控制台来观察,LevyMerchantRelationService的消费者有14个应用共8个java工程。

那么,我们要变更LevyMerchantRelationDTO里的服务商id类型为Long,这些工程的代码,涉及到这个属性的,都要跟着做调整。大好的消息是,有了上面hessian2序列化的这个优势(dubbo RPC默认序列化方式是Hessian2),我们在上线的时候,就不用把14个消费者应用都同时上线,这将极大节省跨小组沟通和上线工作量,更重要的是,dubbo服务正常调用,丝毫不影响系统稳定。

这一点,增强了我这次重构的自信!

那么,我立马想到,如果dubbo接口方法的参数列表里有Integer的服务商id,是不是也能直接改成Long而不影响dubbo消费者的调用呢?经自测验证,这个是行不通的!

关键词: 反序列化 非常时期 系统稳定