日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Spring Cloud Ribbon詳解

作者:爆發的~小宇宙 更新時間: 2022-05-17 編程語言

Spring Cloud Ribbon

簡介

Ribbon 是Netflix公司的一個開源的負載均衡項目,是一個客戶端/進程內負載均衡器,運行在消費者端。

這里引出一個問題客戶端負載均衡和服務端負載均衡的區別是什么呢?

客戶端負載均衡和服務端負載均衡最大的不同在于服務清單所在的位置。

客戶端負載均衡中,客戶端中都維護著自己要訪問的服務段清單,
而這些清單都來源于服務注冊中心(動態地址,例如配置中心Eureka,Consul,Etcd等)
或者本地(靜態地址,可以配置在配置文件中進行維護,不方便)。

但是服務端負載均衡的服務清單是無法自己來維護的,例如Nignx是接收到請求后
把請求轉發到系統應用中。

簡單使用

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    <version>2.2.9.RELEASE</version>
</dependency>
@Configuration
public class RestTemplateConfiguration {

    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;
   @GetMapping
    public String order(){
        log.info("begin do order");
        String url="http://goods-service/goods";
        return goodsInfo=restTemplate.getForObject(url,String.class);
    }
}
goods-service.ribbon.listOfServers=\
  http://localhost:9090,http://localhost:9093

Ribbon連接數配置

Ribbon可以通過下面的配置項,來限制httpclient連接池的最大連接數量、以及針對不同host的最大連接數量。

Ribbon底層的網絡通信,采用的是HttpClient中的PoolingHttpClientConnectionManager連接池,連接池的好處是避免頻繁建立連接(針對單個目標地址)帶來的性能開銷,但是維護過多的鏈接會對客戶端造成內存以及維護上的成本。所以,可以通過MaxTotalConnections 限制總的連接數量,或者通過MaxConnectionsPerHost 限制針對每個host的最大連接數。

# 最大連接數
ribbon.MaxTotalConnections=200 (默認值:200)
# 每個host最大連接數
ribbon.MaxConnectionsPerHost=50 (默認值:50)

Ribbon核心之Ping機制

在ribbon負載均衡器中,提供了ping機制,每隔一段時間,就會去ping服務器,由com.netflix.loadbalancer.IPing 接口去實現。

單獨使用ribbon,不會激活ping機制,默認采用DummyPing(在RibbonClientConfiguration中實例化),isAlive()方法直接返回true。

ribbon和eureka集成,默認采用NIWSDiscoveryPing (在
EurekaRibbonClientConfiguration中實例化的),只有服務器列表的實例狀態為up的時候
才會為Alive。

IPing中默認內置了一些實現方法如下。

  1. PingUrl: 使用httpClient對目標服務逐個實現Ping操作
  2. DummyPing: 默認認為對方服務是正常的,直接返回true
  3. NoOpPing:永遠返回true

Ribbon中的負載均衡策略

負載均衡,不管Nginx還是Ribbon都需要其算法的支持,Nginx使用的是輪詢和加權輪詢算法。而在Ribbon中有更多的負載均衡調度算法,其默認是使用的RoundRobinRule輪詢策略。

  1. RoundRobinRule:輪詢策略。Ribbon默認采用的策略。若經過一輪輪詢沒有找到可用的provider,其最多輪詢 10 輪。若最終還沒有找到,則返回 null。

  2. RandomRule: 隨機策略,從所有可用的 provider 中隨機選擇一個。

  3. RetryRule: 重試策略。先按照 RoundRobinRule 策略獲取 provider,若獲取失敗,則在指定的時限內重試。默認的時限為 500 毫秒。

  4. WeightedRespinseTimeRule:權重輪詢。該策略是對RoundRobinRule的擴展,增加了根據實例的運行情況來計算權重,并根據權重來挑選實例,已達到更優的分配效果。

  5. ClientConfigEnabledRoundRobinRule:該策略較為特殊,我們一般不直接使用它。因為它本身并沒有實現什么特殊的處理邏輯,真如代碼中所示,在他的內部定義了一個RoundRobinRule策略,而choose函數的實現也正是使用了RoundRobinRule的線性輪詢機制,所以它實現的功能實際上RoundeRobinRule相同。
    雖然不能直接使用該策略,但是可以通過繼承該策略,默認的choose就實現了線性輪詢機制,但是可以在子類中實現更高級的策略

  6. BestAvailableRule:最低并發策略。該策略通過遍歷負載均衡器中維護的所有實例,會過濾調故障的實例,并找出并發請求數最小的一個,所以該策略的特征是選擇出最空閑的實例

  7. PredicateBaseRule:先通過子類中實現的Predicate邏輯來過濾一部分服務實例,然后再以線性輪詢的方式從過濾后的實例清單中選出一個。至于如何過濾,需要我們在AbstractServerPredicate的子類中實現apply方法來確定具體的實現策略。

  8. ZoneAvoidanceRule:區域權衡策略。它是PredicateBaseRule的具體實現類,從它的源碼中可以看到它是通過CompositePredicate來進行服務實例清單額過濾的。這是一個組合過濾條件,在其構造函數中,ZoneAvoidancePredicate為主過濾條件,AvailabilityPredicate為次過濾條件初始化了組合過濾條件的實例。綜合判斷server所在的區域性能和server可用性輪詢選擇server,并判斷AWS zone的運行性能是否可用,剔除不可用的區域中的server。

自定義負載均衡器

自定義負載均衡器需要實現AbstractLoadBalancerRule類

public class CustomerDefinieIpHashRule extends AbstractLoadBalancerRule {
    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {
        //....
    }

    public Server choose(ILoadBalancer lb, Object key) {
        if(lb==null){
            return null;
        }
        Server server=null;
        while(server==null){
            //表示啟動的服務列表.(默認情況下單純只用Ribbon時,不會對目標服務做心跳檢測)
            List<Server> upList=lb.getReachableServers();
            List<Server> allList=lb.getAllServers();
            int serverCount=upList.size();
            if(serverCount==0){
                return null;
            }
            int index=ipAddressHash(serverCount);
            server=upList.get(index);
        }
        return server;
    }
    // ip hash算法
    private int ipAddressHash(int serverCount){
        ServletRequestAttributes requestAttributes= (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        String remoteAddr=requestAttributes.getRequest().getRemoteAddr();
        int code=Math.abs(remoteAddr.hashCode());
        return code%serverCount;
    }

    @Override
    public Server choose(Object key) {
        return choose(getLoadBalancer(),key);
    }
}
  • 配置文件
goods-service.ribbon.NFLoadBalancerRuleClassName=cn.train.CustomerDefinieIpHashRule 

原文鏈接:https://blog.csdn.net/yu0_zhang0/article/details/124511181

欄目分類
最近更新