Dubbo3 消費端線程池模型

2022-04-02 10:19 更新

Dubbo 消費端線程池模型用法

2.7.5 版本對整個調(diào)用鏈路做了全面的優(yōu)化,根據(jù)壓測結果顯示,總體 QPS 性能提升將近 30%,同時也減少了調(diào)用過程中的內(nèi)存分配開銷。其中一個值得提及的設計點是 2.7.5 引入了 Servicerepository 的概念,在服務注冊階段提前生成 ServiceDescriptor 和 MethodDescriptor,以減少 RPC 調(diào)用階段計算 Service 原信息帶來的資源消耗。

消費端線程池模型優(yōu)化

對 2.7.5 版本之前的 Dubbo 應用,尤其是一些消費端應用,當面臨需要消費大量服務且并發(fā)數(shù)比較大的大流量場景時(典型如網(wǎng)關類場景),經(jīng)常會出現(xiàn)消費端線程數(shù)分配過多的問題,具體問題討論可參見 Need a limited Threadpool in consumer side #2013

改進后的消費端線程池模型,通過復用業(yè)務端被阻塞的線程,很好的解決了這個問題。

老的線程池模型

消費端線程池.png

我們重點關注 Consumer 部分:

  1. 業(yè)務線程發(fā)出請求,拿到一個 Future 實例。
  2. 業(yè)務線程緊接著調(diào)用 future.get 阻塞等待業(yè)務結果返回。
  3. 當業(yè)務數(shù)據(jù)返回后,交由獨立的 Consumer 端線程池進行反序列化等處理,并調(diào)用 future.set 將反序列化后的業(yè)務結果置回。
  4. 業(yè)務線程拿到結果直接返回

2.7.5 版本引入的線程池模型

消費端線程池新.png

  1. 業(yè)務線程發(fā)出請求,拿到一個 Future 實例。
  2. 在調(diào)用 future.get() 之前,先調(diào)用 ThreadlessExecutor.wait(),wait 會使業(yè)務線程在一個阻塞隊列上等待,直到隊列中被加入元素。
  3. 當業(yè)務數(shù)據(jù)返回后,生成一個 Runnable Task 并放入 ThreadlessExecutor 隊列
  4. 業(yè)務線程將 Task 取出并在本線程中執(zhí)行:反序列化業(yè)務數(shù)據(jù)并 set 到 Future。
  5. 業(yè)務線程拿到結果直接返回

這樣,相比于老的線程池模型,由業(yè)務線程自己負責監(jiān)測并解析返回結果,免去了額外的消費端線程池開銷。

關于性能優(yōu)化,在接下來的版本中將會持續(xù)推進,主要從以下兩個方面入手:

  1. RPC 調(diào)用鏈路。目前能看到的點包括:進一步減少執(zhí)行鏈路的內(nèi)存分配、在保證協(xié)議兼容性的前提下提高協(xié)議傳輸效率、提高 Filter、Router 等計算效率。
  2. 服務治理鏈路。進一步減少地址推送、服務治理規(guī)則推送等造成的內(nèi)存、cpu 資源消耗。



以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號