服務化的演變和負載均衡

2022-07-05 15:24:10 字數 3832 閱讀 9969

分布式應用架構體系對於邏輯複雜的需求十分強烈,上層業務都想借自己已有的遞增服務、來快速搭建更多、更豐富的應用,降低新業務開展的人力和時間成本,快速滿足瞬息萬變的市場需求,公共的業務被區分出來,形成可共用的服務,最大程度地保障了**和邏輯的復用,避免重複建設,這種設計也被稱為soa。

soa(service-oriented architecture)面向服務的架構是乙個元件模型,它將應用程式的不同功能單元(稱為服務)通過這些服務之間定義良好的介面和契約聯絡起來,介面是採用中立的方式進行定義的,它應該獨立於實現服務的硬體平台、作業系統和程式語言。這使得構建在各種各樣的系統中的服務可以以一種統一和通用的方式進行互動。

soa架構中,服務消費者通過服務名稱,在眾多服務中找到要呼叫的服務的位址列表,稱為服務的路由。

而對於負載較高的服務來說,往往對應著由多台伺服器組成的集群。在請求到來時,為了將請求均衡的分配到後的伺服器,負載均衡程式將服務對應的位址列表中,通過相應的負載均衡演算法和規則,選取一台伺服器進行訪問,這個過程稱為服務的負載均衡。

當服務模組較小時,可以曹勇硬編碼的方式將服務位址和配置在**中。通過編碼的方式來解決服務的路由和負載均衡問題,也可以通過傳統的硬體輔助均衡裝置如f5等或者採用lvs或nginx等軟體解決方案,通過相關配置,來解決服務的路由和複雜均衡問題。由於服務的機器數量在可控範圍內,因此維護成本能夠接受。

當服務越來越多,規模越來越大時,對應的機器數量也越來越龐大,單靠人工來管理和維護服務及位址的配置資訊,已經越來越空難。並且,依賴單一的硬體負載均衡裝置或者使用lvs,nginx等軟體方案進行路由和負載均衡伺服器宕機,依賴它的所有服務均將失效。

此時,需要乙個能夠動態註冊和獲取服務資訊的地方,來統一管理服務名稱和其對應的伺服器列表資訊,稱之為服務配置中心,服務提供者在啟動時,將其提供的服務名稱、伺服器位址註冊到服務配置中心,服務消費者通過服務配置中心來獲取需要呼叫的服務的機器列表,通過相應的負載均衡演算法,選取其中一台伺服器進行呼叫。當伺服器宕機或者下線時,相應的機器需要能夠動態的從配置服務中心裡面移除,並通知相應的服務消費者,否則,服務消費者就有可能因為呼叫到已經失效的服務而發生錯誤。在這個過程中,服務消費者只有在第一次呼叫服務時需要查詢服務配置中心,而不需要重新發起請求道服務配置中心去獲取相應的服務位址列表,知道服務的位址列表有變更。這種無中心的結構解決了之前負載均衡設定所導致的單點故障問題,並且大大減輕了服務配置中心的壓力。

基於zookeeper的持久和非持久節點,我們能夠近乎實時地感知到後端伺服器的狀態。通過集群間zab協議,使得服務配置資訊能夠保持一致,而zookeeper本身容錯特性和leader選舉機制,能保障我們方便地進行擴容。通過zookeeper來實現服務動態註冊、機器上線與下線的動態感知,擴容方便,容錯性好,且無中心結構能夠解決之前使用負載均衡裝置所帶來的單點故障問題,只有當配置資訊更新時才會去zookeeper上獲取最新的服務位址列表,其他時候使用本地快取即可、基於zookeeper的服務配置中心的搭建。

服務化的演進提到服務消費者從服務配置中心獲取到服務的位址列表後,需要選擇其中一台來發起rpc呼叫。如何選擇,取決於具體的負載均衡演算法,對應於不同的場景,選擇的演算法也不盡相同,常見的負載均衡演算法有輪訓法、隨機法。源位址雜湊發、加權輪詢法,加權隨機法、最小鏈結法等。

將請求按順序輪流的分配到後端伺服器上,它均衡地對待後端每一台伺服器,而不關心伺服器實際的連線數和當前的系統負載。

通過初始化乙個serverweightmap的map變數來表示伺服器位址和權重的對映,以此來模擬輪詢演算法的實現,

1 serverweightmap=new hashmap();

