零.復習
其實,SpringCloud有點與之前學過的WebService相似。
SpringCloud構建項目的微服務框架,就是一個工具集,集Netfilx的開源組件進一步封裝。
Eureka-Server、Eureka-Client、Ribbon
一.Eureka Client的高可用
- 啟動eureka server注冊中心
- 搭建服務的高可用
①準備服務提供者
②注意:同一個服務提供者的集群,服務的名字必須一致。
③同時向euraka注冊 - 啟動eureka server 啟動多個服務實例即可
二.基于ribbon的負載均衡
Springcloud 中的默認的負載均衡策略是 輪詢策略
restTemplate(類似httpClient協議的通信框架)+ ribbon組件(負載均衡)
<!--引入ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.3.0.RELEASE</version>
</dependency>
-
rebbon組件如何進行負載均衡的呢?
當我們發起一個請求,這個請求調用服務,先去注冊中心拿服務類表;區別于Dubbo,dubbo是在注冊中心中,在服務提供方,設計了一系列負載均衡策略,當然消費方是可以覆蓋服務方的負載均衡策略。(服務方提供負載均衡策略,消費方可覆蓋服務方 )
Springcloud則不同,其所有的負載均衡均屬”軟負載均衡“。軟負載均衡 — 基于客戶端的負載均衡,與服務端無關。(ribbon是一個基于客戶端的軟負載均衡 )
當我們調用某個服務時,客戶端向eureka server請求該服務實例,然后它會把這個服務的服務列表,全部返回給客戶端,并緩存起來。(其中,客戶端緩存列表會與服務器進行心跳檢測,遇宕機會高效剔除 )即在客戶端進行負載均衡,與服務提供者和注冊中心沒有關系。
所以可以使用@LoadBalanced注解,根據默認負載均衡策略拿到列表中的服務節點。 -
那么如何修改策略呢?
ribbon中輪詢策略,是基于三大組件
-
ServerList ”用來獲取服務列表“
根據指定的服務名,去拿取注冊中心中的服務列表 -
ServerListFilter ”通過心跳機制,進行服務過濾“
為了保證服務的高可用,對拿到列表中的服務 與 eureka始終做”心跳機制“,去檢測可用服務 -
IRule ”指定負載均衡規則“(修改處 )
拿到可用服務列表后,具體使用哪種負載均衡策略
- RibbonLoadBalancerClient.class 詳情見 Ribbon負載均衡策略
public class RibbonLoadBalancerClient implements LoadBalancerClient {
//serviceId 服務唯一標識,通過get拿到真正的server
public ServiceInstance choose(String serviceId) {
Server server = this.getServer(serviceId);
return server == null ? null : new RibbonLoadBalancerClient.RibbonServer(serviceId, server, this.isSecure(server, serviceId), this.serverIntrospector(serviceId).getMetadata(server));
}
//chooseServer 取到ILoadBalancer組件
protected Server getServer(ILoadBalancer loadBalancer) {
return loadBalancer == null ? null : loadBalancer.chooseServer("default");
}
- ILoadBalancer
public interface ILoadBalancer {
//再從這去到BaseLoadBalancer實現類
Server chooseServer(Object var1);
- BaseLoadBalancer.class
public class BaseLoadBalancer extends AbstractLoadBalancer implements PrimeConnectionListener, IClientConfigAware {
//rule 默認RoundRobinRule() 輪詢
private static final IRule DEFAULT_RULE = new RoundRobinRule();
//IRule 的實現類,就是哪些策略
protected IRule rule;
private final Counter createCounter() {
return Monitors.newCounter("LoadBalancer_ChooseServer");
}
public Server chooseServer(Object key) {
if (this.counter == null) {
//輪詢需要計數,好知道哪臺機器是否訪問過
this.counter = this.createCounter();
}
//計的數,自增長
this.counter.increment();
//基于rule規則進行選擇
if (this.rule == null) {
return null;
} else {
try {
return this.rule.choose(key);
} catch (Exception var3) {
logger.warn("LoadBalancer [{}]: Error choosing server for key {}", new Object[]{this.name, key, var3});
return null;
}
}
}
三.使用屬性自定義ribbon客戶端
在application.yml中
HELLO-SERVICE: #服務名,注意要與大小寫一致。(restTemplate.getForObject的url)
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule #規則要寫全限定名