1, Concept: ribbon
2, ribbon utility
3, Realize
3.1 client configuration: spring cloud-consumer-dept-80 uses Ribbon
Step 1: first, add two dependencies to the 80 project
<!--Ribbon--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> <version>1.4.7.RELEASE</version> </dependency> <!--Import Ribbon Import at the same time erueka,Because it wants to find out where the service comes from--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> <version>1.4.7.RELEASE</version> </dependency>
Step 2: configure: create a configuration class ConfigBean
@Bean @LoadBalanced //Ribbon, as long as this annotation is added, the RestTemplate becomes load balancing public RestTemplate getRestTemplate() { return new RestTemplate(); }
Because our consumer client uses RestTemplate to read the service, we let RestTemplate realize load balancing. We only need to add an annotation @ LoadBalanced
Step 3: configure yml
server: port: 80 #Eureka configuration eureka: client: register-with-eureka: false #Do not register yourself with eureka service-url: defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
Step 4: configure the main class: deptconsumer_ eighty
//After the integration of Ribbon and Eureka, the client can call directly without caring about the IP address and port number @SpringBootApplication //@EnableEurekaClient / / automatically register with Eureka after the service is started public class DeptConsumer_80 { public static void main(String[] args) { SpringApplication.run(DeptConsumer_80.class, args); } }
Step 5: write DeptConsumerController
Finally, another problem is that our RestTemplate implements load balancing, so how to reflect it? Now we just add a comment on it, which is certainly not good. We also need to change the request path of RestTemplate to make it automatically select, rather than write it dead. The address should be a variable and accessed through the service name; Not Eureka name
//private static final String REST_URL_PREFIX = "http://localhost:8001"; //When using Ribbon for load balancing, it should not be written or dead. The address should be a variable and accessed through the service name private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";
Finally, start 7001, 7002 and 7003 projects, and then start 8001 project. After 8001 project is registered in three of them, start 80 projects
Then visit http://localhost/consumer/dept/list You can see the normal return results. Of course, you can't see load balancing here, so you will configure multiple service providers and multiple databases to test the effect of load balancing.
3.2 load balancing using Ribbon
Step 1: create two other databases: db02 and db03
Step 2: create two other service providers: 8002 and 8003
Directly create two sub model s, and then copy all files of 8001 (provide the same service), which are the same, and then change the configuration file
pom.xml dependency
The port number of application.yml, the corresponding database, and instance ID, for example: instance ID: springcloud-provider-dept8002
Note: do not change the following service ID
spring: application: name: springcloud-provider-dept # The consistency of three service names is the premise
Then, start springcloud-config-eureka-7001 springcloud-config-eureka-7002 springcloud-config-eureka-7003 springcloud-provider-dept-8001 springcloud-provider-dept-8002 springcloud-provider-dept-8003 springcloud-consumer-dept-80
Then visit http://localhost/consumer/dept/list , access the database several times. The query data has not changed, but the database has changed
Step 3: Ribbon custom equalization algorithm
You will find that polling means that each service comes in turn, which is also the default algorithm of Ribbon
There is a very important interface: IRule, which is basically implemented by all equalization algorithms
There are so many equalization algorithms, because the default is polling algorithm, that is, roundrobin rule. How do we use other algorithms?
Just register the Bean in the config class of the 80 project
//IRule //Roundrobin rule: polling //RandomRule: random //Availability filtering rule: it will filter out the tripped and failed services ~, and poll the rest //RetryRule: the service will be obtained according to the polling first. If the service acquisition fails, it will be retried within the specified time @Bean public IRule myRule() { return new RandomRule(); //The default is polling. Now we use random polling }
Then start the 80 project and visit http://localhost/consumer/dept/list , visit the database several times and find that there is no rule to follow every time
Optimize previous step
We should learn to customize the load balancing algorithm. In order to reflect that we have used the custom load balancing algorithm, we should build the package in the same level directory of the main startup class (official suggestion)
Comment out the Bean just written in ConfigBean. Let's imitate its algorithm and write our own algorithm
Step 1: write a configuration class
In the main class configuration, in order to scan the configuration class
Step 2: write a custom method
public class KuangRandomRule extends AbstractLoadBalancerRule { //Visit each machine 5 times and change to the next service (3 in total) //total = 0, default = 0. If = 5, we point to the next service node //index = 0, default = 0, if total=5, then index+1, private int total = 0; //Number of calls private int currentIndex = 0; //Who is currently providing services 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(); //Access to living services List<Server> allList = lb.getAllServers(); //Access to all services int serverCount = allList.size(); if (serverCount == 0) { return null; } //============================================================= if (total < 5) { total++; } else { total = 0; currentIndex++; if (currentIndex >= serverCount) { currentIndex = 0; } } server = upList.get(currentIndex); //============================================================= 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) { } }
Modify a custom configuration class
@Configuration public class WuRule { @Bean public IRule myRule() { return new KuangRandomRule(); //The default is polling. Now try to use your own custom } }
Then restart the 80 project to access http://localhost/consumer/dept/list , visit more times, and you can find that the accessed services are switched every 5 times