使用protostuff自定義編解碼器優化springcloud-feign性能

前言

Spring Cloud feign是僞RPC方式解決微服務間的調用。翻看FeignCloudFeign源碼,能夠看到Feign默認使用HttpUrlConnection; 代碼在DefaultFeignLoadBalancedConfiguration 的Client.Default。html

這裏特地說明下,其餘替代方式有OKhttp和HTTPClient,這兩種方式有鏈接池,能夠減小建立鏈接的性能損耗,可是多家實測效果代表,HttpUrlConnection的效率上是最高的,這也是feign默認的緣由,若是在輕型應用不考慮速度考慮CPU的狀況下,能夠考慮替換成OKhttp和HttpClient。git

在序列化方面,springboot中HttpMessageConverters 默認使用jackson2方式進行序列化和反序列化。 jackson的效率在於GSON和fastjson之上。github

正常狀況下使用jackson2支持先後端開發基本沒有什麼問題,可是若是是微服務間頻頻通訊,使用jackson2序列化和反序列化會佔用很多系統資源,而且效率較差。 這裏有個git地址來對比各類序列化和反序列化框架的性能 https://github.com/eishay/jvm-serializers/wiki,部份內容以下:web


Ser Time+Deser Time (ns)



Size, Compressed size [light] in bytesspring

 

 

 

可見jackson在各類測試中都不佔優點,網上如今不少的教程使用protobuf來替換jackson提高feign的性能,可是因爲nafos中使用的是更加方便的protostuff,並且由圖中能夠看出protostuff的性能比protobuf更勝一籌。因此我決定用protostuff來替換。shell

在feign中,protobuff有默認提供的編解碼器,所以參考其餘教程使用便可,可是protostuf卻沒有默認提供,因此咱們必須本身動手擼了。

數據庫

在手擼以前,咱們確定是須要先了解protostuff和feign提供的protobuf編解碼器的,畢竟protostuff的編解碼器,在網上貌似還沒得教程。json

Protostuff在這裏就不作贅述,能夠參考我博客的另外一篇文章:http://www.javashuo.com/article/p-xnhsiprm-mr.html後端

 

經過查看feign提供的protobuff編解碼器的源碼,能夠看到他是繼承AbstractHttpMessageConverter<Object>,主要實現了supports,readInternal,writeInternal這三個方法。分別是返回類的校驗,解碼器,和編碼器。tomcat

代碼以下:

/**
 * @Author 黃新宇
 * @Date 2018/10/30 下午1:24
 * @Description feign調用中protostuff編解碼器
 **/
public class ProtostuffHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
    private static final Logger logger = LoggerFactory.getLogger(ProtostuffHttpMessageConverter.class); public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); public static final MediaType PROTOBUF; static { PROTOBUF = new MediaType("application", "x-protobuf", DEFAULT_CHARSET); } public ProtostuffHttpMessageConverter() { super(new MediaType[]{PROTOBUF, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}); } @Override protected boolean supports(Class<?> aClass) { return Object.class.isAssignableFrom(aClass); } @Override protected Object readInternal(Class<?> aClass, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { MediaType contentType = inputMessage.getHeaders().getContentType(); if (contentType == null) { contentType = PROTOBUF; } if (!PROTOBUF.isCompatibleWith(contentType)) { logger.error("不支持的解碼格式,請用x-protobuf做爲contentType"); } try { return ProtoUtil.deserializeFromByte(inputMessage.getBody(),aClass); } catch (Exception var7) { throw new HttpMessageNotReadableException("Could not read Protobuf message: " + var7.getMessage(), var7); } } @Override protected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { MediaType contentType = outputMessage.getHeaders().getContentType(); if (contentType == null) { contentType = PROTOBUF; } Charset charset = contentType.getCharset(); if (charset == null) { charset = DEFAULT_CHARSET; } if (!PROTOBUF.isCompatibleWith(contentType)) { logger.error("不支持的編碼格式,請用x-protobuf做爲contentType"); } FileCopyUtils.copy(ProtoUtil.serializeToByte(object), outputMessage.getBody()); } }

 

 

用法:

添加以下配置,ProtostuffHttpMessageConverter在nafos.remote.feign.ProtostuffHttpMessageConverter下

View Code

 

而後在須要用protostuff的feignClient上註明configuration = ProtoFeignConfiguration.class)便可

@FeignClient(value = "service",path ="/nafosRemoteCall/test" , configuration = ProtoFeignConfiguration.class)

 

詳細代碼請參考nafos-network: https://gitee.com/huangxinyu/BC-NETTYGO

 


 

NAFOS

一個基於netty的輕量級高性能服務端框架。 

簡介

nafos是一個基於netty的高性能服務器框架,其目的在於易上手,易擴展,讓開發人員更致力於業務開發。 在先後端分離的web架構上,或者APP,手遊,nafos都是一個很不錯的選擇。

除此以外,sample中也給出了超簡單的擴展方案,使得nafos在分佈式擴展上能更勝一籌。

文檔

特色

    • 一、簡單易用:經過簡單的配置文件便可創建完善的啓動方案,而後就能夠開心的關注業務代碼了;
    • 二、串行設計 :單用戶的全部請求都是串行進行,完美解決單用戶併發問題,減小鎖的使用;
    • 三、高性能:網絡層採用netty做爲中間件,同等配置及優化條件下,相比tomcat性能可提高一倍;
    • 四、易擴展:整合了springBoot,可完美支持spring你們族系列;
    • 五、強兼容: 可單機同時支持HTTP,TCP,websocket等服務,小規模應用下不用多開佔用資源;
    • 六、工具類豐富:封裝全部開發中常見工具類可直接調用;
    • 七、房間策略:封裝常見遊戲的房間策略,開房,比賽,聊天可直接調用,無需多寫;
    • 八、模塊化:多個模塊之間相互解耦,喜歡哪一個用哪一個,不喜歡直接丟棄。
    • 九、腳本支持:內有現成的shell腳本能夠直接使用,開關機,數據庫備份等;
    • 十、自帶分佈式限流器,有IP策略和總流量策略等漏桶限流,抵禦攻擊。
    • 十一、自帶protostuff的feign編解碼器,操做簡單的同時能夠極大程度優化feign端對端的通訊問題。
    • 十二、封裝了kafa和rabbitMQ,工具類通常超簡單使用,無需關注內部業務;
    • 1三、豐富教程:除了詳細文檔外,在sample模塊中還有多模塊使用案例,開發無憂~
相關文章
相關標籤/搜索