分佈式RPC框架Dubbo實現服務治理:集成Kryo實現高速序列化,集成Hystrix實現熔斷器
- 2021 年 5 月 19 日
- 筆記
- 分佈式架構, 架構
Dubbo+Kryo實現高速序列化
- Dubbo RPC是Dubbo體系中最核心的一種高性能,高吞吐量的遠程調用方式,是一種多路復用的TCP長連接調用:
- 長連接: 避免每次調用新建TCP連接,提高調用的響應速度
- 多路復用: 單個TCP連接可交替傳輸多個請求和響應的消息,降低了連接的等待時間,從而減少了同樣並發數的情況下網絡連接數,提高了系統的雲吞吐量
- Dubbo RPC主要用於兩個Dubbo之間的遠程調用,適合高並發,小數據的互聯網場景.序列化對於遠程調用的響應速度,吞吐量,網絡帶寬消耗等同樣也起着至關重要的作用,是提升分佈式系統性能的最關鍵因素之一
- Dubbo中支持的序列化方式:
- dubbo序列化: 阿里的高效java序列化實現
- hessian2序列化: hessian是一種高效跨語言的二進制序列化方式.這裡不是原生的hessian2序列化,而是阿里修改過的hessian lite,是Dubbo RPC默認啟動的序列化方式
- json序列化: 目前有兩種實現-
- 採用阿里的fastjson庫
- 採用dubbo中實現的簡單json庫
- json這種文本序列化性能不如dubbo序列化,hessian2序列化這兩種二進制序列化
- java序列化: 主要採用JDK自帶的Java序列化實現,性能差
- 序列化方式:
- 針對Java語言的序列化方式:Kryo,FST
- 跨語言的序列化方式:Protostuff,ProtoBuf,Thrift,Avro,MsgPack
序列化:
1.序列化(serialization)在計算機科學的資料處理中,是指將數據結構或物件狀態轉換成可取用格式(例如存成檔案,存於緩衝,或經由網絡中傳送),
以留待後續在相同或另一台計算機環境中,能恢復原先狀態的過程。依照序列化格式重新獲取位元組的結果時,
可以利用它來產生與原始物件相同語義的副本。
2.簡單的來講就是將某種數據結構或者對象轉換成一種數據格式,數據格式可以通過網絡傳送或者存入數據庫中,
同時可以根據數據格式還原出原來的數據結構(反序列化)。在 Java 中,對象只有在 JVM 運行時才會存在,如果想要把對象存儲到本地或者發送到遠程的服務器,
則必須通過序列化將對象轉換成相應的位元組然後進行存儲或者傳送,之後再將位元組組裝成對象。
3.在以下場景中都會遇到序列化:
3.1將對象狀態保存到文件或者數據庫中
3.2通過 socket 在網絡中傳送對象
3.3通過RMI(遠程方法調用)傳輸對象
1.為什麼需要手動註冊,不在配置文件中註冊?
因為要註冊的類往往數量較多,導致配置文件冗長
在沒有好的IDE支持下,配置文件的編寫和重構都比Java類複雜得多
這些註冊的類一般是不需要在項目編譯打包後還需要動態修改的
2.為什麼不用@annotation標註然後系統發現並註冊?
因為annotation只能用來標註你可以修改的類,很多序列化的類是無法修改的(第三方庫,JDK系統和其它項目的類)
3.除了annotation,可以用其它方式來自動註冊被序列化的類,如掃描路徑,自動發現實現
Serializable接口(甚至包括Externalizable)的類並註冊,類路徑上找到Serializable類可能非常多,
可以用package前綴來一定程度限定掃描範圍
在自動註冊機制中,要保證服務提供端和消費端以同樣的順序(或者ID)來註冊類,避免錯位.因為可
被發現然後註冊的類的數量可能都是不一樣的
- 注意:(無參構造函數和Serializable接口)
- 如果被序列化的類,不包含無參構造函數,則會導致Kryo序列化性能降低.因為底層將會使用Java的序列化來透明取代Kryo序列化.儘可能為每一個被序列化的類添加無參構造函數(Java類如果不自定義構造函數,默認就有無參構造函數)
- Kryo和FST都不需要被序列化類實現Serializable接口,但還是需要每個序列化類都去實現Serializable接口,保持和Java序列化以及dubbo序列化兼容性
Dubbo+Hystrix實現服務熔斷
- 熔斷器:
- 在微服務架構中,根據業務拆分成一個個的服務,服務服務之間通過RPC相互調用
- 為了保證高可用,單個服務採用集群部署,由於網絡或者自身的原因,服務不能保證100%可用
- 如果單個服務出現問題,調用這個服務就會出現出現線程阻塞,此時若大量的請求湧入,servlet容器的線程就會被消耗完畢,導致服務癱瘓,服務與服務之間的依賴性會導致故障傳播,進而導致整個微服務癱瘓,這就是”服務雪崩效應”
- 為了解決服務雪崩效應,提出熔斷器的模型
- 熔斷器模型:
- 底層的服務出現故障,會導致連鎖故障
- 當對特定服務調用的不可用到達一個閾值(Hystrix默認5秒20次),熔斷器就會被打開
- 熔斷器打開後,為了避免連鎖故障,通過fallback方法直接返回一個固定值
Dubbo Provider中使用熔斷器
- 在Provider(服務提供者)中增加依賴spring-cloud-starter-netflix-hystrix
- 在主類中標註@EnableHystrix註解
- 在接口實現類的服務調用方法上標註@HystrixCommand註解,調用Hystrix代理
可以在@HystrixCommand中的@HystrixProperty中配置閾值
Dubbo Consumer中使用熔斷器
- 在Consumer(服務消費者)中增加依賴spring-cloud-starter-netflix-hystrix
- 在主類上標註@EnableHystrix註解
- 在調用類controller中的調用方法上標註 @HystrixCommand(fallback=”熔斷返回頁面的方法名”)
Dubbo+Hystrix熔斷器儀錶盤
在Provider和Consumer中都需要配置Hystrix儀錶盤,配置方式一致
Dubbo+Hystrix配置熔斷器儀錶盤
- 增加Hystrix儀錶盤依賴spring-cloud-starter-netflix-hystrix-dashboard
- 在主類上標註@EnableHystrixDashboard註解開啟Hystrix儀錶盤功能
- 創建hystrix.stream(監控路徑)的Servlet配置
@Configuration
public class HystrixDashBoardConfiguration{
@Bean
public ServletRegistrationBean getServlet(){
HystrixMetricsStreamServlet streamServlet=new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean=new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBea.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
Hystrix說明
觸發fallback方法
參數 |
描述 |
FAILURE |
執行拋出異常 |
TIMEOUT |
執行開始,但沒有在指定的時間內完成 |
SHORT_CIRCUITED |
斷路器打開,不嘗試執行 |
THREAD_POOL_REJECTED |
線程池拒絕,不嘗試執行 |
SEMAPHORE_REJECTED |
信號量拒絕,不嘗試執行 |
fallback方法拋出異常
參數 |
描述 |
FALLBACK_FAILURE |
Fallback執行拋出出錯 |
FALLBACK_REJECTED |
Fallback信號量拒絕,不嘗試執行 |
FallBack_MISSING |
沒有Fallback實例 |
Hystrix常用配置信息
超時時間(默認1000ms)
- hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 在Consumer中配置,Provider的所有方法的超時時間都是該值,優先級低於下面的指定配置
- hystrix.command.HystrixCommandKey.execution.isolation.thread.timeoutInMilliseconds: 在Consumer中配置,Provider的指定方法(HystrixCommandKey方法名)的超時時間都是該值
線程池核心線程數
- hystrix.threadpool.default.coreSize: 默認為10,Consumer中配置
- Queue:
- hystrix.threadpool.default.maxQueueSize: 最大排隊長度,默認-1,使用 SynchronousQueue, 其他值使用LinkedBlockingQueue. 如果要從-1換成其他值重啟,即該值不能動態調整,需要使用下邊這個配置
- hystrix.threadpool.default.queueSizeRejectionThreshold: 排隊線程數量閾值,默認為5,達到時拒絕,如果配置了該選項,隊列的大小是該隊列(注意: 如果maxQueueSize=-1的話,則該選項不起作用)
斷路器
- hystrix.command.default.circuitBreaker.requestVolume.Threshold: 當在配置時間窗口內達到此數量的失敗後,進行短路,默認20個
- hystrix.command.default.circuitBreaker.sleepWindowinMilliseconds: 短路一定的時間開始嘗試是否恢復,默認5s
- hystrix.command.default.circuitBreaker.errorThresholdPercentage: 出錯百分比閾值,當達到此閾值後,開始短路,默認50%
fallback
- hystrix.command.default.fallback.isloation.semaphore.maxConcurrentRequests: 調用線程(Consumer)允許請求HystrixCommand.GetFallback()最大數量,默認為10.(注意: 該項配置對於THREAD隔離模式也生效)