松花皮蛋的黑板報
  • 分享在京東工作的技術感悟,還有JAVA技術和業內最佳實踐,大部分都是務實的、能看懂的、可復現的

掃一掃
關注公眾號

微服務架構之Msgpack序列化最佳實踐

博客首頁文章列表 松花皮蛋me 2019-05-27 22:28

任何Java序列化工具,序列化/反序列化的時候,都是通過反射去遍歷Class屬性,然后挨個生成byte數組。Msgpack序列化的時候,filed不寫key,只寫index,類似數組,它的編碼方式是type+length+body,這樣傳輸時整體包會小很多,另外Msgpack支持啟動預生成msgpack模版,而不用每次都反射(題外話:方法的反射調用會帶來不少性能開銷,原因主要有變長(Object[] objs或Object… objs)參數方法、自動裝箱拆箱、方法內聯失效,對反射感興趣的朋友可以閱讀http://www.znvxfuqt.icu/archives/73)。不過糟糕的是Msgpack不支持泛型、Ref引用,而且集合類型會丟失

基于這些特性,在服務端和消費者不能同時升級的情況下,字段兼容規則如下,否則會出現模板污染

1、字段變更必須是保證在字段順序最后一位,另外存在父子類的情況下,變更字段不能加在父類,否則會導致子類的最后一個字段沒有機會得到覆值

2、禁止直接使用不熟悉的復雜類,有可能屬性里面存在Native,或者內部引用內部類,會導致報錯

3、不能使用內部類,尤其是集合內部類包括list.sublist、map.keyset等在不同jdk版本下實現方式不一樣的方法

4、不能使用第三方包提供的集合類工具包作為返回值或者入參

  public Class A{
	        Map<String,String> a();
	    }
	
	    public Class Aimpl implements A{
	        public Map<String,String> a(){
	            //  不能這樣使用
	            return JSON.parseObject("{}");
	        }
	    }

5、雖然msgpack不強制要求實體類實現Serializable接口,但是還是強烈建議加上,方便切其他序列化

6、類屬性上不能使用具體類,要使用接口或者超類。JDK 版本不一樣,導致數據結構不一樣

	    public Class A{
	        //不能這樣使用
	        private ConcurrentHashMap<String,String> a;
	    }

黑龙江6+1开奖结果查询