What is Ribbon
Ribbon is an open source project released by Netflix, and its main function is to provide client-side load balancing algorithms. The Ribbon client component provides a series of complete configuration items such as connection timeout, retry, etc. Ribbon will automatically help you connect to these machines based on certain rules (such as round-robin, random, etc.). When used, Ribbon also supports custom load balancing algorithms.
In SpirngCloud, Ribbon uses the service provider list information read from Eureka to make service requests based on the built-in load balancing algorithm when calling service nodes to provide services.
Difference between Ribbo and Nginx
Generally, to achieve load balancing, there will be two options, client load balancing and server load balancing
Nginx is server-side load balancing, and the load balancing strategy algorithm is implemented on the server side.
Ribbon is client-side load balancing, and the load balancing algorithm is maintained by the caller itself.
Strategy
Ribbon has built-in multiple load balancing strategies, and the internal top-level interface responsible for complex balancing is
com.netflix.loadbalancer.IRule;
com.netflix.loadbalancer.RoundRobinRule;polling strategy com.netflix.loadbalabcer.RandomRule; random strategy; com.netflix.loadbalancer.BestAvailableRule; best available strategy
usage
1. Add pom file
<!--Ribbon--> <!-- <dependency>--> <!-- <groupId>org.springframework.cloud</groupId>--> <!-- <artifactId>spring-cloud-starter-ribbon</artifactId>--> <!-- <version>1.4.6.RELEASE</version>--> <!-- </dependency>--> <!--comes with ribbon--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka- client</artifactId> </dependency>
2. Add annotations
@Bean @LoadBalanced //Ribbon public RestTemplate getRestTemplate(){ return new RestTemplate(); }
custom ribbon
1. Override method
public class KuangRandomRule extends AbstractLoadBalancerRule { //Each service, visit 5 times ~, change to the next service (3) // total=0, default=0, if=5, we point to the next service node // index=0, default 0, if total=5, index+1, private int total = 0; //the number of times it was called private int currentIndex = 0; //Who is currently providing the service~
//@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE") public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { return null; } Server server = null; while (server == null) { if (Thread.interrupted()) { return null; } List<Server> upList = lb.getReachableServers(); //get living service List<Server> allList = lb.getAllServers(); //get full service int serverCount = allList.size(); if (serverCount == 0) { return null; }
// int index = chooseRandomInt(serverCount); //Generate interval random numbers
// server = upList.get(index); //Get a random one from a live service~
//-========================================================= if (total<5){ server = upList.get(currentIndex); total++; }else { total = 0; currentIndex++; if (currentIndex>upList.size()){ currentIndex = 0; } server = upList.get(currentIndex); //From a live service, get the specified service to operate }
//-========================================================= if (server == null) { Thread.yield(); continue; } if (server.isAlive()) { return (server); } server = null; Thread.yield(); } return server; } protected int chooseRandomInt(int serverCount) { return ThreadLocalRandom.current().nextInt(serverCount); }
@Override public Server choose(Object key) { return choose(getLoadBalancer(), key); } @Override public void initWithNiwsConfig(IClientConfig clientConfig) { // TODO Auto-generated method stub } }
2. inject it ````java @Bean public IRule myRule(){ return new RoundRobinRule(); //The default is polling, now we define ~ KuangRandomRule }
Note: It must be written outside the main configuration, otherwise it will be scanned by componentscan. Otherwise, it is shared by all @RibbonClients. If you use @ComponentScan (or @SpringBootApplication ), you need to take steps to avoid including it (for example, you can put it in a separate, non-overlapping package, or specify that you want it in @ComponentScan).