大數(shù)據(jù)服務(wù)上云的思考">大數(shù)據(jù)服務(wù)上云的思考
951
2022-05-28
Dubbo+Kryo實現(xiàn)高速序列化
Dubbo RPC是Dubbo體系中最核心的一種高性能,高吞吐量的遠程調(diào)用方式,是一種多路復(fù)用的TCP長連接調(diào)用:
長連接: 避免每次調(diào)用新建TCP連接,提高調(diào)用的響應(yīng)速度
多路復(fù)用: 單個TCP連接可交替?zhèn)鬏敹鄠€請求和響應(yīng)的消息,降低了連接的等待時間,從而減少了同樣并發(fā)數(shù)的情況下網(wǎng)絡(luò)連接數(shù),提高了系統(tǒng)的云吞吐量
Dubbo RPC主要用于兩個Dubbo之間的遠程調(diào)用,適合高并發(fā),小數(shù)據(jù)的互聯(lián)網(wǎng)場景.序列化對于遠程調(diào)用的響應(yīng)速度,吞吐量,網(wǎng)絡(luò)帶寬消耗等同樣也起著至關(guān)重要的作用,是提升分布式系統(tǒng)性能的最關(guān)鍵因素之一
Dubbo中支持的序列化方式:
dubbo序列化: 阿里的高效java序列化實現(xiàn)
hessian2序列化: hessian是一種高效跨語言的二進制序列化方式.這里不是原生的hessian2序列化,而是阿里修改過的hessian lite,是Dubbo RPC默認啟動的序列化方式
json序列化: 目前有兩種實現(xiàn)-
采用阿里的fastjson庫
采用dubbo中實現(xiàn)的簡單json庫
json這種文本序列化性能不如dubbo序列化,hessian2序列化這兩種二進制序列化
java序列化: 主要采用JDK自帶的Java序列化實現(xiàn),性能差
序列化方式:
針對Java語言的序列化方式:Kryo,FST
跨語言的序列化方式:Protostuff,ProtoBuf,Thrift,Avro,MsgPack
序列化: 1.序列化(serialization)在計算機科學(xué)的資料處理中,是指將數(shù)據(jù)結(jié)構(gòu)或物件狀態(tài)轉(zhuǎn)換成可取用格式(例如存成檔案,存于緩沖,或經(jīng)由網(wǎng)絡(luò)中傳送), 以留待后續(xù)在相同或另一臺計算機環(huán)境中,能恢復(fù)原先狀態(tài)的過程。依照序列化格式重新獲取字節(jié)的結(jié)果時, 可以利用它來產(chǎn)生與原始物件相同語義的副本。 2.簡單的來講就是將某種數(shù)據(jù)結(jié)構(gòu)或者對象轉(zhuǎn)換成一種數(shù)據(jù)格式,數(shù)據(jù)格式可以通過網(wǎng)絡(luò)傳送或者存入數(shù)據(jù)庫中, 同時可以根據(jù)數(shù)據(jù)格式還原出原來的數(shù)據(jù)結(jié)構(gòu)(反序列化)。在 Java 中,對象只有在 JVM 運行時才會存在,如果想要把對象存儲到本地或者發(fā)送到遠程的服務(wù)器, 則必須通過序列化將對象轉(zhuǎn)換成相應(yīng)的字節(jié)然后進行存儲或者傳送,之后再將字節(jié)組裝成對象。 3.在以下場景中都會遇到序列化: 3.1將對象狀態(tài)保存到文件或者數(shù)據(jù)庫中 3.2通過 socket 在網(wǎng)絡(luò)中傳送對象 3.3通過RMI(遠程方法調(diào)用)傳輸對象
在面向生產(chǎn)的環(huán)境中,使用Dubbo+Kryo實現(xiàn)序列化:
引入Kryo依賴kryo-serializers
配置文件中增加配置
dubbo.protocol. serialization=kryo
注冊被序列化類
要讓Kryo發(fā)揮高性能,需要將需要被序列化的實體類注冊到Dubbo系統(tǒng)中,實現(xiàn)如下回調(diào)接口:
public class SerializationOptimizerImpl implements SerializationOptimizerImpl{ public Collection
配置文件中增加配置
dubbo.protocol.optimizer=com.oxford.SerializationOptimizerImpl
注冊這些類后,序列化的性能大大提升,特別是針對小數(shù)量的嵌套對象
1.為什么需要手動注冊,不在配置文件中注冊? 因為要注冊的類往往數(shù)量較多,導(dǎo)致配置文件冗長 在沒有好的IDE支持下,配置文件的編寫和重構(gòu)都比Java類復(fù)雜得多 這些注冊的類一般是不需要在項目編譯打包后還需要動態(tài)修改的 2.為什么不用@annotation標注然后系統(tǒng)發(fā)現(xiàn)并注冊? 因為annotation只能用來標注你可以修改的類,很多序列化的類是無法修改的(第三方庫,JDK系統(tǒng)和其它項目的類) 3.除了annotation,可以用其它方式來自動注冊被序列化的類,如掃描路徑,自動發(fā)現(xiàn)實現(xiàn) Serializable接口(甚至包括Externalizable)的類并注冊,類路徑上找到Serializable類可能非常多, 可以用package前綴來一定程度限定掃描范圍 在自動注冊機制中,要保證服務(wù)提供端和消費端以同樣的順序(或者ID)來注冊類,避免錯位.因為可 被發(fā)現(xiàn)然后注冊的類的數(shù)量可能都是不一樣的
==注意:==(無參構(gòu)造函數(shù)和Serializable接口)
如果被序列化的類,不包含無參構(gòu)造函數(shù),則會導(dǎo)致Kryo序列化性能降低.因為底層將會使用Java的序列化來透明取代Kryo序列化.盡可能為每一個被序列化的類添加無參構(gòu)造函數(shù)(Java類如果不自定義構(gòu)造函數(shù),默認就有無參構(gòu)造函數(shù))
Kryo和FST都不需要被序列化類實現(xiàn)Serializable接口,但還是需要每個序列化類都去實現(xiàn)Serializable接口,保持和Java序列化以及dubbo序列化兼容性
Dubbo+Hystrix實現(xiàn)服務(wù)熔斷
熔斷器:
在微服務(wù)架構(gòu)中,根據(jù)業(yè)務(wù)拆分成一個個的服務(wù),服務(wù)服務(wù)之間通過RPC相互調(diào)用
為了保證高可用,單個服務(wù)采用集群部署,由于網(wǎng)絡(luò)或者自身的原因,服務(wù)不能保證100%可用
如果單個服務(wù)出現(xiàn)問題,調(diào)用這個服務(wù)就會出現(xiàn)出現(xiàn)線程阻塞,此時若大量的請求涌入,servlet容器的線程就會被消耗完畢,導(dǎo)致服務(wù)癱瘓,服務(wù)與服務(wù)之間的依賴性會導(dǎo)致故障傳播,進而導(dǎo)致整個微服務(wù)癱瘓,這就是"服務(wù)雪崩效應(yīng)"
為了解決服務(wù)雪崩效應(yīng),提出熔斷器的模型
熔斷器模型:
底層的服務(wù)出現(xiàn)故障,會導(dǎo)致連鎖故障
當對特定服務(wù)調(diào)用的不可用到達一個閾值(Hystrix默認5秒20次),熔斷器就會被打開
熔斷器打開后,為了避免連鎖故障,通過fallback方法直接返回一個固定值
Dubbo Provider中使用熔斷器
在Provider(服務(wù)提供者)中增加依賴spring-cloud-starter-netflix-hystrix
在主類中標注@EnableHystrix注解
在接口實現(xiàn)類的服務(wù)調(diào)用方法上標注@HystrixCommand注解,調(diào)用Hystrix代理
可以在@HystrixCommand中的@HystrixProperty中配置閾值
Dubbo Consumer中使用熔斷器
在Consumer(服務(wù)消費者)中增加依賴spring-cloud-starter-netflix-hystrix
在主類上標注@EnableHystrix注解
在調(diào)用類controller中的調(diào)用方法上標注 @HystrixCommand(fallback=“熔斷返回頁面的方法名”)
Dubbo+Hystrix熔斷器儀表盤
在Provider和Consumer中都需要配置Hystrix儀表盤,配置方式一致
Dubbo+Hystrix配置熔斷器儀表盤
增加Hystrix儀表盤依賴spring-cloud-starter-netflix-hystrix-dashboard
在主類上標注@EnableHystrixDashboard注解開啟Hystrix儀表盤功能
創(chuàng)建hystrix.stream(監(jiān)控路徑)的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說明
觸發(fā)fallback方法
fallback方法拋出異常
Hystrix常用配置信息
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 在Consumer中配置,Provider的所有方法的超時時間都是該值,優(yōu)先級低于下面的指定配置
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換成其他值重啟,即該值不能動態(tài)調(diào)整,需要使用下邊這個配置
hystrix.threadpool.default.queueSizeRejectionThreshold: 排隊線程數(shù)量閾值,默認為5,達到時拒絕,如果配置了該選項,隊列的大小是該隊列(==注意:== 如果maxQueueSize=-1的話,則該選項不起作用)
hystrix.command.default.circuitBreaker.requestVolume.Threshold: 當在配置時間窗口內(nèi)達到此數(shù)量的失敗后,進行短路,默認20個
hystrix.command.default.circuitBreaker.sleepWindowinMilliseconds: 短路一定的時間開始嘗試是否恢復(fù),默認5s
hystrix.command.default.circuitBreaker.errorThresholdPercentage: 出錯百分比閾值,當達到此閾值后,開始短路,默認50%
hystrix.command.default.fallback.isloation.semaphore.maxConcurrentRequests: 調(diào)用線程(Consumer)允許請求HystrixCommand.GetFallback()最大數(shù)量,默認為10.(==注意:== 該項配置對于THREAD隔離模式也生效)
Dubbo RPC 分布式
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應(yīng)法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。