Fastjson到了說再見的時候了

專注Java領域分享、成長,拒絕淺嘗輒止
作者A哥(YourBatman)
公衆號:BAT的烏托邦(ID:BAT-utopia)
個人博客https://www.yourbatman.cn,本文已收錄

前言

各位小夥伴大家好,我是A哥。停更1個月後迴歸啦,今天咱們聊聊一個比較有意思的話題:是否真的需要跟Fastjson說再見了?

我的態度

我在CSDN寫過好些篇關於JSON的文章,特別是2020年專門寫了一個付費專欄:享學Jackson


這個專欄“銷量”在我心目中還湊合,4個月“賣出”200份的樣子(雖不值一提,但我很滿足了😄),小小的一個JSON庫而已,熱度可見一斑。專欄裏不可避免的提到了Jackson和Fastjson的比較,我本人一直持中立態度,主要原因有二:

  1. 兩者都很流行(國內Fastjson流行度甚至超過Jackson),因此平時開發中我兩者都用(需要隨大流嘛)
  2. 國產開源軟件是需要被支持的,即使現在還存在差距(聯想下最初的國產手機和蘋果手機的差距,再看看現在呢?)

當然,本文不一樣了,必須得加點料。態度中立並不代表沒有偏向:很明顯我偏向於使用Jackson作爲你的 唯一 JSON庫。



從本文起,我將把CSDN裏該付費專欄全部內容搬到公衆號,免費助你輕鬆擁抱世界上最好的JSON庫:Jackson。
從本文起,我將把CSDN裏該付費專欄全部內容搬到公衆號,免費助你輕鬆擁抱世界上最好的JSON庫:Jackson。
從本文起,我將把CSDN裏該付費專欄全部內容搬到公衆號,免費助你輕鬆擁抱世界上最好的JSON庫:Jackson。

市面上並無成體系介紹Jackson的教程(官網都木有),獨此一家哦。當然嘍,這必將損傷到我的CSDN專欄售賣權益(小錢也是錢嘛😄),所以希望你關注公衆號,關注此專欄,然後學到手我就覺得值了



2020-05-30阿里雲應急響應中心監測到Fastjson爆發新的反序列化遠程代碼執行漏洞,黑客利用漏洞,可繞過autoType限制,直接遠程執行任意命令攻擊服務器,風險極大(話外音:此bug必須Fix)。幸運的是,官方的響應速度非常快:

還記得上一次Fastjson 高級別風險 安全漏洞是什麼時候嗎?是的,它就發生在2019-09-04,兩次相距着實不遠,不滿你說我還記憶猶新呢,我司安全部門發的郵件還能找到😄。

當然,之前也有些漏洞問題,但關注度不如這兩次。主要是這兩次時間相近,危險級別非常高影響面很大,所以社區反應較爲強烈

這兩次“相鄰”的安全漏洞着實把Fastjson推到了風口浪尖,喫瓜羣衆一波接一波,一時間 “棄用Fastjson,擁抱Jackson/Gson” 的聲音不絕於耳。這很容易理解,因爲誰都不情願時不時收到公司安全部門的這種郵件:

針對此漏洞,雖說咱們Fix起來步驟簡單:升級Fastjson的版本,然後重啓應用。看起來毫不費力,實則是個大坑。你是否曾想過這個問題:倘若有上百個、幾百個Java應用呢?且不談你操作上的時間和人力成本有多高,單單管理起來的工作量也不容小覷。所以如果你是技術Leader,胸中的怒火釋放一下是在情理之中的。

相信很少有部門/團隊把Spring Boot應用做成Jar包分離的形式的吧~因此大概率都需要經過升版本 -> 提交代碼 -> 合代碼 -> 上pre -> 上線 -> 驗證等步驟,so還是比較麻煩的


你爲何用Fastjson?

這個問題你可以問自己,也可以問身邊的同事。彙總一下就是答案,這纔是來自用戶最真實的聲音嘛。我針對此也簡單“調查”過,把我聽到的瞭解到的彙總爲如下三點:

  1. API簡單(static方法直接使用),上手快,對開發者友好
  2. 阿里巴巴出品,背靠大廠值得信賴.
  3. 社區相對活躍,維護升級有保障

容我猜猜,這3個理由大概率命中了你心中所想吧😄?有大廠做背書自然能給產品加分,但自身優秀才是硬道理。雖然原因有三點,但我認爲讓很多人決定去使用它、贊它的最最最主要原因其實就一點:API簡單,static方法直接調用對開發者友好

我感覺對於大多數Java Coder(特別對於初學者)來說,使用時會有這樣的一種情節在裏面:靜態方法的逼格比實例方法高。而實際上不應該是這樣子的,初學者(初/中級選手)熱愛使用靜態方法,而高手在設計一個庫/框架時應在靜態方法+實例方法間運用自如。一味地、過多地使用靜態方法只會讓你的的思維傾向於面向過程,而非更好的利用Java 面向對象 的特性,因此高下立判。

