dubbo常見效能問題
1.dubbo一個提供方和一個消費方,預設使用單一長連線
如果消費方呼叫提供方其中一個服務比較慢,則會造成其它服務緩慢,解決辦法是設定多個連線。
但連線數過多也會造成服務端連線暴滿的問題,需要根據實際情況設定。
全域性設定:
<dubbo:protocol name=“dubbo” connections=“2” />
單個服務設定:
<dubbo:service connections=”2”>或<dubbo:reference connections=”2”>表示該服務使用獨立兩條長連線。
2.事件分發模式
Dispatcher
all 所有訊息都派發到執行緒池,包括請求,響應,連線事件,斷開事件,心跳等。
direct 所有訊息都不派發到執行緒池,全部在IO執行緒上直接執行。
message 只有請求響應訊息派發到執行緒池,其它連線斷開事件,心跳等訊息,直接在IO執行緒上執行。
<dubbo:protocol name=“dubbo” port=“20880” dispatcher=“all” threadpool=“fixed” threads=“100” />
3.服務提供方,儘量與服務消費方在同一區域網
spring cloud提供呼叫優先順序。優先呼叫同機房服務,沒有則呼叫同一個城市服務。
4.超時時間設定
根據不同業務設定超時時間,有些後臺任務,需要設定長點。預設超時時間為6秒。
面向使用者的服務,超時時間不能過長,如果這個服務出現問題,會導致雪崩。
5.讀服務可以重試,寫服務一般不建議重試
6.設定處理執行緒池的大小和型別
<dubbo:protocol name=“dubbo” port="${dubbo.protocol.port}" server=“netty” client=“netty” serialization=“dubbo” charset=“UTF-8” threadpool=“fixed” threads=“500” queues=“0” buffer=“8192” accepts=“0” payload=“8388608”
iothreads=“9” />
預設執行緒池核心執行緒數為:200,最大執行緒數為200,queue為SyncronouseQueue。
考慮下,如果出現請求200個處理執行緒都不夠,再來一個請求會發生什麼情況?
底層會拋一個RejectedExecutionException,使用的是dubbo自己的拒絕策略:AbortPolicyWithReport。
這裡最好不要設定queues。
如果設定了,因為在請求比較多時,如果服務提供方處理不過來,會將請求儲存在queue,但因為是先進先出,所以之前早點的請求會被先處理,處理完後由於有dubbo超時時間這批請求實際是無效的。
接著導致之後新的請求就算服務已經恢復正常速度,由於還要先處理之前舊的請求導致這批請求都無效。
初始化程式碼:
public Executor getExecutor(URL url) {
String name = url.getParameter(Constants.THREAD_NAME_KEY, Constants.DEFAULT_THREAD_NAME);
int threads = url.getParameter(Constants.THREADS_KEY, Constants.DEFAULT_THREADS);
int queues = url.getParameter(Constants.QUEUES_KEY, Constants.DEFAULT_QUEUES);
return new ThreadPoolExecutor(threads, threads, 0, TimeUnit.MILLISECONDS,
queues == 0 ? new SynchronousQueue() :
(queues < 0 ? new LinkedBlockingQueue()
: new LinkedBlockingQueue(queues)),
new NamedThreadFactory(name, true), new AbortPolicyWithReport(name, url));
}
7.dubbo呼叫鏈監控
使用開源的cat,pinpoint或自研。
8.現在dubbo用的是netty3,nett4之後做了很多優化,其中包括快取池的利用可以提升不少效能。
期望dubbo之後能有升級。
9.dubbo限流
針對某個介面做限流
服務消費方:
dubbo:referenceconnections
防止服務提供方接收過多連線:
dubbo:protocolname="dubbo"accepts=“1000”/
10.請求響應資料大小限制
dubbo:protocal payload
預設8M
不要傳送大包
11.業務的熔斷降級
dubbo預設不提供,可以使用hystrix去做
12.服務提供方及消費者限制呼叫某個服務的併發數
//限制服務端,這個服務可以同時併發的執行緒數
<dubbo:service interface=“com.foo.BarService” executes=“10” />
//限制服務端,這個服務可以同時存在的連線數
<dubbo:service interface=“com.foo.BarService” actives=“10” />
<dubbo:reference interface=“com.foo.BarService” actives=“10” />
13.dubbo本身上層有心跳,底層還設定了tcp的keepAlive
這樣做的原因可能是擔心dubbo執行緒池無可用執行緒用於心跳檢測,導致服務端連線不釋放。
14.服務不能拆的太細
原因:
1.在組裝某個業務結果時,涉及遠端呼叫太多
2.服務方過多,消費方建立的socket也會比較多。