之前在講divide外掛程式時,只講了hashloadbalance,randomloadbalance兩種負載均衡方式,這次我們一起來看一下roundrobinloadbalance,輪詢。
事實上,soul 提供的負載均衡方式是可設定權重的,所以**比普通的負載均衡負載一點。
roundrobinloadbalance 維護了乙個 methodweightmap 作為各個upstream的快取,同時維護了atomicboolean型別變數updatelock作為輕量級鎖來保證一致性。
接下來看**:
作為對比,我們再來看一下 spring ribbon 的輪詢關鍵**,com.netflix.loadbalancer.roundrobinrule:@override
public divideupstream doselect
(final list
upstreamlist,
final string ip)
int totalweight =0;
long maxcurrent = long.min_value;
long now = system.
currenttimemillis()
; divideupstream selectedinvoker = null;
weightedroundrobin selectedwrr = null;
// 遍歷所有可選的主機
for(divideupstream upstream : upstreamlist)
if(weight != weightedroundrobin.
getweight()
)// 加上自己的權重
long cur = weightedroundrobin.
increasecurrent()
; weightedroundrobin.
setlastupdate
(now)
;// 對比,如果當前主機優先順序最高,則設定為 selected
if(cur > maxcurrent)
// 總權重累加
totalweight += weight;
}// 以cas操作來實現輕量級的同步鎖if(
!updatelock.
get(
)&& upstreamlist.
size()
!= map.
size()
&& updatelock.
compareandset
(false
,true))
finally}if
(selectedinvoker != null)
return upstreamlist.
get(0)
;}
public server choose
(iloadbalancer lb, object key)
server server = null;
int count =0;
// 最多嘗試 10 次,10 次後仍然沒有可用主機時,直接失敗
while
(server == null && count++
<10)
// 計數器加一併按照當前主機數取模
int nextserverindex =
incrementandgetmodulo
(servercount)
; server = allservers.
get(nextserverindex);if
(server == null)
// 主機探活
if(server.
isalive()
&&(server.
isreadytoserve()
))// next.
server = null;}if
(count >=10)
return server;
}private
intincrementandgetmodulo
(int modulo)
}
Soul原始碼閱讀 1 初識 Soul
無論我們學習什麼東西之前,都要先搞清楚我們要學習的是什麼,就像一些哲學思考先要給出清晰的定義,否則後面的一切都無從談起。從今天開始,我來和大家一起,學習一款非常優秀的開源閘道器專案 soul。soul 是什麼呢?先來看下官網作者的定義 這是乙個非同步的,高效能的,跨語言的,響應式的api閘道器。我希...
Soul閘道器原始碼學習05
soul web基於webflux 可以使用netty作為應用伺服器,eventloop 可以說是netty的排程中心,負責事件的監聽 i o事件 訊號事件 channelpipeline 事件處理鏈,channelhandler事件處理。相對於channelpipeline 而言netty事件分為...
Soul閘道器原始碼學習06
在soul閘道器中每個請求,都會通過責任鏈的方式執行相匹配的外掛程式,所以外掛程式也是soul閘道器的核心,soul閘道器的外掛程式是可插拔的,並且是外掛程式之間依賴關係是松耦合且外掛程式的功能實現高聚合,其次使用者可根據需求定製外掛程式滿足自己的需求。soul外掛程式配置類,使用 spring.f...