02. Ribbon

02. Ribbon

用于负载均衡

在eureka的基础上修改消费者模块

  • 添加依赖

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    

    如果引入的eureka-client 就可以不用引入ribbon依赖

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

    server:
      port: 8082 #可以设置为80端口, 这样就可以不用输出端口
    spring:
      application:
        name: microsoft-consumer-8082
      thymeleaf:
        cache: false
    eureka:
      client:
        #消费者不用注册仅服务中心,但是从服务中心拿服务fetch-registry 默认开启
        register-with-eureka: false
        service-url:
          #eureka集群
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    
    
  • 修改主启动类

    @EnableEurekaClient
    @SpringBootApplication
    public class MicrosoftConsumer8082Application {
    
    	public static void main(String[] args) {
    		SpringApplication.run(MicrosoftConsumer8082Application.class, args);
    	}
    }
    
  • 修改ConfigBean

    默认使用ZoneAvoidanceRule类似于RoundRobbin

        @Bean
        //负载均衡
        @LoadBalanced
        public RestTemplate getRestTemplate(){
            return new RestTemplate();
        }
    
  • 修改controller

    private static final String REST_URL_PREFIX = "http://microsoft-provider-8081/provider";
    

    如果不需要自定义Ribbon配置运行即可

#自定义Ribbon配置

  • The CustomConfiguration class must be a @Configuration class, but take care that it is not in a @ComponentScan for the main application context. Otherwise, it is shared by all the @RibbonClients.

  • The following table shows the beans that Spring Cloud Netflix provides by default for Ribbon:

    Bean Type Bean Name Class Name
    IClientConfig ribbonClientConfig DefaultClientConfigImpl
    IRule ribbonRule ZoneAvoidanceRule
    IPing ribbonPing DummyPing
    ServerList ribbonServerList ConfigurationBasedServerList
    ServerListFilter ribbonServerListFilter ZonePreferenceServerListFilter
    ILoadBalancer ribbonLoadBalancer ZoneAwareLoadBalancer
    ServerListUpdater ribbonServerListUpdater PollingServerListUpdater

    需要将自定义的RibbonConfig放在著启动类扫描范围之外

    #RibbonConfig
    @Configuration(proxyBeanMethods = false)
    public class MyRibbonConfig {
    
        @Bean
        public IRule ribbonRule() {
            return new MyRibbonRule();
        }
    }
    
    #RibbonRule
    //实现随机调用每台服务器五次
    //自定义rule
    public class MyRibbonRule extends AbstractLoadBalancerRule {
        int currentIndex = 0;
        int total = 0;
    
        public Server choose(ILoadBalancer lb, Object key) {
            if (null == lb) {
                return null;
            }
            Server server = null;
            //多线程判断while
            while (server == null) {
                if (Thread.interrupted()) {//检测当前线程是否被打断
                    return null;
                }
                List<Server> upServers = lb.getReachableServers();//当前存活的服务
                List<Server> allServers = lb.getAllServers();//获取所有服务
                int serverCount = allServers.size();
                if (0 == serverCount) {
                    return null;
                }
                if (total < 5) {
                    server = upServers.get(currentIndex);
                    total++;
                } else {
                    total = 0;
                    currentIndex++;
                    if (currentIndex >= upServers.size()) {
                        currentIndex = 0;
                    }
                }
                if (server == null) {
                    /*
                     * The only time this should happen is if the server list were
                     * somehow trimmed. This is a transient condition. Retry after
                     * yielding.
                     */
                    Thread.yield();
                    continue;
                }
                if (server.isAlive()) {
                    return (server);
                }
                // Shouldn't actually happen.. but must be transient or a bug.
                server = null;
                Thread.yield();
            }
            return server;
    
        }
    
    
    
        @Override
        public Server choose(Object key) {
            return choose(getLoadBalancer(), key);
        }
    
        @Override
        public void initWithNiwsConfig(IClientConfig clientConfig) {
    
        }
    }
    
    #主启动类
    //自定义ribbon rule , 如果采用默认的rule不用配置也行
    //name是微服务的名字, 应该采用全大写
    @RibbonClient(name = "MICROSOFT-PROVIDER",configuration = MyRibbonConfig.class)
    @EnableEurekaClient
    @SpringBootApplication
    public class MicrosoftConsumer80Application {
    
    	public static void main(String[] args) {
    		SpringApplication.run(MicrosoftConsumer80Application.class, args);
    	}
    }
    
原文地址:https://www.cnblogs.com/kikochz/p/12868778.html