Ribbon负载均衡

概念

Ribbon是基于客户端的负载均衡,与nginx这种反向代理的负载均衡不同

导包



    org.springframework.cloud
    spring-cloud-starter-netflix-ribbon

配置

由于ribbon负载均衡基于消费者,所以提供者无需更改

消费者

配置类:

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

启动类:

@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class);
    }
}

修改负载均衡算法

默认为轮询算法

PROVIDER: # 服务id
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 轮询(负载均衡算法类)

写一个自己的负载均衡算法

写自己的负载均衡算法因该实现IRule接口,然后在application配置中修改算法,此算法类不需要注入spring容器
Ribbon负载均衡_第1张图片
照葫芦画瓢随机算法(public class RandomRule extends AbstractLoadBalancerRule)

算法类

特别注意的点:我们这里直接实现IRule,为了获取ILoadBalancer必须要写setLoadBalancer方法,不然无法获取服务列表

package com.roderick.config;

import com.netflix.loadbalancer.*;

import java.util.List;

/**
 * 轮流访问每个服务5次
 */
public class MyRule implements IRule {
    private int count = 0;
    private int currentIndex = 0;
    private ILoadBalancer loadBalancer;

    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        }
        Server server = null;

        while (server == null) {
            if (Thread.interrupted()) {
                return null;
            }
            List upList = lb.getReachableServers(); //可用的服务列表
            List allList = lb.getAllServers();  //所有的服务列表

            int serverCount = allList.size();
            if (serverCount == 0) {
                /*
                 * No servers. End regardless of pass, because subsequent passes
                 * only get more restrictive.
                 */
                return null;
            }

            if (count < 5) {
                server = upList.get(currentIndex);
                count++;    //5
            } else {
                count = 0;
                currentIndex++; //2
                if (currentIndex >= upList.size()) { //2
                    currentIndex = 0;
                }
                server = upList.get(currentIndex);
            }


            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 setLoadBalancer(ILoadBalancer lb) {
        this.loadBalancer = lb; //注意这里要设置,不然无法获取服务列表
    }

    @Override
    public ILoadBalancer getLoadBalancer() {
        return loadBalancer;
    }
}

测试

@SpringBootTest(classes = ConsumerApplication.class)
public class RibbonLoadBalanceTest {

    @Autowired
    LoadBalancerClient client;

    @Test
    public void loadBalance() {
        for (int i = 0; i < 20; i++) {
            ServiceInstance consumer = client.choose("PROVIDER");
            System.out.println(consumer.getPort());
        }
    }
}

Ribbon负载均衡_第2张图片

你可能感兴趣的:(springcloud,ribbon,java)