2 serverweightmap.put("

192.168.1.100

",1);

3 serverweightmap.put("

192.168.1.101

",1);

4 serverweightmap.put("

192.168.1.102

",4);

5 serverweightmap.put("

192.168.1.103

",3);

輪詢的關鍵**:

1

public

static

string testroundrobin()

1516 server=keylist.get

(pos);

17 pos++;18}

19return

server.

20 }

由於serverweightmap中的位址列表是動態的,隨時可能有機器上線、下線或者宕機,因此,為了避免可能出現的併發問題,如陣列越界,通過新建方法內的區域性變數servermap,先將域變數複製到執行緒本地,以避免多個執行緒虛高。這樣可能會引入新的問題,複製一會serverweightmap的修改將無法反映給servermap,也就是說,在這一輪選擇伺服器的的過程中。新增伺服器或者下線伺服器負載均衡演算法中將無法獲知,新增比較好處理,而當伺服器下線或者宕機時,服務消費者將有可能訪問到不存在的位址,因此,在服務消費者的實現端需要考慮該問題,並且進行相應的容錯處理,比如重新發起一次呼叫。

對於當前輪詢的位置變數pos,為了保證伺服器選擇地順序性,需要在操作時對其加上synchronized鎖,使得在同一時刻只有乙個執行緒能夠修改pos的值,都在當pos變數被併發修改,則無法保證伺服器選擇的順序性,甚至有可能導致keylist陣列越界。

由概率論可知,隨著呼叫量的增大,其實際效果越來越接近平均分配流量到每一台後端伺服器,也就是輪詢的效果。

1

public

static

string testrandom()

源位址雜湊的思想是獲取客戶端訪問的ip位址值,通過雜湊函式計算得到乙個數值,用該數值對伺服器列表的大小進行取模運算,得到的結果便是要訪問的伺服器的序號。採用雜湊法進行負載均衡,同一ip位址的客戶端,當後端伺服器列表不變時,它每次都會被對映到同一台後端伺服器進行訪問。

1

public

static

string testconsumerhash(string remoteip)

通過引數傳入的客戶端remoteip引數,取得它的雜湊值,對伺服器列表的大小取模,結果便是選用的伺服器在伺服器列表中的索引值。該演算法保證了相同的客戶端ip位址將會被「雜湊」到同一台後端伺服器,直到後端伺服器列表變更。根據此特性可以在服務消費者與服務提供者之間建立有狀態的session會話。

不同的後端伺服器可能機器的配置和當前系統的負載並不相同,因此他們抗壓能力也不盡相同。給配置搞,負載低的機器配置更高的權重,讓其處理更多的請求,而低配置、負載高的機器,則給其分配較低的權重,將其其系統負載,甲醛輪詢能很好地處理這一問題,並將請求順序且安裝權重分配到後端。

1

public

static

string testweightroundrobin()15}

16 string server = null;17

synchronized(pos)

22 server = serverlist.get

(pos);

23 pos++;24}

25return

server;

26 }

1

public

static

string testweightrandom()15}

16 random random = new

random();

17int randompos =random.nextint(serverlist.size());

18 string server = serverlist.get

(randompos);

19return

server;

20 }

服務和負載均衡的實現(zookeeper)

是什麼?zookeeper是乙個大型分布式系統的可靠地協調系統,提供的功能包括配置維護,名字服務,分布式同步,組服務等。zeepkeeper 是可以通過集群複製的,集群間通過自動廣播協議來保持資料的一致性。該協議包括 leader election 和atomic broadcas 階段。集群中將選...

Docker Swarm服務發現和負載均衡原理

docker swarm服務發現和負載均衡原理 docker使用的是linux核心iptables和ipvs的功能來實現服務發現和負載均衡。iptables是linux核心中可用的包過濾技術,可根據資料報的內容進行分類 修改和 決策。ipvs是linux核心中可用的傳輸級負載均衡。本地建立乙個集群環...

nginx負載均衡和lvs負載均衡的比較分析

2010 04 13 11 11 16 lvs和nginx都可以用作多機負載的方案,它們各有優缺,在生產環境中需要好好分析實際情況並加以利用。首先提醒,做技術切不可人云亦云,我雲即你雲 同時也不可太趨向保守,過於相信舊有方式而等別人來幫你做墊被測試。把所有即時聽說到的好東西加以鑽研,從 而提高自己對...