目錄
Ribbon
簡(jiǎn)介
負(fù)載均衡
簡(jiǎn)介
負(fù)載均衡方式
服務(wù)端負(fù)載均衡
工作原理
特點(diǎn)
客戶端負(fù)載均衡
工作原理
特點(diǎn)
對(duì)比
實(shí)現(xiàn)
負(fù)載均衡策略
切換負(fù)載均衡策略
定制負(fù)載均衡策略
超時(shí)與重試
單個(gè)服務(wù)配置
全局配置
服務(wù)調(diào)用
示例
Ribbon
簡(jiǎn)介
????????Ribbon 是 Netflix 公司發(fā)布的開源組件,其主要功能是提供客戶端的負(fù)載均衡算法和服務(wù)調(diào)用;通過它,我們可以將面向服務(wù)的 REST 模板請(qǐng)求轉(zhuǎn)換為客戶端負(fù)載均衡的服務(wù)調(diào)用。微服務(wù)之間的調(diào)用,API 網(wǎng)關(guān)的請(qǐng)求轉(zhuǎn)發(fā)等內(nèi)容,實(shí)際上都是通過 Ribbon 來實(shí)現(xiàn)的。
負(fù)載均衡
簡(jiǎn)介
????????在任何一個(gè)系統(tǒng)中,負(fù)載均衡都是一個(gè)十分重要且不得不去實(shí)施的內(nèi)容,它是系統(tǒng)處理高并發(fā)、緩解網(wǎng)絡(luò)壓力和服務(wù)端擴(kuò)容的重要手段之一。
????????負(fù)載均衡,簡(jiǎn)單點(diǎn)說就是將用戶的請(qǐng)求平攤分配到多個(gè)服務(wù)器上運(yùn)行,以達(dá)到擴(kuò)展服務(wù)器帶寬、增強(qiáng)數(shù)據(jù)處理能力、增加吞吐量、提高網(wǎng)絡(luò)的可用性和靈活性的目的。
負(fù)載均衡方式
常見的負(fù)載均衡方式有兩種:服務(wù)端負(fù)載均衡、客戶端負(fù)載均衡
服務(wù)端負(fù)載均衡
工作原理
????????服務(wù)端負(fù)載均衡是在客戶端和服務(wù)端之間建立一個(gè)獨(dú)立的負(fù)載均衡服務(wù)器,該服務(wù)器既可以是硬件設(shè)備(例如 F5),也可以是軟件(例如 Nginx)。這個(gè)負(fù)載均衡服務(wù)器維護(hù)了一份可用服務(wù)端清單,然后通過心跳機(jī)制來刪除故障的服務(wù)端節(jié)點(diǎn),以保證清單中的所有服務(wù)節(jié)點(diǎn)都是可以正常訪問的。
????????當(dāng)客戶端發(fā)送請(qǐng)求時(shí),該請(qǐng)求不會(huì)直接發(fā)送到服務(wù)端進(jìn)行處理,而是全部交給負(fù)載均衡服務(wù)器,由負(fù)載均衡服務(wù)器按照某種算法(例如輪詢、隨機(jī)等),從其維護(hù)的可用服務(wù)清單中選擇一個(gè)服務(wù)端,然后進(jìn)行轉(zhuǎn)發(fā)。
特點(diǎn)
??????? 1.需要建立一個(gè)獨(dú)立的負(fù)載均衡服務(wù)器
??????? 2.負(fù)載均衡是在客戶端發(fā)送請(qǐng)求后進(jìn)行的,因此客戶端并不知道到底是哪個(gè)服務(wù)端提供的服務(wù)
??????? 3.可用服務(wù)端清單存儲(chǔ)在負(fù)載均衡服務(wù)器上
客戶端負(fù)載均衡
相較于服務(wù)端負(fù)載均衡,客戶端服務(wù)在均衡則是一個(gè)比較小眾的概念
工作原理
????????客戶端負(fù)載均衡是將負(fù)載均衡邏輯以代碼的形式封裝到客戶端上,即負(fù)載均衡器位于客戶端??蛻舳送ㄟ^服務(wù)注冊(cè)中心(例如 Eureka Server)獲取到一份服務(wù)端提供的可用服務(wù)清單。有了服務(wù)清單后,負(fù)載均衡器會(huì)在客戶端發(fā)送請(qǐng)求前通過負(fù)載均衡算法選擇一個(gè)服務(wù)端實(shí)例再進(jìn)行訪問,以達(dá)到負(fù)載均衡的目的;
????????客戶端負(fù)載均衡也需要心跳機(jī)制去維護(hù)服務(wù)端清單的有效性,這個(gè)過程需要配合服務(wù)注冊(cè)中心一起完成?
特點(diǎn)
??????? 1.負(fù)載均衡器位于客戶端,不需要單獨(dú)搭建一個(gè)負(fù)載均衡服務(wù)器
??????? 2.負(fù)載均衡是在客戶端發(fā)送請(qǐng)求前進(jìn)行的,因此客戶端清楚地知道是哪個(gè)服務(wù)端提供的服務(wù)
??????? 3.客戶端都維護(hù)了一份可用服務(wù)清單,而這份清單都是從服務(wù)注冊(cè)中心獲取的
????????Ribbon 就是一個(gè)基于 HTTP 和 TCP 的客戶端負(fù)載均衡器,當(dāng)我們將 Ribbon 和 Eureka 一起使用時(shí),Ribbon 會(huì)從 Eureka Server(服務(wù)注冊(cè)中心)中獲取服務(wù)端列表,然后通過負(fù)載均衡策略將請(qǐng)求分?jǐn)偨o多個(gè)服務(wù)提供者,從而達(dá)到負(fù)載均衡的目的
對(duì)比
實(shí)現(xiàn)
????????Ribbon 是一個(gè)客戶端的負(fù)載均衡器,它可以與 Eureka 配合使用輕松地實(shí)現(xiàn)客戶端的負(fù)載均衡。Ribbon 會(huì)先從 Eureka Server(服務(wù)注冊(cè)中心)去獲取服務(wù)端列表,然后通過負(fù)載均衡策略將請(qǐng)求分?jǐn)偨o多個(gè)服務(wù)端,從而達(dá)到負(fù)載均衡的目的
負(fù)載均衡策略
序號(hào) | 實(shí)現(xiàn)類 | 負(fù)載均衡策略 |
---|---|---|
1 | RoundRobinRule | 輪詢策略,即按照一定的順序依次選取服務(wù)實(shí)例 |
2 | RandomRule | 隨機(jī)選取一個(gè)服務(wù)實(shí)例 |
3 | RetryRule | 按照輪詢的策略來獲取服務(wù),如果獲取的服務(wù)實(shí)例為 null 或已經(jīng)失效,則在指定的時(shí)間之內(nèi)不斷地進(jìn)行重試,如果超過指定時(shí)間依然沒獲取到服務(wù)實(shí)例則返回?null? |
4 | WeightedResponseTimeRule | 根據(jù)平均響應(yīng)時(shí)間,來計(jì)算所有服務(wù)實(shí)例的權(quán)重,響應(yīng)時(shí)間越短的服務(wù)實(shí)例權(quán)重越高,被選中的概率越大 |
5 | BestAvailableRule | 先過濾點(diǎn)故障或失效的服務(wù)實(shí)例,然后再選擇并發(fā)量最小的服務(wù)實(shí)例 |
6 | AvailabilityFilteringRule | 先過濾掉故障或失效的服務(wù)實(shí)例,然后再選擇并發(fā)量較小的服務(wù)實(shí)例 |
7 | ZoneAvoidanceRule | 默認(rèn)的負(fù)載均衡策略,綜合判斷服務(wù)所在區(qū)域的性能和服務(wù)的可用性,來選擇服務(wù)實(shí)例 |
切換負(fù)載均衡策略
Ribbon 默認(rèn)使用輪詢策略選取服務(wù)實(shí)例,我們也可以根據(jù)自身的需求切換負(fù)載均衡策略,只需要在服務(wù)消費(fèi)者(客戶端)的配置類中,將 IRule 的其他實(shí)現(xiàn)類注入到容器中即可
在配置類 ConfigBean 中添加以下代碼,將負(fù)載均衡策略切換為?RandomRule(隨機(jī))
@Bean public IRule myRule() { // RandomRule 為隨機(jī)策略 return new RandomRule(); }
定制負(fù)載均衡策略
1.創(chuàng)建一個(gè)名為?MyRandomRule 的類
package net.biancheng.myrule;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import java.util.List;
/**
* 定制 Ribbon 負(fù)載均衡策略
*/
public class MyRandomRule extends AbstractLoadBalancerRule {
private int total = 0; // 總共被調(diào)用的次數(shù),目前要求每臺(tái)被調(diào)用5次
private int currentIndex = 0; // 當(dāng)前提供服務(wù)的機(jī)器號(hào)
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
return null;
}
Server server = null;
while (server == null) {
if (Thread.interrupted()) {
return null;
}
//獲取所有有效的服務(wù)實(shí)例列表
List<Server> upList = lb.getReachableServers();
//獲取所有的服務(wù)實(shí)例的列表
List<Server> allList = lb.getAllServers();
//如果沒有任何的服務(wù)實(shí)例則返回 null
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
//與隨機(jī)策略相似,但每個(gè)服務(wù)實(shí)例只有在調(diào)用 3 次之后,才會(huì)調(diào)用其他的服務(wù)實(shí)例
if (total < 3) {
server = upList.get(currentIndex);
total++;
} else {
total = 0;
currentIndex++;
if (currentIndex >= upList.size()) {
currentIndex = 0;
}
}
if (server == null) {
Thread.yield();
continue;
}
if (server.isAlive()) {
return (server);
}
server = null;
Thread.yield();
}
return server;
}
@Override
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
// TODO Auto-generated method stub
}
}
2.創(chuàng)建一個(gè)名為?MySelfRibbonRuleConfig 的配置類,將我們定制的負(fù)載均衡策略實(shí)現(xiàn)類注入到容器中
/**
* 定制 Ribbon 負(fù)載均衡策略的配置類
* 該自定義 Ribbon 負(fù)載均衡策略配置類 不能在 net.biancheng.c 包及其子包下
* 否則所有的 Ribbon 客戶端都會(huì)采用該策略,無法達(dá)到特殊化定制的目的
*/
@Configuration
public class MySelfRibbonRuleConfig {
@Bean
public IRule myRule() {
//自定義 Ribbon 負(fù)載均衡策略
return new MyRandomRule(); //自定義,隨機(jī)選擇某一個(gè)微服務(wù),執(zhí)行五次
}
}
3.修改位于啟動(dòng)類,在該類上使用 @RibbonClient 注解讓我們定制的負(fù)載均衡策略生效
@SpringBootApplication
@EnableEurekaClient
//自定義 Ribbon 負(fù)載均衡策略在主啟動(dòng)類上使用 RibbonClient 注解,在該微服務(wù)啟動(dòng)時(shí),就能自動(dòng)去加載我們自定義的 Ribbon 配置類,從而是配置生效
// name 為需要定制負(fù)載均衡策略的微服務(wù)名稱(application name)
// configuration 為定制的負(fù)載均衡策略的配置類,
// 且官方文檔中明確提出,該配置類不能在 ComponentScan 注解(SpringBootApplication 注解中包含了該注解)下的包或其子包中,即自定義負(fù)載均衡配置類不能在 net.biancheng.c 包及其子包下
@RibbonClient(name = "MICROSERVICECLOUDPROVIDERDEPT", configuration = MySelfRibbonRuleConfig.class)
public class MicroServiceCloudConsumerDept80Application {
public static void main(String[] args) {
SpringApplication.run(MicroServiceCloudConsumerDept80Application.class, args);
}
}
超時(shí)與重試
????????使用HTTP發(fā)起請(qǐng)求難免會(huì)發(fā)生問題,在F版開始Ribbon的重試機(jī)制默認(rèn)是開啟的,需要添加對(duì)超時(shí)時(shí)間與重試策略的配置;
單個(gè)服務(wù)配置
RIBBON-SERVICE-B:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
ConnectTimeout: 3000
ReadTimeout: 60000
MaxAutoRetries: 3 #對(duì)第一次請(qǐng)求的服務(wù)的重試次數(shù)
MaxAutoRetriesNextServer: 1 #要重試的下一個(gè)服務(wù)的最大數(shù)量(不包括第一個(gè)服務(wù))
OkToRetryOnAllOperations: true
全局配置
ribbon:
ConnectTimeout: 3000
ReadTimeout: 60000
MaxAutoRetries: 3 #對(duì)第一次請(qǐng)求的服務(wù)的重試次數(shù)
MaxAutoRetriesNextServer: 1 #要重試的下一個(gè)服務(wù)的最大數(shù)量(不包括第一個(gè)服務(wù))
OkToRetryOnAllOperations: true
服務(wù)調(diào)用
????????Ribbon 可以與 RestTemplate(Rest 模板)配合使用,以實(shí)現(xiàn)微服務(wù)之間的調(diào)用
????????RestTemplate 是 Spring 家族中的一個(gè)用于消費(fèi)第三方 REST 服務(wù)的請(qǐng)求框架。RestTemplate 實(shí)現(xiàn)了對(duì) HTTP 請(qǐng)求的封裝,提供了一套模板化的服務(wù)調(diào)用方法。通過它,Spring 應(yīng)用可以很方便地對(duì)各種類型的 HTTP 請(qǐng)求進(jìn)行訪問。
示例
1.引入依賴
<!--Spring Cloud Ribbon 依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
2.創(chuàng)建請(qǐng)求,調(diào)用服務(wù)端提供的服務(wù)
@RestController
public class DeptController_Consumer {
//private static final String REST_URL_PROVIDER_PREFIX = "http://localhost:8001/"; 這種方式是直調(diào)用服務(wù)方的方法,根本沒有用到 Spring Cloud
//面向微服務(wù)編程,即通過微服務(wù)的名稱來獲取調(diào)用地址
private static final String REST_URL_PROVIDER_PREFIX = "http://MICROSERVICECLOUDPROVIDERDEPT"; // 使用注冊(cè)到 Spring Cloud Eureka 服務(wù)注冊(cè)中心中的服務(wù),即 application.name
@Autowired
private RestTemplate restTemplate; //RestTemplate 是一種簡(jiǎn)單便捷的訪問 restful 服務(wù)模板類,是 Spring 提供的用于訪問 Rest 服務(wù)的客戶端模板工具集,提供了多種便捷訪問遠(yuǎn)程 HTTP 服務(wù)的方法
//獲取指定部門信息
@RequestMapping(value = "/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Integer id) {
return restTemplate.getForObject(REST_URL_PROVIDER_PREFIX + "/dept/get/" + id, Dept.class);
}
//獲取部門列表
@RequestMapping(value = "/consumer/dept/list")
public List<Dept> list() {
return restTemplate.getForObject(REST_URL_PROVIDER_PREFIX + "/dept/list", List.class);
}
}
3.訪問文章來源:http://www.zghlxwxcb.cn/news/detail-718732.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-718732.html
到了這里,關(guān)于Spring Cloud之負(fù)載均衡與服務(wù)調(diào)用(Ribbon)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!