一個由於侵入框架引起的故障


背景

其實最近一直想寫些幫助大家提高架構底蘊的東西。無奈最近當家的身體抱恙,我白天上班,晚上照顧病人,沒有多余的精力 點、線、面的橫向思考技術的問題。倒是“無為空自老,含嘆負平生”的人生感慨多一些。今天還是談談點上的東西。
記得早些時候,被別人要求寫算法代碼沒寫出來,后來我刷了百道leetcode。算法題再也沒難住我了。但是想來,平時工作中是還是真的少些這些底層代碼為妙,業務代碼有業務代碼的寫法。寫業務代碼最忌諱:“炫技”。和做人一樣,講究“技高不炫技”。下面來介紹一個由於侵入了框架內部引起的故障。

 

使用Java反射引起的報錯

我們平時用Spring框架寫Controller進行http請求處理時,框架幫我們做了JavaBean到傳輸數據的轉換。在內部,實際上數據會先轉成map再轉成我們要處理的JavaBean。這次,在一個RPC泛化調用的場景(泛化調用主要用於沒有接口API的情況下。不需要引入接口 jar 包,而是直接通過 通用接口來發起服務調用,參數及返回值中的所有 pojo均用 map 表示)。有個同學客戶端處理時,自己寫了一個JavaBean轉成Map的方式,他是這么寫的:

public static Map<String,Object> objectTpMap(Object obj) {

     Map<String,Object> map = new HashMap();

     Class objectClass = obj.getClass();

     while(objectClass != null) {

          Field[] declaredFields = objectClass.getDeclaredFields();

          for(Field field : declaredFields) {

               field.setAccessible(true);

               resultMap.put(field.getName(), field.get(object));

          }

     }

     return resultMap;

}

這里,在做JavaBean到Map轉化時,用了反射的方法,將對象的所有屬性(包含private final類型)都提取出來,傳給服務端。服務端組件內部,開始時反序列化時,使用的是getField方法查找這個map中的每一個key。如果對象是private final類型是獲取不到的,所以沒有影響。后來組件升級,反序列化時,並沒有使用getField方法,而是使用了getDeclaredField方法,就可以獲取到private final類型的屬性,進行賦值操作的時候就產生了問題。
這個bug經過了一兩年時間才引起了事故。讓人意想不到,恢復和排查的響應時間都會收到影響。

 

后記

能寫出這樣的代碼,究其原因,大致有兩種:一種遇到這個問題,經過搜索資料和思考,覺得這樣可以實現,就沒有做更多的思考;另一種是抱着學習的態度,想用一些之前不常用的技術解決問題。這兩種原因寫出的代碼都是建立在對原理了解不透徹的基礎上,相當危險。
最近在看《山河令》,里面有個詩詞底蘊極高的溫客行。說話時引經據典,天花亂墜。見到周子舒渡船,溫客行說:“但度無所苦,我自迎接汝”。這本是大文豪王獻之寫給他的愛妾桃葉的詩。因為桃葉怕坐船,王獻之就說了:“你只管渡江就好,不用想太多,我自然會在江邊迎接你。”這里溫客行用的隱隱表露出自己的小心思,倒也用的妙。
為了和溫客行做對比,里面還出現了個愛附庸風雅的大白兔:曹蔚寧。小曹喜歡阿湘。於是跟阿湘誇她名字好:“九嶷繽兮並迎,靈之來兮如雲。”句子里沒有出現一個“湘”字。和湘沾邊的是前半句“九嶷繽兮並迎“出自屈原的《九歌.湘夫人》。而后半句是曹植的《洛神賦》。洛神叫甄宓啊,和湘字沒有半毛錢關系,純粹是背詩背串了。所以溫客行說聽小曹背詩,屈原都能被氣活過來。這境界反差出來了吧。
但是強如溫客行,人家在河邊喝水,他本是想打招呼示好的話。他來了一首:“滄浪之水清兮,可以濯我纓;滄浪之水濁兮,可以濯我足。”我只是覺得人家在喝水,你又是洗衣服又是洗腳的,這水喝着真倒胃口。你倒是來一首:“問渠那得清如許?為有源頭活水來。” 也能讓人覺得水的甘甜。或者來首:“秋水清無底,蕭然靜客心。” 也可在這炎炎夏日送上一抹涼意。也難怪周子舒不理他。
溫客行的漏洞可不止這一處,溫客行造了30個假的琉璃甲,帶着周子舒去看狗咬狗。他在屋頂上說的是:“沖天香陣透岳陽,滿城盡是琉璃甲”。這本是黃巢寫菊花的詩:“沖天香陣透長安,滿城盡帶黃金甲。” 你要是改,也要改的徹底一點,人家菊花是香的,香陣一詞用的妙,琉璃甲和香有什么關系嗎?沖天香陣肯定是沒有,沖天的殺氣卻是名副其實。說這么多,無非是想說明,還是要敬畏生產。不了解原理還是不要直接在要上生產的代碼里嘗試。侵入框架底層的代碼最好不要寫,盡量看看能否用寫業務代碼的方式來解決。連溫客行身上都能找到這么多詩詞的錯處,平時咱們寫的業務代碼還怕找不出來Bug?一旦出現生產事故,豈不是丟了排面?

 

推薦閱讀

代碼榮辱觀-以運用風格為榮,以隨意編碼為恥

工作中溝通的4點感悟

知名互聯網公司需要什么樣的人才

《兩地書》--K8s基礎知識


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM