自從在園子里,發(fā)表了兩篇如何基于Netty構(gòu)建RPC服務(wù)器的文章:談?wù)勅绾问褂肗etty開發(fā)實(shí)現(xiàn)高性能的RPC服務(wù)器、Netty實(shí)現(xiàn)高性能RPC服務(wù)器優(yōu)化篇之消息序列化 之后,收到了很多同行、園友們熱情的反饋和若干個(gè)優(yōu)化建議,于是利用閑暇時(shí)間,打算對(duì)原來NettyRPC中不合理的模塊進(jìn)行重構(gòu),并且增強(qiáng)了一些特性,主要的優(yōu)化點(diǎn)如下:
- 在原來編碼解碼器:JDK原生的對(duì)象序列化方式、kryo、hessian,新增了:protostuff。
- 優(yōu)化了NettyRPC服務(wù)端的線程池模型,支持LinkedBlockingQueue、ArrayBlockingQueue、SynchronousQueue,并擴(kuò)展了多個(gè)線程池任務(wù)處理策略。
- RPC服務(wù)啟動(dòng)、注冊(cè)、卸載支持,通過Spring中自定義的nettyrpc標(biāo)簽進(jìn)行統(tǒng)一管理。
現(xiàn)在重點(diǎn)整理一下重構(gòu)思路、經(jīng)驗(yàn),記錄下來。對(duì)應(yīng)源代碼代碼,大家可以查看我的開源github:https://github.com/tang-jie/NettyRPC 項(xiàng)目中的NettyRPC 2.0目錄。
在最早的NettyRPC消息編解碼插件中,我使用的是:JDK原生的對(duì)象序列化(ObjectOutputStream/ObjectInputStream)、Kryo、Hessian這三種方式,后續(xù)有園友向我提議,可以引入Protostuff序列化方式。經(jīng)過查閱網(wǎng)絡(luò)的相關(guān)資料,Protostuff基于Google protobuf,但是提供了更多的功能和更簡(jiǎn)易的用法。原生的protobuff是需要數(shù)據(jù)結(jié)構(gòu)的預(yù)編譯過程,需要編寫.proto格式的配置文件,再通過protobuf提供的工具翻譯成目標(biāo)語言代碼,而Protostuff則省略了這個(gè)預(yù)編譯的過程。以下是Java主流序列化框架的性能測(cè)試結(jié)果(圖片來自網(wǎng)絡(luò)):
可以發(fā)現(xiàn),Protostuff序列化確實(shí)是一種很高效的序列化框架,相比起其他主流的序列化、反序列化框架,其序列化性能可見一斑。如果用它來進(jìn)行RPC消息的編碼、解碼工作,再合適不過了?,F(xiàn)在貼出具體的Protostuff序列化編解碼器的實(shí)現(xiàn)代碼。
首先是定義Schema,這個(gè)是因?yàn)镻rotostuff-Runtime實(shí)現(xiàn)了無需預(yù)編譯對(duì)java bean進(jìn)行protobuf序列化/反序列化的能力。我們可以把運(yùn)行時(shí)的Schema緩存起來,提高序列化性能。具體實(shí)現(xiàn)類SchemaCache代碼如下: