ribbon有7種負載均衡策略可供選擇:
1、隨機策略——RandomRule
2、輪詢策略——RoundRobinRule
注:Ribbon默認策略
3、重試策略——RetryRule
4、最低並發策略——BestAvailableRule
5、可用過濾策略——AvailabilityFilteringRule
過濾掉那些因為一直連接失敗的被標記為circuit tripped的后端server,並過濾掉那些高並發的的后端server(active connections 超過配置的閾值)
性能僅次於最低並發策略。
6、響應時間加權策略——WeightedResponseTimeRule
每隔30秒計算一次服務器響應時間,以響應時間作為權重,響應時間越短的服務器被選中的概率越大。
7、區域權衡策略——ZoneAvoidanceRule
Ribbon的負載均衡策略使用建議
一般情況下,推薦使用最低並發策略,這個性能比默認的輪詢策略高很多。
策略類 | 命名 | 描述 |
RandomRule | 隨機策略 | 隨機選擇server |
RoundRobinRule | 輪詢策略 | 按照順序選擇server(ribbon默認策略) |
RetryRule | 重試策略 | 在一個配置時間段內,當選擇server不成功,則一直嘗試選擇一個可用的server |
BestAvailableRule | 最低並發策略 | 逐個考察server,如果server斷路器打開,則忽略,再選擇其中並發鏈接最低的server |
AvailabilityFilteringRule | 可用過濾策略 | 過濾掉一直失敗並被標記為circuit tripped的server,過濾掉那些高並發鏈接的server(active connections超過配置的閾值) |
ResponseTimeWeightedRule | 響應時間加權重策略 | 根據server的響應時間分配權重,響應時間越長,權重越低,被選擇到的概率也就越低。響應時間越短,權重越高,被選中的概率越高,這個策略很貼切,綜合了各種因素,比如:網絡,磁盤,io等,都直接影響響應時間 |
ZoneAvoidanceRule | 區域權重策略 | 綜合判斷server所在區域的性能,和server的可用性,輪詢選擇server並且判斷一個AWS Zone的運行性能是否可用,剔除不可用的Zone中的所有server |
配置類配置
package com.wsm.ribbon; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RandomRule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RibbonRandomRuleConfig { //方法名一定要中 iRule @Bean public IRule iRule(){ return new RandomRule(); } }
package com.wsm.order.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import javax.swing.*; @RestController @RequestMapping("/order") public class OrderController { @Autowired RestTemplate restTemplate; @RequestMapping("/add") public String add(){ System.out.println("aaaaaaaaaaaaa"); // String msg = restTemplate.getForObject("http://localhost:8011/stock/reduct", String.class); String msg = restTemplate.getForObject("http://stock-service/stock/reduct", String.class); return "hello world "+msg; } }
package com.wsm.order; import com.wsm.ribbon.RibbonRandomRuleConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.client.RestTemplateBuilder; 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.web.client.RestTemplate; @SpringBootApplication //@EnableDiscoveryClient 老版本要加,新版本可以不加 @RibbonClients(value = { @RibbonClient(name = "stock-service",configuration = RibbonRandomRuleConfig.class) }) public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class,args); } @Bean @LoadBalanced //啟用負載均衡 public RestTemplate restTemplate(RestTemplateBuilder builder){ RestTemplate restTemplate = builder.build(); return restTemplate; } }
server: port: 8030 #應用名稱 (nacos 會將該名稱當作服務名稱) spring: application: name: order-ribbon-service cloud: nacos: # server-addr: 127.0.0.1:8848 server-addr: 192.168.133.128:8847 #集群 nginx 負載均衡訪問 nacos discovery: username: nacos password: nacos namespace: public
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springcloudalibaba</artifactId> <groupId>com.wsm.springcloud</groupId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>order-ribbon</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- <version>2.5.5</version>--> </dependency> <!-- nacos 服務注冊發現 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies> </project>
配置文件配置
server:
port: 8030
#應用名稱 (nacos 會將該名稱當作服務名稱)
spring:
application:
name: order-ribbon-service
cloud:
nacos:
# server-addr: 127.0.0.1:8848
server-addr: 192.168.133.128:8847 #集群 nginx 負載均衡訪問 nacos
discovery:
username: nacos
password: nacos
namespace: public
stock-service:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule #指定使用Nacos提供的負載均衡策略(優先調用同一集群的實例,基於隨機&權重)
package com.wsm.order; import com.wsm.ribbon.RibbonRandomRuleConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.client.RestTemplateBuilder; 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.web.client.RestTemplate; @SpringBootApplication //@EnableDiscoveryClient 老版本要加,新版本可以不加 //@RibbonClients(value = { // @RibbonClient(name = "stock-service",configuration = RibbonRandomRuleConfig.class) //}) public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class,args); } @Bean @LoadBalanced //啟用負載均衡 public RestTemplate restTemplate(RestTemplateBuilder builder){ RestTemplate restTemplate = builder.build(); return restTemplate; } }
自定義負載均衡策略
package com.wsm.ribbon.rule; 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; import java.util.concurrent.ThreadLocalRandom; public class CustomRule extends AbstractLoadBalancerRule { @Override public Server choose(Object o) { ILoadBalancer loadBalancer = this.getLoadBalancer(); //獲得當前請求的服務實例 List<Server> reachableServers = loadBalancer.getReachableServers(); int random = ThreadLocalRandom.current().nextInt(reachableServers.size()); Server server = reachableServers.get(random); // if(server.isAlive()){ // return server; // } return server; } @Override public void initWithNiwsConfig(IClientConfig iClientConfig) { } }
server: port: 8030 #應用名稱 (nacos 會將該名稱當作服務名稱) spring: application: name: order-ribbon-service cloud: nacos: # server-addr: 127.0.0.1:8848 server-addr: 192.168.133.128:8847 #集群 nginx 負載均衡訪問 nacos discovery: username: nacos password: nacos namespace: public stock-service: ribbon: # NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule #指定使用Nacos提供的負載均衡策略(優先調用同一集群的實例,基於隨機&權重) NFLoadBalancerRuleClassName: com.wsm.ribbon.rule.CustomRule
server: port: 8030 #應用名稱 (nacos 會將該名稱當作服務名稱) spring: application: name: order-ribbon-service cloud: nacos: # server-addr: 127.0.0.1:8848 server-addr: 192.168.133.128:8847 #集群 nginx 負載均衡訪問 nacos discovery: username: nacos password: nacos namespace: public stock-service: ribbon: # NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule #指定使用Nacos提供的負載均衡策略(優先調用同一集群的實例,基於隨機&權重) NFLoadBalancerRuleClassName: com.wsm.ribbon.rule.CustomRule ribbon: eager-load: enabled: true #開啟ribbon飢餓加載 clients: stock-service #配置stock-service使用ribbon飢餓加載,多個使用逗號分隔