rpc之負載均衡

2022-08-23 14:30:14 字數 3854 閱讀 3348

使用集群,比如zk來控制註冊中心,當乙個服務有多個請求位址的時候,會返回多個位址。

那麼就需要負載均衡來控制我們要請求哪台機器來得到請求。

方案一:隨機

傳入key值和key所包含的ip位址值,該位址值存入treeset中(有序儲存)

獲得treeset的長度,然後隨機得到其索引,挑出隨機的乙個。

public string route(string servicekey, treesetaddressset)

方案二:輪詢

treeset中的位址值存入乙個陣列中,並設定乙個map集合來記錄該函式呼叫了幾次,每次呼叫,就將索引加1,然後返回該索引的位址值。這樣就會按照treeset中的順序依次選取請求位址。

private concurrenthashmaproutecounteachjob = new concurrenthashmap();

private

long cache_valid_time = 0;

private

intcount(string servicekey)

//count++

integer count =routecounteachjob.get(servicekey);

count = (count==null || count>1000000)?(new random().nextint(100)):++count; //

初始化時主動random一次,緩解首次壓力

routecounteachjob.put(servicekey, count);

system.out.println("count:"+count);

return

count;

}@override

public string route(string servicekey, treesetaddressset)

方案三: lru(最近最少使用排程演算法)

每次使用了每個節點的時候,就將該節點放置在最後面,這樣就保證每次使用的節點都是最近最久沒有使用過的節點,當節點數大於最大空間的時候,就直接將前面的節點刪掉。

實現:使用linkedhashmap來實現。它內部有乙個雙向鍊錶在維護

public string doroute(string servicekey, treesetaddressset) 

//init lru

linkedhashmaplruitem =joblrumap.get(servicekey);

if (lruitem == null

) else}};

joblrumap.putifabsent(servicekey, lruitem);

}//put

for(string address: addressset)

}//load

string eldestkey =lruitem.entryset().iterator().next().getkey();

string eldestvalue = lruitem.get(eldestkey);//

lru演算法關鍵體現在這裡,實現了固定長度的lru演算法

return

eldestvalue;

}

方案四:lfu(訪問最頻繁的使用概率也最高),因此,將使用最頻繁的放在最後面使用,保證了使用不頻繁的也能使用上

hashmap的存放是無序的。

public string doroute(string servicekey, treesetaddressset) 

//lfu item init

hashmaplfuitemmap = joblfumap.get(servicekey); //

key排序可以用treemap+構造入參compare;value排序暫時只能通過arraylist;

if (lfuitemmap == null

)

for(string address: addressset)

}//load least userd count address

list> lfuitemlist = new arraylist>(lfuitemmap.entryset());

collections.sort(lfuitemlist,

new comparator>()

});system.out.println(lfuitemlist);

map.entry

addressitem = lfuitemlist.get(0);

string minaddress =addressitem.getkey();

addressitem.setvalue(addressitem.getvalue() + 1);

return

minaddress;

//return null;

}

方案五:一致性雜湊

consistent hashing 是一種 hash 演算法,簡單的說,在移除 / 新增乙個 cache 時,它能夠盡可能小的改變已存在 key 對映關係,盡可能的滿足單調性的要求。

每個節點設定5個虛擬節點

計算servicekey的hash值

使用treemap的tailmap方法返回其鍵大於或等於fromkey的部分檢視

取檢視的第乙個作為服務呼叫的address

private

int virtual_node_num = 5;

/*** get hash code on 2^32 ring (md5雜湊的方式計算hash值)

* @param

key *

@return

*/private

long

hash(string key)

catch

(nosuchalgorithmexception e)

md5.reset();

byte keybytes = null

;

try

catch

(unsupportedencodingexception e)

md5.update(keybytes);

byte digest =md5.digest();

//hash code, truncate to 32-bits

long hashcode = ((long) (digest[3] & 0xff) << 24)

| ((long) (digest[2] & 0xff) << 16)

| ((long) (digest[1] & 0xff) << 8)

| (digest[0] & 0xff);

long truncatehashcode = hashcode & 0xffffffffl;

return

truncatehashcode;

}public string doroute(string servicekey, treesetaddressset)

}//treemap的存放是根據addresshash值排序

long jobhash =hash(servicekey);

sortedmap

lastring =addressring.tailmap(jobhash);

//將addresshash值大於jobhash值的adress都取出來

if (!lastring.isempty())

//返回沒有減少的位址的第乙個

return

addressring.firstentry().getvalue();

}

一文詳解 RPC 之負載均衡

假設有一次流量高峰,突然發現線上服務的可用率降低了,經過排查發現是有幾台機器比較舊了,當流量達到高峰時,這幾台機器由於負載太高,就扛不住壓力,那怎麼解決這種問題呢?首先我們可能會想到,在治理平台上調低這幾台機器的權重,這樣的話,流量自然就減少了。但是這樣會導致服務可用率降低,業務請求受到影響,那 r...

RPC實現原理之核心技術 路由與負載均衡

為什麼要採用路由?真實的環境中一般是以集群的方式提供服務,但對於服務呼叫方來說,乙個介面會有多個服務提供方同時提供服務,所以 rpc 在每次發起請求的時候,都需要從多個服務節點裡面選取乙個用於處理請求的服務節點。每次上線應用的時候都不止執行一台伺服器例項,上線就會涉及到變更,只要變更就可能導致原本正...

負載均衡之lvs

集群 cluster 將一組計算機軟 硬體連線起來,高度緊密的協作完成計算工作,其中的單個計算機通常稱為節點。負載均衡集群 load balancing 通過負載均衡器,將負載盡可能平均分攤處理。lvs linux virtul server linux虛擬服務,分為三層結構 排程器 上面的虛擬ip...