沒有孰優孰劣,適合的纔是最好的

發現了沒,使用Fastjson的原因中,我們至始至終都沒有提到性能高/速度快等字眼,但這卻是Fastjson最最最爲核心的特性,可謂是它能立足於衆多JSON庫中、“脫穎而出”的立身之本。豈不怪哉,我們使用它竟不是因爲它最核心的特性有多好,那這是爲何呢?


你爲何仍在用Fastjson?

原因可以說出5678種,總而言之言而總之,你不(敢)切換的原因或許只有一個:Fastjson的靜態方法調用用着省心;最重要的是,對其它JSON庫(如Jackson/Gson)並不熟悉不敢切換。

我認爲害怕來自於未知

不可否認Jackson/Gson的使用門檻的確比Fastjson高那麼一丟丟,但這絕不是你拒絕去使用它的理由。受Fastjson這“連續”兩次高危漏洞影響,A哥更加堅定了把Jackson當作 唯一 JSON庫的決心,甚至在團隊內嚴令禁止使用Fastjson。大家統一了語言/工具,更能提高生產力~

如果你也是因爲不太瞭解Jackson而不敢離開溫室,那麼看到本文就很幸運了,本系列會免費帶你擁抱Jackson這個高級JSON庫,功能上比Fastjson強了不止一點點。


正文

坊間在某壇裏看到這樣一句言論:若你還依賴於使用Fastjson,那麼你大概率還只是初/中級水平。這句話必然讓Fastjson的忠實用戶火冒三丈,抄起傢伙嘎嘎就是幹。話出必然有因,那麼這句話是否真的言過於詞呢?接下來就絮叨絮叨

我很願意用存在即合理原則來表達一個觀點:Fastjson出個bug就能有這麼高的關注度,不可否認這本身就是一種成功。

誤區描述:“合理”請不要誤讀爲“合乎情理”之類,而是當做“理由”來講。“存在即合理”正確理解爲:一切存在的事物都有它存在的理由

任何技術能夠流行起來,well-known被我們所熟知必然有它的優勢,哪怕這個過人之處只有一個。下面我們來看看爲何Fastjson能一步步被寵愛,它的魔力到底在哪?

技術選型不應該像相親:肯定你只需要一個理由,而否定你卻能...


Why Fastjson?

雖然最近Fastjson由於出現安全漏洞,社區言論一邊倒。即使如此,幾乎沒人直接否定過Fastjson本身的優秀,特別是當你知道這個使用廣泛的庫幾乎全部來自於一人之手時。他就是匠人溫少:
圖片來源於開源中國

值得一提的是:溫少另一個開源項目Druid是國內流行的(甚至沒有之一)數據庫連接池產品,廣受好評

成人只看利弊,小孩才分對錯。爲何要使用它能流行開來,那必然是因爲它優秀。它優秀品質在其官網可一覽無遺:
截圖來自於Fastjson官網
這些“優點”用中文描述出來更加直(震)觀(撼):

1、速度快

fastjson相對其他JSON庫的特點是快,從2011年fastjson發佈1.1.x版本之後,其性能從未被其他Java實現的JSON庫超越。

話外音:速度/性能這一塊,Fastjson一直拿捏得死死的

2、使用廣泛

fastjson在阿里巴巴大規模使用,在數萬臺服務器上部署,fastjson在業界被廣泛接受。在2012年被開源中國評選爲最受歡迎的國產開源軟件之一。

話外音:阿里巴巴數以萬計的大規模集羣實例做規模背書,說服力槓槓的

3、測試完備

fastjson有非常多的testcase,在1.2.11版本中,testcase超過3321個。每次發佈都會進行迴歸測試,保證質量穩定。

話外音:單測覆蓋率高,代碼健壯性有保證

4、使用簡單

fastjson的API十分簡潔。

String text = JSON.toJSONString(obj); //序列化
VO vo = JSON.parseObject("{...}", VO.class); //反序列化

話外音:不管你是小白還是小小白,輕鬆上手,使用起來都無障礙

5、功能完備

支持泛型,支持流處理超大文本,支持枚舉,支持序列化和反序列化擴展。

話外音:我這一家就夠了,你要的,這都有


Why Not Fastjson?


文首有表態本文我是有態度和有偏向的,因此不來幾點原因實則不妥。那麼我就針對於官網列出的5點(見上),給出個人觀點供以參考。是否言過於辭,咱們拿出另外一個JSON庫做出對比,本文以Jackson爲例。


版本約定

