Random LoadBalance(默認) 隨機,按權重設置隨機機率。
在一個截面上碰撞的機率高,但調用量越大分佈越均勻,並且按機率使用權重後也比較均勻,有利於動態調整 提供者權重。phpRoundRobin LoadBalance 輪詢,按公約後的權重設置輪詢比率。
存在慢的提供者累積請求的問題,好比:第二臺機器很慢,但沒掛,當請求調到第二臺時就卡在那,久而久 之,全部請求都卡在調到第二臺上。javaLeastActive LoadBalance 最少活躍調用數,相同活躍數的隨機,活躍數指調用先後計數差。
使慢的提供者收到更少請求,由於越慢的提供者的調用先後計數差會越大。springConsistentHash LoadBalance 一致性 Hash,相同參數的請求老是發到同一提供者。
當某一臺提供者掛時,本來發往該提供者的請求,基於虛擬節點,平攤到其它提供者,不會引發劇烈變更。缺省只對第一個參數 Hash,若是要修改,請配置 缺省用 160 份虛擬節點,若是要修改,請配置docker
1.2配置
1.2.1xml方式
能夠在提供方配置也能夠在消費方配置. 有以下幾種,任選一種數據庫
服務端服務級別緩存
<dubbo:service interface="..." loadbalance="roundrobin" />
服務端方法級別安全
<dubbo:service interface="...">
<dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:service>
客戶端服務級別ruby
<dubbo:reference interface="..." loadbalance="roundrobin" />
客戶端方法級別bash
<dubbo:reference interface="...">
<dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:reference>
1.2.2註解方式
提供者配置服務器
@Service(loadbalance = "")
public class UserServiceImpl implements UserService {}
消費者配置,經過loadbalance屬性
@Reference(loadbalance = "roundrobin ")
private UserService userService;
2.集羣容錯
2.1集羣中容錯類型
在集羣調用失敗時,Dubbo 提供了多種容錯方案,缺省爲 failover 重試。
2.2Dubbo中容錯策略
Failover Cluster
失敗自動切換,當出現失敗,重試其它服務器. 一般用於讀操做,但重試會帶來更長延遲。可通 過 retries="2" 來設置重試次數(不含第一次)。能夠在提供方配置也能夠在消費方配置
//提供方配置
<dubbo:service retries="2" />
//消費方配置
<dubbo:reference retries="2" />
Failfast Cluster
快速失敗,只發起一次調用,失敗當即報錯。一般用於非冪等性的寫操做,好比新增記錄。Failsafe Cluster
失敗安全,出現異常時,直接忽略。一般用於寫入審計日誌等操做。Failback Cluster
失敗自動恢復,後臺記錄失敗請求,定時重發。一般用於消息通知操做。Forking Cluster
並行調用多個服務器,只要一個成功即返回。一般用於實時性要求較高的讀操做,但須要浪費更多服務資源。可經過 forks="2" 來設置最大並行數。Broadcast Cluster
廣播調用全部提供者,逐個調用,任意一臺報錯則報錯 [2]。一般用於通知全部提供者更新緩存或日誌等本地 資源信息。
2.3配置
2.3.1xml方式
服務提供方
<dubbo:service cluster="failsafe" />
服務消費方
<dubbo:reference cluster="failsafe" />
2.3.2註解方式
服務提供方
@Service(cluster = "failsafe")
服務消費方
@Reference(cluster = "failsafe")
3.SpringBoot整合熔斷器Hystrix
3.1Hystrix概述
Hystrix是一個用於處理分佈式系統的延遲和容錯的開源庫,Hystrix 能使你的系統在出現依賴服務失效的時 候,經過隔離系統所依賴的服務,防止服務級聯失敗,同時提供失敗回退機制,更優雅地應對失效,並使你的系統 能更快地從異常中恢復 .
「斷路器」自己是一種開關裝置,當某個服務單元發生故障以後,經過斷路器的故障監控(相似熔斷保險絲), 向調用方返回一個符合預期的、可處理的備選響應(FallBack),而不是長時間的等待或者拋出調用方沒法處理的 異常,這樣就保證了服務調用方的線程不會被長時間、沒必要要地佔用,從而避免了故障在分佈式系統中的蔓延,乃 至雪崩。
3.2整合Hystrix進行容錯
3.2.1提供方
在pom.xml添加Hystrix起步依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐starter‐netflix‐hystrix</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在啓動類上面開啓Hystrix(@EnableHystrix )
@EnableHystrix
@EnableDubbo
@SpringBootApplication
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class,args);
}
}
在提供的方法上面添加註解@HystrixCommand
@Service
public class UserServiceImpl implements UserService {
/**
* 按照用戶id返回全部的收貨地址
* @param userId
* @return
*/ @HystrixCommand
public List<Address> findUserAddressList(String userId) {
//模擬dao查詢數據庫
System.out.println("UserServiceImpl....");
List<Address> list = new ArrayList<Address>();
list.add(new Address(1,"北京","1","張三","12306"));
list.add(new Address(2,"武漢","2","李四","18170"));
return list;
}
}
3.2.2消費者
在pom.xml添加Hystrix起步依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐starter‐netflix‐hystrix</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在啓動類上面開啓Hystrix(@EnableHystrix )
@EnableHystrix
@EnableDubbo
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class,args);
}
}
在調用的方法上面添加註解@HystrixCommand
@RestController
@RequestMapping("/order")
public class OrderController {
@Reference(cluster = "") private UserService userService;
@HystrixCommand(fallbackMethod = "nativeMethod")
@RequestMapping("/save")
public List<Address> save(){
List<Address> list = userService.findUserAddressList("1");
System.out.println(list);
//調用業務...
return list;
}
//當遠程方法調用失敗,會觸發當前方法
public List<Address> nativeMethod(){
List<Address> list = new ArrayList<Address>();
list.add(new Address(1,"默認地址","1","默認收貨人","默認電話"));
return list;
}
}
4.Zookeeper集羣
4.1.Zookeeper集羣簡介
4.1.1爲何搭建Zookeeper集羣
大部分分佈式應用須要一個主控、協調器或者控制器來管理物理分佈的子進程。目前,大多數都要開發私有的 協調程序,缺少一個通用機制,協調程序的反覆編寫浪費,且難以造成通用、伸縮性好的協調器,zookeeper提供 通用的分佈式鎖服務,用以協調分佈式應用。因此說zookeeper是分佈式應用的協做服務。
zookeeper做爲註冊中心,服務器和客戶端都要訪問,若是有大量的併發,確定會有等待。因此能夠經過 zookeeper集羣解決。
下面是zookeeper集羣部署結構圖:
4.1.2Leader選舉
Zookeeper的啓動過程當中leader選舉是很是重要並且最複雜的一個環節。那麼什麼是leader選舉呢?zookeeper爲何須要leader選舉呢?zookeeper的leader選舉的過程又是什麼樣子的?
看什麼是leader選舉。其實這個很好理解,leader選舉就像總統選舉同樣,每人一票,得到多數票的 人就當選爲總統了。在zookeeper集羣中也是同樣,每一個節點都會投票,若是某個節點得到超過半數以上的節點的 投票,則該節點就是leader節點了。
4.2搭建Zookeeper集羣
4.2.1搭建要求
真實的集羣是須要部署在不一樣的服務器上的,可是在咱們測試時同時啓動十幾個虛擬機內存會吃不消,因此我 們一般會搭建僞集羣,也就是把全部的服務都搭建在一臺虛擬機上,用端口進行區分。
搭建一個三個節點的Zookeeper集羣(僞集羣)。
4.2.2準備工做
(1)安裝JDK 【步驟略】。
(2)Zookeeper壓縮包上傳到服務器【也可用docker方式】
(3)將Zookeeper解壓,建立data目錄 ,將 conf下zoo_sample.cfg 文件更名爲 zoo.cfg
(4)創建/usr/local/zookeeper-cluster目錄,將解壓後的Zookeeper複製到如下三個目錄
/usr/local/zookeeper-cluster/zookeeper-1
/usr/local/zookeeper-cluster/zookeeper-2
/usr/local/zookeeper-cluster/zookeeper-3
[root@localhost ~]# mkdir /usr/local/zookeeper‐cluster
[root@localhost ~]# cp ‐r zookeeper‐3.4.6 /usr/local/zookeeper‐cluster/zookeeper‐1
[root@localhost ~]# cp ‐r zookeeper‐3.4.6 /usr/local/zookeeper‐cluster/zookeeper‐2
[root@localhost ~]# cp ‐r zookeeper‐3.4.6 /usr/local/zookeeper‐cluster/zookeeper‐3
(5) 配置每個Zookeeper 的dataDir(zoo.cfg) clientPort 分別爲2181 2182 2183
修改/usr/local/zookeeper-cluster/zookeeper-1/conf/zoo.cfg
clientPort=2181
dataDir=/usr/local/zookeeper‐cluster/zookeeper‐1/data
修改/usr/local/zookeeper-cluster/zookeeper-2/conf/zoo.cfg
clientPort=2182
dataDir=/usr/local/zookeeper‐cluster/zookeeper‐2/data
修改/usr/local/zookeeper-cluster/zookeeper-3/conf/zoo.cfg
clientPort=2183
dataDir=/usr/local/zookeeper‐cluster/zookeeper‐3/data
4.2.3配置集羣
(1)在每一個zookeeper的 data 目錄下建立一個 myid 文件,內容分別是一、二、3 。這個文件就是記錄每一個服務器 的ID
‐‐‐‐‐‐‐知識點小貼士‐‐‐‐‐‐
若是你要建立的文本文件內容比較簡單,咱們能夠經過echo 命令快速建立文件
格式爲:
echo 內容 >文件名
例如咱們爲第一個zookeeper指定ID爲1,則輸入命令
(2)在每個zookeeper 的 zoo.cfg配置客戶端訪問端口(clientPort)和集羣服務器IP列表。
集羣服務器IP列表以下
server.1=192.168.25.140:2881:3881
server.2=192.168.25.140:2882:3882
server.3=192.168.25.140:2883:3883
解釋:server.服務器ID=服務器IP地址:服務器之間通訊端口:服務器之間投票選舉端口
4.2.4啓動集羣
(1)啓動集羣就是分別啓動每一個實例
(2)啓動後咱們查詢一下每一個實例的運行狀態
先查詢第一個服務, Mode爲follower表示是跟隨者(從)
再查詢第二個服務Mod 爲leader表示是領導者(主)
查詢第三個爲跟隨者(從)
4.2.5模擬集羣異常
(1)首先咱們先測試若是是從服務器掛掉,會怎麼樣
把3號服務器停掉,觀察1號和2號,發現狀態並無變化
由此得出結論,3個節點的集羣,從服務器掛掉,集羣正常
(2)咱們再把1號服務器(從服務器)也停掉,查看2號(主服務器)的狀態,發現已經中止運行了。
由此得出結論,3個節點的集羣,2個從服務器都掛掉,主服務器也沒法運行。由於可運行的機器沒有超過集羣總數 量的半數。
(3)咱們再次把1號服務器啓動起來,發現2號服務器又開始正常工做了。並且依然是領導者。
(4)咱們把3號服務器也啓動起來,把2號服務器停掉(汗~~幹嗎?領導掛了?)停掉後觀察1號和3號的狀態。
發現新的leader產生了~
由此咱們得出結論,當集羣中的主服務器掛了,集羣中的其餘服務器會自動進行選舉狀態,而後產生新得leader
(5)咱們再次測試,當咱們把2號服務器從新啓動起來(汗~~這是詐屍啊!)啓動後,會發生什麼?2號服務器會再 次成爲新的領導嗎?咱們看結果
咱們會發現,2號服務器啓動後依然是跟隨者(從服務器),3號服務器依然是領導者(主服務器),沒有撼動3號 服務器的領導地位。
由此咱們得出結論,當領導者產生後,再次有新服務器加入集羣,不會影響到現任領導者。
4.3.Dubbo鏈接zookeeper集羣
修改服務提供者和服務調用者的spring 配置文件
<!‐‐ 指定註冊中心地址 ‐‐>
<dubbo:registry protocol="zookeeper" address="192.168.25.140:2181,192.168.25.140:2182,192.168.25.140:2183">
</dubbo:registry>
本文分享自微信公衆號 - JAVA高級架構(gaojijiagou)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。