Springcloud的性能問(wèn)題
應(yīng)用服務(wù)組件調(diào)優(yōu)
Servlet 容器 優(yōu)化
Feign 配置優(yōu)化
Gateway組件調(diào)優(yōu)
Zuul配置 優(yōu)化
hystrix配置 優(yōu)化
ribbon 優(yōu)化
Springcloud的性能問(wèn)題
Springcloud 原始的配置,性能是很低的,大家可以使用Jmeter測(cè)試一下,QPS不會(huì)到50。要做到高并發(fā),需要做不少的配置優(yōu)化,主要的配置優(yōu)化有以下幾點(diǎn):
Feign 配置優(yōu)化
hystrix配置 優(yōu)化
ribbon 優(yōu)化
Servlet 容器 優(yōu)化
Zuul配置 優(yōu)化
應(yīng)用服務(wù)組件調(diào)優(yōu)
Servlet 容器 優(yōu)化
默認(rèn)情況下,Spring Boot 使用 Tomcat 來(lái)作為內(nèi)嵌的 Servlet 容器,可以將 Web 服務(wù)器切換到 Undertow 來(lái)提高應(yīng)用性能,Undertow 是紅帽公司開(kāi)發(fā)的一款基于 NIO 的高性能 Web 嵌入式
Zuul使用的內(nèi)置容器默認(rèn)是Tomcat,可以將其換成undertow,可以顯著減少線程的數(shù)量,替換方式即在pom中添加以下內(nèi)容:
第一步,移除Tomcat 依賴(lài)
org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-tomcat
第二步,增加Untertow 依賴(lài)
org.springframework.boot spring-boot-starter-undertow
第三步,Undertow 的屬性配置
server: undertow: io-threads:16 worker-threads:256 buffer-size:1024 buffers-per-region:1024 direct-buffers:true
server.undertow.io-threads: 設(shè)置IO線程數(shù), 它主要執(zhí)行非阻塞的任務(wù),它們會(huì)負(fù)責(zé)多個(gè)連接, 默認(rèn)設(shè)置每個(gè)CPU核心一個(gè)線程,不要設(shè)置過(guò)大,如果過(guò)大,啟動(dòng)項(xiàng)目會(huì)報(bào)錯(cuò):打開(kāi)文件數(shù)過(guò)多
server.undertow.worker-threads`:阻塞任務(wù)線程池,當(dāng)執(zhí)行類(lèi)似servlet請(qǐng)求阻塞IO操作,undertow會(huì)從這個(gè)線程池中取得線程,它的值設(shè)置取決于系統(tǒng)線程執(zhí)行任務(wù)的阻塞系數(shù),默認(rèn)值是`IO線程數(shù)*8
server.undertow.buffer-size: 以下的配置會(huì)影響buffer,這些buffer會(huì)用于服務(wù)器連接的IO操作,有點(diǎn)類(lèi)似netty的池化內(nèi)存管理,每塊buffer的空間大小,越小的空間被利用越充分,不要設(shè)置太大,以免影響其他應(yīng)用,合適即可
server.undertow.buffers-per-region`:每個(gè)區(qū)分配的buffer數(shù)量,所以pool的大小是`buffer-size*buffers-per-region
server.undertow.direct-buffers: 是否分配的直接內(nèi)存(NIO直接分配的堆外內(nèi)存)
Feign 配置優(yōu)化
feign 默認(rèn)不啟用hystrix,需要手動(dòng)指定 feign.hystrix.enabled=true 開(kāi)啟熔斷
feign 啟用壓縮也是一種有效的性能優(yōu)化方式,具體的配置如下
feign: compression: request: enabled:true mime-types:text/xml,application/xml,application/json response: enabled:true
feign HTTP請(qǐng)求方式選擇
feign默認(rèn)使用的是基于JDK提供的URLConnection調(diào)用HTTP接口,不具備連接池,所以資源開(kāi)銷(xiāo)上有點(diǎn)影響,經(jīng)測(cè)試JDK的URLConnection比Apache HttpClient快很多倍。Apache HttpClient和okhttp都支持配置連接池功能,也可以使用okhttp請(qǐng)求方式。
當(dāng)使用HttpClient時(shí),可如下設(shè)置:
feign: httpclient: enabled:true max-connections:1000 max-connections-per-route:200
當(dāng)使用OKHttp時(shí),可如下設(shè)置:
feign: okhttp: enabled:true httpclient: max-connections:1000 max-connections-per-route:200
max-connections 設(shè)置整個(gè)連接池最大連接數(shù)(該值默認(rèn)為200), 根據(jù)自己的場(chǎng)景決定
max-connections-per-route 設(shè)置路由的默認(rèn)最大連接(該值默認(rèn)為50),限制數(shù)量實(shí)際使用
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶(hù)小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶(hù)、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能
項(xiàng)目地址:https://github.com/YunaiV/yudao-cloud
視頻教程:https://doc.iocoder.cn/video/
Gateway組件調(diào)優(yōu)
Zuul配置 優(yōu)化
我們知道Hystrix有隔離策略:THREAD 以及SEMAPHORE ,默認(rèn)是 SEMAPHORE 。
Zuul默認(rèn)是使用信號(hào)量隔離,并且信號(hào)量的大小是100,請(qǐng)求的并發(fā)線程超過(guò)100就會(huì)報(bào)錯(cuò),可以調(diào)大該信號(hào)量的最大值來(lái)提高性能,配置如下:
zuul: semaphore: max-semaphores:5000
表示,當(dāng)Zuul的隔離策略為SEMAPHORE時(shí),設(shè)置指定服務(wù)的最大信號(hào)量為5000。對(duì)于特定的微服務(wù),可以通過(guò)下面的方式,設(shè)置最大信號(hào)量
設(shè)置默認(rèn)最大信號(hào)量:
zuul: semaphore: max-semaphores:5000#默認(rèn)值
設(shè)置指定服務(wù)的最大信號(hào)量:
zuul: eureka: : semaphore: max-semaphores:5000
為了方便ThreadLocal的使用,也可以改為使用線程隔離的策略,這種場(chǎng)景下,就需要調(diào)大hystrix線程池線程大小,該線程池默認(rèn)10個(gè)線程,調(diào)整的配置示例如下:
zuul: ribbonIsolationStrategy:THREAD hystrix: threadpool: default: coreSize:100 maximumSize:400 allowMaximumSizeToDivergeFromCoreSize:true maxQueueSize:-1
hystrix.threadpool.default.allowMaximumSizeToDivergeFromCoreSize:是否讓maximumSize生效,false的話(huà)則只有coreSize會(huì)生效
hystrix.threadpool.default.maxQueueSize:線程池的隊(duì)列大小,-1代表使用SynchronousQueue隊(duì)列
hystrix.threadpool.default.maximumSize:最大線程數(shù)量
hystrix.threadpool.default.allowMaximumSizeToDivergeFromCoreSize:是否讓maximumSize生效,false的話(huà)則只有coreSize會(huì)生效
hystrix.threadpool.default.maxQueueSize:線程池的隊(duì)列大小,-1代表使用SynchronousQueue隊(duì)列
zuul.ribbon-isolation-strategy:設(shè)置線程隔離,thread 線程隔離,SEMAPHORE 表示信號(hào)量隔離
默認(rèn)配置都可以去HystrixThreadPoolProperties和ZuulProperties這兩個(gè)java文件中查找
hystrix配置 優(yōu)化
首先需要設(shè)置參數(shù)hystrix.threadpool.default.coreSize 來(lái)指定熔斷隔離的線程數(shù),這個(gè)數(shù)需要調(diào)優(yōu),經(jīng)測(cè)試線程數(shù)我們?cè)O(shè)置為和提供方的容器線程差不多,吞吐量高許多。
其次,啟用Hystrix后,很多服務(wù)當(dāng)?shù)谝淮卧L問(wèn)的時(shí)候都會(huì)失敗 是因?yàn)槌跏蓟?fù)載均衡一系列操作已經(jīng)超出了超時(shí)時(shí)間了,因?yàn)槟J(rèn)的超時(shí)時(shí)間為1S,需要修改超時(shí)時(shí)間參數(shù),方可解決這個(gè)問(wèn)題。
參考的hystrix配置如下:
hystrix: threadpool: default: coreSize:500 command: default: circuitBreaker: requestVolumeThreshold:1000 fallback: enabled:true execution: isolation: thread: timeoutInMilliseconds:100000
hystrix.command.default: 全局的作用域,作用的所有的hystrix的客戶(hù)端,如果需要對(duì)某個(gè)微服務(wù),可以寫(xiě)serviceId
hystrix.command.default.fallback.enabled 是否開(kāi)啟回退方法
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 請(qǐng)求處理的超時(shí)時(shí)間,缺省為1000,表示默認(rèn)的超時(shí)時(shí)間為1S
hystrix.threadpool.default.coreSize 核心線程池?cái)?shù)量
hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests 回退最大線程數(shù)
hystrix.command.default.circuitBreaker.requestVolumeThreshold 熔斷器失敗的個(gè)數(shù),進(jìn)入熔斷器的請(qǐng)求達(dá)到1000時(shí)服務(wù)降級(jí)(之后的請(qǐng)求直接進(jìn)入熔斷器)
ribbon 優(yōu)化
Ribbon進(jìn)行客戶(hù)端負(fù)載均衡的Client并不是在服務(wù)啟動(dòng)的時(shí)候就初始化好的,而是在調(diào)用的時(shí)候才會(huì)去創(chuàng)建相應(yīng)的Client,所以第一次調(diào)用的耗時(shí)不僅僅包含發(fā)送HTTP請(qǐng)求的時(shí)間,還包含了創(chuàng)建RibbonClient的時(shí)間,這樣一來(lái)如果創(chuàng)建時(shí)間速度較慢,同時(shí)設(shè)置的超時(shí)時(shí)間又比較短的話(huà),很容易就會(huì)出現(xiàn)上面所描述的顯現(xiàn)。
因此我們可以通過(guò)設(shè)置:
ribbon: eager-load: enabled:true clients:service-1,service-2,service-n
參數(shù)說(shuō)明:
ribbon.eager-load.enabled : 開(kāi)啟Ribbon的饑餓加載模式
ribbon.eager-load.clients: 指定需要饑餓加載的服務(wù)名,如果不指定服務(wù)名稱(chēng),饑餓加載模式無(wú)效
Zuul的饑餓加載,沒(méi)有設(shè)計(jì)專(zhuān)門(mén)的參數(shù)來(lái)配置,而是直接采用了讀取路由配置來(lái)進(jìn)行饑餓加載。所以,如果我們使用默認(rèn)路由,而沒(méi)有通過(guò)配置的方式指定具體路由規(guī)則,那么 zuul.ribbon.eager-load.enabled=true 的配置就沒(méi)有什么作用了。
如果需要真正啟用Zuul 的饑餓加載,需要通過(guò)zuul.ignored-services=*來(lái)忽略所有的默認(rèn)路由,讓所有路由配置均維護(hù)在配置文件中,以達(dá)到網(wǎng)關(guān)啟動(dòng)的時(shí)候就加載好各個(gè)路由的負(fù)載均衡對(duì)象。
關(guān)于Zuul 的默認(rèn)路由,這里詳細(xì)介紹一下。假設(shè)你的注冊(cè)服務(wù)中心有三個(gè)已經(jīng)注冊(cè)的服務(wù)名稱(chēng)service-a,service-b,service-c。但是在zuul配置文件中,只映射了service-a,service-b,如下:
zuul: ribbon: eager-load: enabled:true ignored-services:‘*’ routes: a: path:/a/** serviceId:service-a b: path:/b/** serviceId:service-b
這里,雖然沒(méi)有配置service-c的映射,但是,由于zuul有默認(rèn)的映射機(jī)制,還是可以通過(guò)Url,訪問(wèn)到你的service-c服務(wù),如果不想向外界暴露默認(rèn)的服務(wù)映射,可以加上 zuul.ignored-services:*
審核編輯:劉清
-
URL
+關(guān)注
關(guān)注
0文章
138瀏覽量
15272 -
JAVA語(yǔ)言
+關(guān)注
關(guān)注
0文章
138瀏覽量
20055 -
QPS
+關(guān)注
關(guān)注
0文章
24瀏覽量
8782 -
HTTP接口
+關(guān)注
關(guān)注
0文章
21瀏覽量
1755
原文標(biāo)題:SpringCloud 組件性能優(yōu)化技巧
文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論