因爲要做比較嘛,所以對使用的JSON庫做出版本約定:

  • Jackson:2.10.1
    • 演示代碼均使用最常用的高層API,而非底層API。畢竟用底層API去PK Fastjson並不公平,畢竟那並不常用
  • Fastjson:1.2.72
    • only one jar

1、速度上並沒有那麼的快

速度快/性能高是Fastjson 最最最最最最 大的“賣點”,可謂是立身之本,從它的命名以及它的logo設計上你都能感受到這一點。

沒有調研就沒有發言權,本文針對於最常用的使用場景來一波測試對比(對比儘量公正,切勿鑽牛角尖)。關於Fastjson和Jackson在性能PK這一塊,網上的案例有不少,我自己也書寫了多個場景的比較代碼。但最終我還是決定引用Robin的結果展示給大家,我看了他的測試方案(代碼)更加專業些:幾種常用 JSON 庫性能比較,結論如下兩張圖

序列化
反序列化
總的結論:除了Json-lib是來搞笑的(它早已停止更新,切勿在生產上使用),Fastjson、Jsckson、Gson三者不分伯仲,差異性較小。

綜合各種測試case,網上的 + 我自己寫的測試用例,三者在性能方面除了Gson稍微差點外,Jackson和Fastjson在速度上可認爲是差不多的(甚至Jackson綜合性能表現更好)

既然差異性這麼小,Fastjson一味的強調它是最快的真的有意義嗎?


JSON的解析速度絕不會制約系統的性能

比如我們一次REST調用環節全流程可能100ms;其中操作一次數據庫,可能需要幾十ms;序列化反序列化一次json 一般只需要幾ms;也就是說不同的json庫,性能相差都在毫秒間;在一次REST調用全流程裏,不同的JSON庫在性能表現上影響甚微。

在現代應用程序中,即使最慢的Gson,也是滿足需求的;解析文檔速度的快慢,並不能作爲選型的唯一標準,可能連主要標準都算不上。對IO優化、網絡優化、並行處理等優化措施,遠比選用一個更快的庫更有效。

言而總之,如果你選擇一個JSON庫把性能當作了一個標準,就犯了方向性的錯誤。


2、並沒有那麼的流行

使用廣不廣泛、流行度有多高這玩意是相對的。有一個最直觀的數據,那就是在Maven中的引用量,我截圖如下:



從usages數值上看,似乎不在一個量級上。當然這麼比較我個人認爲不算特別客觀,主要原因有二:

  1. 開源的技術發展的越早,使用者越多,主流框架越支持(比如Spring MVC內置Jackson支持),就會形成聚集效應,贏者通喫
  2. Fastjson起步較晚,且主要發力於國內

不可否認Fastjson在國內的流行度是非常高的,甚至超過Jackson。否則最近一次的安全漏洞也不會有那麼多人喫瓜嘛,但是這種“使用廣泛”你也得辯證性的去看,畢竟在中國Java領域裏,阿里巴巴是絕對的執牛耳者。

Fastjson的流行,是有着內在的原因的,比如這個無奈:


3、測試真的完備嗎?

額,這個我只能說:Fastjson自己知道就成,並無必要當作亮點show出來,畢竟使用者只關心出bug、出漏洞的頻率和嚴重性,並不關心工程內部是如何保證健壯性的。

在使用者眼中:不出bug,一行單測沒有都沒關係。出了嚴重bug,有上萬個test case也難以讓人信服。


4、API真的簡單嗎?

答:真的。文上有解釋,這也許可能大概是你選擇使用Jackson作爲JSON庫最重要的理由。

當然,API使用簡單針對於simple場景,對於複雜場景它也並不能簡單應對。道理很簡單,POP is simple,OOP is Complex。但恰好的是,在互聯網應用場景中使用JSON庫,大多屬於簡單場景,因此Fastjson把它當做一個亮點我覺得是無可厚非的。


5、功能並沒有那麼完備

官網強調了它是支持泛型、枚舉等類型的序列化、反序列化的。但是對着JavaBean + JSON規範來講,Fastjson有不少功能缺失(沒遵循規範),這是A哥最爲忍受不了的地方,因爲它已經不能實現我的功能了。如果你基於它做過中間件開發、框架開發或者是DDD驅動設計開發,相信你也深有體會:


總結

真理是相對的,沒有絕對的真理。真理是讓人明白道理的,不是用來詭辯的,更不是用來擡扛的。

同樣的,Fastjson還是Jackson也就沒有標準的答案,各位還是結合自己的具體情況,見仁見智。本文只是闡述我的個人觀點,表達了我的使用傾向,供以你決策時參考。

如果你和我一樣,也想把Jackson作爲你的唯一 JSON庫,那就關注我吧,接下來我會把付費專欄裏的內容全部搬過來給你,免費助你平滑過渡到這個世界上最好的JSON庫。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章