Netflix Ribbon
調(diào)度算法
1庞瘸、First Come First Served 先來先服務(wù)
2、Earliest deadline first 最早截止時(shí)間優(yōu)先
3拿诸、Shortest remaining time first 最短保留時(shí)間優(yōu)先
4、Fixed Priority 固定優(yōu)先級(jí)
5塞茅、Round-Robin 輪訓(xùn)
6亩码、Multilevel Queue 多級(jí)別隊(duì)列列
引入Maven 依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
激活 Ribbon 客戶端
package com.segumentfault.springcloudlesson6;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
// 多個(gè) Ribbon 定義
@RibbonClients({
@RibbonClient(name = "spring-cloud-service-provider")
})
public class SpringCloudLesson6Application {
public static void main(String[] args) {
SpringApplication.run(SpringCloudLesson6Application.class, args);
}
//聲明 RestTemplate 開啟負(fù)載均衡的注解
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
配置 Ribbon 客戶端
application.properties
### 配置ribbon 服務(wù)地提供方
spring-cloud-service-provider.ribbon.listOfServers = \
http://${serivce-provider.host}:${serivce-provider.port}
調(diào)整 RestTemplate
//聲明 RestTemplate
@LoadBalanced // RestTemplate 的行為變化
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
Neflix Ribbon 整合 Eureka
激活服務(wù)發(fā)現(xiàn)的客戶端
package com.segumentfault.springcloudlesson6;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
// 多個(gè) Ribbon 定義
@RibbonClients({
@RibbonClient(name = "spring-cloud-service-provider")
})
@EnableDiscoveryClient // 激活服務(wù)發(fā)現(xiàn)客戶端
public class SpringCloudLesson6Application {
public static void main(String[] args) {
SpringApplication.run(SpringCloudLesson6Application.class, args);
}
//聲明 RestTemplate
@LoadBalanced // RestTemplate 的行為變化 開啟負(fù)載均衡的注解
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
創(chuàng)建并且啟動(dòng) Eureka Server
以spring-cloud-lesson6-eureka-server
為例
激活 Eureka Server
package com.segumentfault.springcloudlesson6eurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class SpringCloudLesson6EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudLesson6EurekaServerApplication.class, args);
}
}
配置 Eureka 服務(wù)器
## Eureka Serer
spring.application.name = spring-cloud-eureka-server
## 服務(wù)端口
server.port = 10000
## Spring Cloud Eureka 服務(wù)器作為注冊(cè)中心
## 通常情況下,不需要再注冊(cè)到其他注冊(cè)中心去
## 同時(shí)野瘦,它也不需要獲取客戶端信息
### 取消向注冊(cè)中心注冊(cè)
eureka.client.register-with-eureka = false
### 取消向注冊(cè)中心獲取注冊(cè)信息(服務(wù)描沟、實(shí)例信息)
eureka.client.fetch-registry = false
## 解決 Peer / 集群 連接問題
eureka.instance.hostname = localhost
eureka.client.serviceUrl.defaultZone = http://${eureka.instance.hostname}:${server.port}/eureka
啟動(dòng) Eureka Server
調(diào)整 Ribbon 客戶端連接 Eureka Server
applicaiont.properties
## 服務(wù)提供方
spring.application.name = spring-cloud-ribbon-client
### 服務(wù)端口
server.port = 8080
### 管理安全失效
management.security.enabled = false
### 暫時(shí)性關(guān)閉 Eureka 注冊(cè)
## 當(dāng)使用 Eureka 服務(wù)發(fā)現(xiàn)時(shí),請(qǐng)注釋掉一下配置
# eureka.client.enabled = false
## 連接 Eureka Sever
eureka.client.serviceUrl.defaultZone = http://localhost:10000/eureka/
### 服務(wù)提供方主機(jī)
serivce-provider.host = localhost
### 服務(wù)提供方端口
serivce-provider.port = 9090
serivce-provider.name = spring-cloud-service-provider
### 配置ribbon 服務(wù)地提供方
## 當(dāng)使用 Eureka 服務(wù)發(fā)現(xiàn)時(shí)鞭光,請(qǐng)注釋掉一下配置
# spring-cloud-service-provider.ribbon.listOfServers = \
http://${serivce-provider.host}:${serivce-provider.port}
調(diào)整服務(wù)提供方并且連接 Eureka Server
## 服務(wù)提供方
spring.application.name = spring-cloud-service-provider
### 服務(wù)端口
server.port = 9090
### 管理安全失效
management.security.enabled = false
### 暫時(shí)性關(guān)閉 Eureka 注冊(cè)
## 當(dāng)使用 Eureka 服務(wù)發(fā)現(xiàn)時(shí)吏廉,請(qǐng)注釋掉一下配置
# eureka.client.enabled = false
## 連接 Eureka Sever
eureka.client.serviceUrl.defaultZone = http://localhost:10000/eureka/
再啟動(dòng)兩臺(tái)服務(wù)提供方實(shí)例
--server.port=9091
--server.port=9092
實(shí)際請(qǐng)求客戶端
- LoadBalancerClient
- RibbonLoadBalancerClient
負(fù)載均衡上下文
- LoadBalancerContext
- RibbonLoadBalancerContext
負(fù)載均衡器
- ILoadBalancer
- BaseLoadBalancer
- DynamicServerListLoadBalancer
- ZoneAwareLoadBalancer
- NoOpLoadBalancer
總結(jié)一下:
ILoadBalancer接口實(shí)現(xiàn)類做了以下的一些事情:
1.維護(hù)了存儲(chǔ)服務(wù)實(shí)例Server對(duì)象的二個(gè)列表。一個(gè)用于存儲(chǔ)所有服務(wù)實(shí)例的清單惰许,一個(gè)用于存儲(chǔ)正常服務(wù)的實(shí)例清單
2.初始化得到可用的服務(wù)列表席覆,啟動(dòng)定時(shí)任務(wù)去實(shí)時(shí)的檢測(cè)服務(wù)列表中的服務(wù)的可用性,并且間斷性的去更新服務(wù)列表汹买,結(jié)合注冊(cè)中心佩伤。
3.選擇可用的服務(wù)進(jìn)行調(diào)用(這個(gè)一般交給IRule去實(shí)現(xiàn),不同的輪詢策略)
三個(gè)很重要的概念
ServerList接口:定義用于獲取服務(wù)器列表的方法的接口,主要實(shí)現(xiàn)DomainExtractingServerList接口晦毙,每隔30s種執(zhí)行g(shù)etUpdatedListOfServers方法進(jìn)行服務(wù)列表的更新畦戒。
ServerListUpdater接口:主要實(shí)現(xiàn)類EurekaNotificationServerListUpdater和PollingServerListUpdater(默認(rèn)使用的是PollingServerListUpdater,結(jié)合Eureka注冊(cè)中心结序,定時(shí)任務(wù)的方式進(jìn)行服務(wù)列表的更新)
ServerListFilter接口:根據(jù)LoadBalancerStats然后根據(jù)一些規(guī)則去過濾部分服務(wù)障斋,比如根據(jù)zone(區(qū)域感知)去過濾。(主要實(shí)現(xiàn)類ZonePreferenceServerListFilter的getFilteredListOfServers會(huì)在更新服務(wù)列表的時(shí)候去執(zhí)行)。
負(fù)載均衡規(guī)則
核心規(guī)則接口
- IRule
- 隨機(jī)規(guī)則:RandomRule 隨機(jī)選擇一個(gè)server
- 最可用規(guī)則:BestAvailableRule 選擇一個(gè)最小的并發(fā)請(qǐng)求的server
- 輪訓(xùn)規(guī)則:RoundRobinRule 默認(rèn)策略 輪詢選擇server
- 重試實(shí)現(xiàn):RetryRule 對(duì)選定的負(fù)載均衡策略機(jī)上重試機(jī)制
- 客戶端配置:ClientConfigEnabledRoundRobinRule
- 可用性過濾規(guī)則:AvailabilityFilteringRule 過濾掉那些因?yàn)橐恢边B接失敗的被標(biāo)記為circuittripped的后端server垃环,并過濾掉那些高并發(fā)的的后端server(active connections 超過配置的閾值)
- RT權(quán)重規(guī)則:WeightedResponseTimeRule 根據(jù)相應(yīng)時(shí)間分配一個(gè)weight邀层,相應(yīng)時(shí)間越長,weight越小遂庄,被選中的可能性越低寥院。
- 規(guī)避區(qū)域規(guī)則:ZoneAvoidanceRule 復(fù)合判斷server所在區(qū)域的性能和server的可用性選擇server
PING 策略
核心策略接口
- IPingStrategy
PING 接口
- IPing
- NoOpPing
- DummyPing
- PingConstant
- PingUrl
Discovery Client 實(shí)現(xiàn)
- NIWSDiscoveryPing