在分佈式系統領域有個著名的CAP定理
(C-數據一致性
;A-服務可用性
;P-服務對網絡分區故障的容錯性
,這三個特性在任何分佈式系統中不能同時知足,最多同時知足兩個
); eureka是AP
,zookeeper是CP
。對於服務發現
而言,可用性
比數據一致性
更加劇要——AP賽過CP
java
Consul | zookeeper | euerka | etcd | |
---|---|---|---|---|
服務健康檢查 | 服務狀態,內存,硬盤等 | (弱)長鏈接,keepalive | 可配支持 | 鏈接心跳 |
多數據中心 | 支持 | — | — | — |
kv存儲服務 | 支持 | 支持 | — | 支持 |
一致性 | raft | paxos | — | raft |
CAP | ca | cp | ap | cp |
使用接口(多語言能力) | 支持http和dns | 客戶端 | http(sidecar) | http/grpc |
watch支持(客戶端觀察到服務提供者變化) | 全量/支持long polling | 支持 | 支持long polling/大部分增量 | 支持long polling |
自身監控 | metrics | — | metrics | metrics |
安全 | acl /https | acl | — | https支持(弱) |
spring cloud集成 | 已支持 | 已支持 | 已支持 | 已支持 |
raft
:Raft強依賴 Leader 節點的可用性來確保集羣數據的一致性。 git
paxos
: 第一次由提交者Leader向全部其餘服務器發出prepare消息請求準備,全部服務器中大多數若是回覆諾言承諾就表示準備好了,能夠接受寫入;第二次提交者向全部服務器發出正式建議propose,全部服務器中大多數若是回覆已經接收就表示成功了。github
long polling
:長輪詢,客戶端向服務器發送Ajax請求,服務器接到請求後hold住鏈接,直到有新消息才返回響應信息並關閉鏈接,客戶端處理完響應信息後再向服務器發送新的請求。web
metrics
:做爲一款監控指標的度量類庫,它提供了不少模塊能夠爲第三方庫或者應用提供輔助統計信息, 它還能夠將度量數據發送給Ganglia和Graphite以提供圖形化的監控算法
Eureka的自我保護模式
Eureka Server
在運行期間,會統計心跳失敗的比例在15分鐘以內是否 低於85%,若是出現低於的狀況(實際在 生產環境上一般是因爲網 絡不穩定致使),Eureka Server
會將當前的實例註冊信息保護起來,同時提 示警告。保護模式主要用於一組客戶端和Eureka Server
之間存在網絡分 區場景下的保護。一旦進入保護模式,Eureka Server
將會嘗試保護其服務注 冊表中的信息,再也不刪除服務註冊表中的數據(也就是不會註銷任何微服務)。
因此Eureka
的哲學是,同時保留」好數據「
與」壞數據「
總比丟掉任何」好數據「要更好,因此這種模式在實踐中很是有效。,spring
ZooKeeper
是分佈式協調服務,它的職責是保證數據(注:配置數據,狀態數據)在其管轄下的全部服務之間保持同步、一致;(強一致性)ZooKeeper
使用單一主進程Leader
用於處理客戶端全部事務請求,採用ZAB協議
將服務器數狀態以事務形式廣播到全部Follower
上;若是三臺服務掛了兩臺怎麼選出leader
;1 不大於 (3/2)=1的
,ZooKeeper服務
就很是的困難ZooKeeper
會將它們都從本身管理範圍中剔除出去,外界就不能訪問到這些節點了,自己這些節點是「健康」
的,能提供服務的包含不實的信息的結果也比什麼都不返回要好
(由於暫時的網絡故障而找不到可用的服務器)所以, Eureka
能夠很好的應對因網絡故障致使部分節點失去聯繫的狀況,而不會像zookeeper
那樣使整個註冊服務癱瘓。json
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
複製代碼
經過 @EnableEurekaServer
註解啓動一個服務註冊中心提供給其餘應用進行對話,這個註解須要在springboot工程
的啓動application類
上加安全
package io.ymq.example.eureka.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
複製代碼
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
複製代碼
@EnableEurekaClient
,但只有Eureka
可用,你也可使用@EnableDiscoveryClient
。須要配置才能找到Eureka註冊中心服務器
discovery service
有許多種實現(eureka、consul、zookeeper
等)@EnableDiscoveryClient
基於spring-cloud-commons
,@EnableEurekaClient
基於spring-cloud-netflix
。eureka
,那麼就推薦@EnableEurekaClient
,@EnableDiscoveryClient
。@SpringBootApplication
@EnableEurekaClient
@RestController
public class EurekaProviderApplication {
@RequestMapping("/")
public String home() {
return "Hello world";
}
public static void main(String[] args) {
SpringApplication.run(EurekaProviderApplication.class, args);
}
}
複製代碼
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: eureka-provider
server:
port: 8081
複製代碼
向Eureka
註冊服務,消費者使用Ribbon
開啓負載均衡springboot
Ribbon
是Netflix
發佈的開源項目,主要功能是提供客戶端的軟件負載均衡算法,將Netflix
的中間層服務鏈接在一塊兒。Ribbon
客戶端組件提供一系列完善的配置項如鏈接超時,重試等。簡單的說,就是在配置文件中列出Load Balancer(簡稱LB)
後面全部的機器,Ribbon
會自動的幫助你基於某種規則(如簡單輪詢,隨即鏈接等)
去鏈接這些機器。咱們也很容易使用Ribbon
實現自定義的負載均衡算法。服務器
Ribbon
在工做時首選會經過ServerList
來獲取全部可用的服務列表,而後經過ServerListFilter
過慮掉一部分地址,最後在剩下的地址中經過IRule
選擇出一臺服務器做爲最終結果。
ServerList
:用於獲取地址列表。它既能夠是靜態的(提供一組固定的地址),也能夠是動態的(從註冊中心中按期查詢地址列表)。ServerListFilter
:僅當使用動態ServerList
時使用,用於在原始的服務列表中使用必定策略過慮掉一部分地址。IRule
:選擇一個最終的服務地址做爲LB結果
。選擇策略有輪詢、根據響應時間加權、斷路器(當Hystrix可用時)
等。簡單輪詢負載均衡(RoundRobin)
: 以輪詢的方式依次將請求調度不一樣的服務器,即每次調度執行i = (i + 1) mod n,並選出第i臺服務器。隨機負載均衡 (Random)
: 隨機選擇狀態爲UP的Server加權響應時間負載均衡 (WeightedResponseTime)
: 根據相應時間分配一個weight,相應時間越長,weight越小,被選中的可能性越低。區域感知輪詢負載均衡(ZoneAvoidanceRule)
:複合判斷server所在區域的性能和server的可用性選擇server@SpringBootApplication
@EnableEurekaClient
@RestController
public class EurekaProviderApplication {
@Value("${server.port}")
String port;
@RequestMapping("/")
public String home() {
return "Hello world ,port:" + port;
}
public static void main(String[] args) {
SpringApplication.run(EurekaProviderApplication.class, args);
}
}
複製代碼
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: eureka-provider
server:
port: 8081
複製代碼
<!-- 客戶端負載均衡 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<!-- eureka客戶端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
複製代碼
@EnableDiscoveryClient
@SpringBootApplication
public class RibbonConsumerApplication {
@LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RibbonConsumerApplication.class, args);
}
}
複製代碼
/** * 描述:調用提供者的 `home` 方法 **/
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping(value = "/hello")
public String hello() {
return restTemplate.getForEntity("http://eureka-provider/", String.class).getBody();
}
}
複製代碼
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: ribbon-consumer
server:
port: 9000
複製代碼
依次啓動服務(Eureka服務,三臺service provider和service Consumer)
,查看ribbon
是否開啓負載均衡
因爲Consul
自身提供了服務端,因此咱們不須要像以前實現Eureka
的時候建立服務註冊中心,直接經過下載consul的服務端程序就可使用。 Consul
內置了服務註冊
與發現框架
(一站式)、具備如下性質(參考上面列表):
client
:客戶端, 無狀態, 將 HTTP 和 DNS 接口請求轉發給局域網內的服務端集羣,全部註冊到當前節點的服務會被轉發到server,自己是不持久化這些信息server
:服務端, 保存配置信息, 高可用集羣, 在局域網內與本地客戶端通信,功能和client都同樣,惟一不一樣的是,它會把全部的信息持久化的本地,這樣遇到故障,信息是能夠被保留的。 經過廣域網與其餘數據中心通信. 每一個數據中心的 server 數量推薦爲 3 個或是 5 個.server-leader
:代表這個server是它們的老大,它和其它server不同的一點是,它須要負責同步註冊的信息給其它的server,同時也要負責各個節點的健康監測。raft
:server節點之間的數據一致性保證,一致性協議使用的是raft,而zookeeper用的paxos,etcd採用的也是taft。服務發現協議
:consul採用http和dns協議,etcd只支持http服務註冊
:支持兩種方式實現服務註冊,consul官方建議使用第二種方式。服務發現
:支持兩種方式實現服務發現,關於consul
的環境搭建以及應用後續再補充吧~
在github
上有關於Spring Cloud
完整的部署。
其它相關文章
Spring cloud(1)-簡介以及選擇
Spring cloud(2)-服務發現(Eureka,Consul)
Spring cloud(3)-負載均衡(Feign,Ribbon)
Spring cloud(4)-熔斷(Hystrix)
Spring cloud(5)-路由網關(Zuul)
Spring cloud(6)-配置管理及刷新(Config,Bus)
最後,給個 star 吧~
我的博客~
簡書~