zoukankan      html  css  js  c++  java
  • SpringCloud Netflix(四) : Riddon负载均衡

    简介

    Ribbon是一个客户端IPC库,在云中进行了测试。它提供了以下特性

    • 负载均衡

    • 容错性

    • 异步反应模型中的多协议(HTTP、TCP、UDP)支持

    • 缓存和批量处理

    基础使用

    1.导入依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        <version>2.2.2.RELEASE</version>
    </dependency>

    2.在RestTemplate Bean加上注解@LoadBalanced

    @Bean
    @LoadBalanced //默认采用的是RoundRobinRule,轮询策略
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    自定义负载均衡策略

    源码分析

    Riddon的负载均衡策略

    通过查看Riddon的源码可以看出,Riddon的负载均衡策略类都继承了AbstractLoadBalancerRule

    package com.netflix.loadbalancer;
    
    import com.netflix.client.IClientConfigAware;
    
    public abstract class AbstractLoadBalancerRule implements IRule, IClientConfigAware {
        private ILoadBalancer lb;
    
        public AbstractLoadBalancerRule() {
        }
    
        public void setLoadBalancer(ILoadBalancer lb) {
            this.lb = lb;
        }
    
        public ILoadBalancer getLoadBalancer() {
            return this.lb;
        }
    }

    AbstractLoadBalancerRule实现了Riddon的负载均衡方法接口 IRule

    package com.netflix.loadbalancer;
    
    public interface IRule {
        Server choose(Object var1);
    
        void setLoadBalancer(ILoadBalancer var1);
    
        ILoadBalancer getLoadBalancer();
    }

    所以我们只要继承AbstractLoadBalancerRule,重写IRule接口里的choose方法,并把自定义负载均衡策略的实现类通过配置类@Bean以IRule类型返回就可以自定义负载均衡策略了

    自定义负载均衡策略实现

    配置类不能放在@SpringBootApplication应用同级目类下,否则它由所有@RibbonClients共享,就达不到特殊化指定的目的了

    CustomConfiguration类必须是@Configuration类,但请注意,对于主应用程序上下文,它不在@ComponentScan中。否则,它由所有@RibbonClients共享。如果您使用@ComponentScan(或@SpringBootApplication),则需要采取措施避免将其包括在内(例如,可以将其放在单独的,不重叠的程序包中,或指定要在@ComponentScan)。

    • 创建负载均衡策略的配置类
    @Configuration
    public class MyRuleConfig {
        @Bean
        public IRule ribbonRule(){
            return new MyRule();
        }
    }
    • 创建负载均衡策略的实现类
    public class MyRule extends AbstractLoadBalancerRule {
    
        private static Logger log = LoggerFactory.getLogger(MyRule.class);
        private int total = 0;
        private int index = 0;
    
        @Override
        public void initWithNiwsConfig(IClientConfig iClientConfig) {
    
        }
        @Override
        public Server choose(Object o) {
            return this.choose(this.getLoadBalancer(),o);
        }
    
        public Server choose(ILoadBalancer lb, Object key) {
            if (lb == null) {
                return null;
            } else {
                Server server = null;
    
                while (server == null) {
                    if (Thread.interrupted()) {
                        return null;
                    }
    
                    List<Server> upList = lb.getReachableServers();//获取可获得到的服务,即没有故障可以运行的服务
                    List<Server> allList = lb.getAllServers();//获取所有服务
                    int serverCount = allList.size();
                    if (serverCount == 0) {
                        return null;
                    }
    
                    //自定义负载均衡方法,每个服务执行3次,依次轮询
                    if (total<3){
                        server = (Server) upList.get(index);//根据索引从可获得的服务中获取服务
                        total++;
                    }else {
                        total=0;
                        if (index>=upList.size()-1){
                            index=0;
                        }else {
                            index++;
                        }
                    }
    
                    if (server == null) {
                        Thread.yield();
                    } else {
                        if (server.isAlive()) {
                            return server;
                        }
    
                        server = null;
                        Thread.yield();
                    }
                }
    
                return server;
            }
        }
    }
    • 在主配置类上添加@RibbonClient
    @Configuration
    //name为服务提供者配置的spring.application.name,configuration为自定义负载均衡的配置类
    @RibbonClient(name = "SPRINGCLOUD-PROVIDER", configuration = MyRuleConfig.class) 
    public class BeanConfig {
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }

    我的个人博客站

  • 相关阅读:
    再说Play!framework http://hsfgo.iteye.com/blog/806974
    PlayFramework 1 自定义标签 -- FastTags http://unmi.cc/category/javajee/playframework/
    [译] 第三十天:Play Framework
    你可以使用 play framework 做5件很爽的事情http://www.anool.net/?p=629
    Play常用代码片段 http://www.anool.net/?p=625
    Play 内置模板标签(1.2.3版本)http://www.anool.net/?p=617
    for what? while 与 until 差在哪?-- Shell十三问<第十三问>
    你要 if 还是 case 呢?-- Shell十三问<第十二问>
    > 与 < 差在哪?-- Shell十三问<第十一问>
    && 与 || 差在哪?-- Shell十三问<第十问>
  • 原文地址:https://www.cnblogs.com/gaofei200/p/12897731.html
Copyright © 2011-2022 走看看