柚子快報邀請碼778899分享:面試 Ribbon負載均衡器
1. 負載均衡器
目前主流的負載方案分為以下兩種:(面試題)
1.1 服務(wù)端負載均衡
在消費者和服務(wù)提供方中間使用獨立的代理方式進行負載,有硬件的(比如 F5),也有軟件的(比如 Nginx,openResty)
例如Nginx,通過Nginx進行負載均衡,先發(fā)送請求,然后通過負載均衡算法,在多個服務(wù)器之間選擇一個進行訪問;即在服務(wù)器端再進行負載均衡算法分配。
2 客戶端負載均衡器
客戶端根據(jù)自己的請求情況做負載均衡,Ribbon 就屬于客戶端自己做負載均衡。
2.Ribbon
Spring Cloud Ribbon是基于Netflix Ribbon 實現(xiàn)的一套客戶端的負載均衡工具,Ribbon客戶端組件提供一系列的完善的配置,如超時,重試等。通過LoadBalancer獲取到服務(wù)提供的所有機器實例,Ribbon會自動基于某種規(guī)則(輪詢,隨機)去調(diào)用這些服務(wù)。Ribbon也可以實現(xiàn)我們自己的負載均衡算法。
3.常見的負載均衡算法
如果使用的RestTemplate進行服務(wù)調(diào)用,那么創(chuàng)建RestTemplate的方法上面加@LoadBalanced注解就會開啟Ribbon的負載均衡,Ribbon負載均衡有以下7中規(guī)則,默認輪詢。
RoundRobinRule(輪詢規(guī)則): 最簡單的負載均衡策略,按照順序循環(huán)地將請求分發(fā)到每個服務(wù)實例。每個服務(wù)實例依次接收請求,實現(xiàn)基本的公平分配。 AvailabilityFilteringRule(可用性過濾規(guī)則): 此規(guī)則會先從服務(wù)列表中過濾掉由于多次訪問失敗而標記為“短路”的服務(wù)實例,以及那些當前并發(fā)連接數(shù)過高的實例,然后采用輪詢的方式選擇一個可用的服務(wù)實例。它可以有效避免將請求分發(fā)到已知有問題的實例上。 WeightedResponseTimeRule(加權(quán)響應(yīng)時間規(guī)則): 根據(jù)每個服務(wù)實例的歷史響應(yīng)時間動態(tài)調(diào)整其權(quán)重,響應(yīng)時間越快的服務(wù)實例被選中的概率越高。這種方式可以逐漸將更多流量導(dǎo)向性能更好的服務(wù)實例。 RandomRule(隨機規(guī)則): 隨機選擇一個服務(wù)實例來處理請求。雖然簡單,但在某些場景下可以減少特定服務(wù)實例被連續(xù)擊中的可能性。 BestAvailableRule(最佳可用規(guī)則): 選擇當前并發(fā)請求數(shù)最少的服務(wù)實例,如果有多個這樣的實例,則隨機選擇一個。這個策略側(cè)重于選擇當前負載較低的服務(wù)。 ZoneAvoidanceRule(區(qū)域避免規(guī)則): 這個規(guī)則不僅考慮實例的可用性,還會考慮網(wǎng)絡(luò)延遲,傾向于選擇同區(qū)域中表現(xiàn)最好的服務(wù)實例。特別適合部署在多區(qū)域環(huán)境中的服務(wù),以減少跨區(qū)域的網(wǎng)絡(luò)延遲。
這些規(guī)則通過實現(xiàn) IRule 接口來定義,允許用戶根據(jù)自己的業(yè)務(wù)需求選擇合適的負載均衡策略。此外,Ribbon 還支持自定義規(guī)則,用戶可以根據(jù)特定場景實現(xiàn)自己的負載均衡邏輯
4.Nacos中使用Rabbion
nacos-discovery已經(jīng)包含Ribbon的依賴,不需要再單獨引入Ribbon
4.1添加@LoadBalanced注解
@Configuration
public class RestConfig {
@Bean
@LoadBalanced
//注意:需要添加@LoadBalanced注解
//如果使用了注冊中心,必須加@LoadBalanced
//作用:RestTemplate 就會把url上面的一級目錄最為服務(wù)名,去注冊中心找到對應(yīng)的ip列表,
//根據(jù)算法使用其中一個ip,調(diào)用該ip對應(yīng)的接口
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
4.2 調(diào)用
@SpringBootApplication
public class NacosApplication {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(NacosApplication.class, args);
RestTemplate restTemplate = ctx.getBean(RestTemplate.class);
String forObject = restTemplate.getForObject("http://nacos-b/hello", String.class);
System.out.println(forObject);
}
}
5.Ribbon負載均衡策略
IRule這是所有負載均衡策略的父接口,里邊的核心方法就是choose方法,用來選擇一個服務(wù)實例。
6.修改默認負載均衡策略
6.1使用其它規(guī)則
@Configuration
public class MyRuleConfig {
@Bean
public IRule rule(){
return new RandomRule();
}
}
?6.2自定義規(guī)則
public class MyRule extends AbstractLoadBalancerRule {
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
//JUC包下,線程安裝的Integer
private static AtomicInteger count = new AtomicInteger(0);
private Server server = null;
@Override
@SneakyThrows
public Server choose(Object key) {
BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
//獲取服務(wù)名稱
String serverName = loadBalancer.getName();
NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
List
//6062
Instance maxInstance = allInstances.stream().max(Comparator.comparing(Instance::getWeight)).get();
//6061
Instance minInstance = allInstances.stream().min(Comparator.comparing(Instance::getWeight)).get();
int count2 = count.addAndGet(1);
System.out.println(count2);
int mod = count2 % 5; //取模運算 5,10,15,20,25 ...
if(mod == 0){ //當次數(shù)是5的倍數(shù)的時候,mod就是0, 6061
server = new Server(minInstance.getIp(),minInstance.getPort());
} else {
//mod 是 1,2,3,4 的時候打到權(quán)重高的這個機器上 6062
server = new Server(maxInstance.getIp(),maxInstance.getPort());
}
return server;
}
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
}
6.3 使用自己的規(guī)則(兩種配置方式)
6.3.1 使用注解配置
@Configuration
@RibbonClients(defaultConfiguration = MyRule.class) //全局設(shè)置負載規(guī)則,默認是輪詢的
@RibbonClient(name = "order-nacos-a", configuration = MyRule.class) //針對某個服務(wù),特殊配置
public class RibbonConfig {
/**
* 全局配置
* 指定負載均衡策略
*/
@Bean
public IRule iRule() {
//使用隨機的策略
return new RandomRule();
//指定使用Nacos提供的負載均衡策略
return new NacosRule();
//使用自己的規(guī)則
return new MyRule();
}}
6.3.2 基于配置文件配置,調(diào)用指定微服務(wù)提供的服務(wù)時,使用對應(yīng)的負載均衡算法
#配置具體某一個服務(wù)個性化規(guī)則
nacos-b.ribbon.NFLoadBalancerRuleClassName=com.beiyou.config.MyRule
##配置全局的負載均衡規(guī)則 (不生效)
default.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RoundRobinRule
如果同時應(yīng)用了以上兩種方式去配置負載均衡,注解的優(yōu)先級更高,則以注解為準.
因為配置文件的加載順序在注解之前,后加載的配置會覆蓋先前配置。
推薦使用配置文件,可以放進nacos,比較靈活。
7.饑餓加載 (面試題)
在進行服務(wù)調(diào)用的時候,如果網(wǎng)絡(luò)情況不好,第一次調(diào)用會超時。
Ribbon默認懶加載,意味著只有在發(fā)起調(diào)用的時候才會創(chuàng)建客戶端。
開啟饑餓加載,解決第一次調(diào)用慢的問題:
ribbon:
??eager-load:
????#開啟ribbon饑餓加載
????enabled:?true
????#配置order-service使用ribbon饑餓加載,多個使用逗號分隔
????clients:?order-service
8.內(nèi)核原理
柚子快報邀請碼778899分享:面試 Ribbon負載均衡器
文章來源
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。