Original link: https://www.javazhiyin.com/5130.html
Micro-Service Development column: Https://www.javazhiyin.com/category/springcloud
What is the ribbon?
The Ribbon is a set of client load balancing tools implemented based on the Netflix ribbon.
To put it simply, the ribbon is an open-source project by Netflix that provides a client-side software load-balancing algorithm that connects Netflix's middle-tier services. The Ribbon client component provides a complete set of configuration items such as connection timeouts, retries, and so on.
Simply put, all the machines behind load Balancer (lb) are listed in the configuration file, and the Ribbon automatically helps you to connect the machines based on certain rules (such as simple polling, random connections, etc.). It is also easy to implement a custom load balancing algorithm using the Ribbon.
What can the Ribbon do?
LB, or Load balancer (load Balance), is an application that is often used in microservices or distributed clusters.
Load balancing simply means that the user's request is distributed evenly across multiple services to achieve the ha of the system.
Common load balancer has software Nginx,lvs, hardware F5 and so on.
The corresponding load balancing is provided in the middleware, for example: Dubbo and Springcloud, and the Springcloud load balancing algorithm can be customized.
Centralized lb:
The use of a separate lb facility between the consumer and provider of the service (which can be hardware, such as F5, or software, such as Nginx), by which the facility is responsible for forwarding access requests through a policy to the provider of the service.
In-process lb:
Integrating the LB logic into the consumer, the consumer learns from the service registry which addresses are available and then chooses a suitable server from those addresses themselves.
The ribbon belongs to the in-process lb, which is just a class library, integrated in the consumer process, through which the consumer obtains the address of the service provider.
Information about the Ribbon
https://github.com/Netflix/ribbon/wiki/Getting-Started
Initial configuration of the Ribbon
1. Modify the MICROSERVICECLOUD-CONSUMER-DEPT-80 project
1). Modify the Pom file to add the following content
<!--ribbon related--><dependency><groupid>org.springframework.cloud</groupid><artifactid >spring-cloud-starter-eureka</artifactId></dependency><dependency><groupId> org.springframework.cloud</groupid><artifactid>spring-cloud-starter-ribbon</artifactid></ Dependency><dependency><groupid>org.springframework.cloud</groupid><artifactid> Spring-cloud-starter-config</artifactid></dependency>
2. Modify the service registration address of APPLICATION.YML append Eureka
2). Modify the Application.yml resource file to add the following:
Eureka:client: register-with-eureka:false service-url: defaultzone:http://eureka7001.com:7001/ eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
3. New annotations to the Configbean class @loadbalanced the configuration to join the Ribbon when the rest is obtained.
3). Modify the Configbean class to add the following:
// require clients to have load balancing when accessing microservices through rest Public resttemplate getresttemplate () {returnnew resttemplate ();}
4. Main startup class Deptconsumer80_app add @enableeurekaclient annotations.
4). Modify the main startup class Deptconsumer80_app to add the following:
@SpringBootApplication @enableeurekaclient Public class Deptconsumer80_app {public static void main (string[] args) {Springapplication.run (deptconsumer80_app.class, args);}}
5. Modify the Deptcontroller_consumer client Access class.
5). Modify the Deptcontroller_consumer to add the following:
/private static final String Rest_url_prefix = "http://localhost:8001";//from Eureka above there is a name Microservicecloud-dept micro service, Micro services accessed by name private static final String Rest_url_prefix = "Http://MICROSERVICECLOUD-DEPT";
6. Test:
1). Start with 3 Eureka clusters, i.e. microservicecloud-eureka-7001,microservicecloud-eureka-7002 and microservicecloud-eureka-7003.
2). Restart microservicecloud-provider-dept-8001 and register into Eureka.
3). Start microservicecloud-consumer-dept-80 again.
Input to Browser: HTTP://LOCALHOST/CONSUMER/DEPT/GET/1 for testing
Input to Browser: Http://localhost/consumer/dept/list for testing
Input to Browser: http://localhost/consumer/dept/add?dname= Big Data Department for testing
Check out our MySQL database to see if the big Data department is added:
Add success:
Summary: After the Ribbon and Eureka are integrated, consumer can invoke the service directly without caring for the address and port number.
Ribbon load Balancing
Ribbon Load Balancer Architecture diagram:
The ribbon is divided into two steps at work
The first step is to select Eurekaserver, which prioritizes servers with less load within the same region.
The second step then selects an address in the list of service registrations from the server, based on the user-specified policy.
The Ribbon provides a variety of strategies, such as polling, randomization, and weighting based on response time.
1. Create a maven Module for microservicecloud-provider-dept-8002 under the total parent project
1). Then refer to the microservicecloud-provider-dept-8001 pom file for a copy of the configuration in the Pom file to the microservicecloud-provider-dept-8002 Pom file.
2. Create the microservicecloud-provider-dept-8003 maven Module again under the total parent project
1). Then refer to the microservicecloud-provider-dept-8001 pom file for a copy of the configuration in the Pom file to the microservicecloud-provider-dept-8003 Pom file.
3. Copy the Java source of microservicecloud-provider-dept-8001 two copies to microservicecloud-provider-dept-8002 and Microservicecloud-provider-dept-8 respectively. 003, and modify the main startup class name separately
After the successful modification:
4. Then copy the two configuration files in the Resources folder under the MICROSERVICECLOUD-PROVIDER-DEPT-8001 project to microservicecloud-provider-dept-8002 and MICROSERVICEC loud-provider-dept-8003
As follows:
We then modified the ports in the Application.yml file for microservicecloud-provider-dept-8002 and microservicecloud-provider-dept-8003, respectively, to 8002 and 8003 ports.
5. Create a new two database to connect and use the two projects of microservicecloud-provider-dept-8002 and microservicecloud-provider-dept-8003
Note: Create the CLOUDDB02 database and execute the following SQL statement
DROP DATABASE IF EXISTS cloudDB02; CREATE DATABASE cloudDB02 CHARACTER SET UTF8; Use cloudDB02; CREATE TABLE Dept (deptno BIGINT not NULL PRIMARY KEY auto_increment,dname varchar, db_source varchar (60)); INSERT INTO Dept (Dname,db_source) VALUES (' Development Department ', Database ()), insert INTO dept (Dname,db_source) VALUES (' HR ', database () INSERT INTO Dept (Dname,db_source) VALUES (' Finance Department ', Database ()), insert INTO dept (Dname,db_source) VALUES (' Marketing ', database ()); INSERT into dept (Dname,db_source) VALUES (' Operations ', DATABASE ()); SELECT * FROM Dept;
Then create a database named CloudDB03 and execute the following SQL statement.
DROP DATABASE IF EXISTS cloudDB03; CREATE DATABASE cloudDB03 CHARACTER SET UTF8; Use cloudDB03; CREATE TABLE Dept (deptno BIGINT not NULL PRIMARY KEY auto_increment,dname varchar, db_source varchar (60)); INSERT INTO Dept (Dname,db_source) VALUES (' Development Department ', Database ()), insert INTO dept (Dname,db_source) VALUES (' HR ', database () INSERT INTO Dept (Dname,db_source) VALUES (' Finance Department ', Database ()), insert INTO dept (Dname,db_source) VALUES (' Marketing ', database ()); INSERT into dept (Dname,db_source) VALUES (' Operations ', DATABASE ()); SELECT * FROM Dept;
And then change the microservicecloud-provider-dept-8002 and microservicecloud-provider-dept-8003 the database name under the URL of the Application.yml file for both projects.
MICROSERVICECLOUD-PROVIDER-DEPT-8002 Engineering Even cloudDB02,
MICROSERVICECLOUD-PROVIDER-DEPT-8003 Engineering even cloudDB03.
Well, we've done so much configuration and modification, now to go into testing our load Balancer!!!!
Steps to test:
1. Start 3 Eureka cluster configurations (MICROSERVICECLOUD-EUREKA-7001 series)
2. Launch 3 Dept Micro Services and test pass (MICROSERVICECLOUD-PROVIDER-DEPT-8001 series)
Launch 3 Dept Micro-Service successfully test first
1). Enter the first URL in the browser first: Http://localhost:8001/dept/list to test
2). Then enter a second URL from the browser: http://localhost:8002/dept/list to test
3). Then enter a third URL from the browser: http://localhost:8003/dept/list to test
If three URLs have successfully appeared JSON string, and db_source data are different, then the success!!!
3. Start microservicecloud-consumer-dept-80
After successful startup, in Browser input: http://localhost/consumer/dept/list
Can reflect the effect of load balancing.
Load balancing After successful startup: This is the result of the first visit,
We'll refresh the page on the Http://localhost/consumer/dept/list page and we'll see that CLOUDDB03 will become a clouddb02 and then the refresh will become CLOUDDB01. In turn, this pattern uses a polling algorithm, which is not demonstrated here.
Note: Notice that the database names returned are different, and load balancing is implemented
Then open the http://eureka7001.com:7001/and you can see three instances hanging under a micro service
Summary: The ribbon is actually a soft-load-balanced client component that can be used in conjunction with other client-requested clients, and Eureka is just one example.
Irule of ribbon core components
Select a service to access from the list of services according to the specific algorithm.
The Springcloud combines the ribbon, which comes with 7 algorithms from the factory by default.
The first type is: Roundrobinrule polling
The second type is: Randomrule random
The third is: Availabilityfilteringrule will first filter out due to multiple access failures in the circuit breaker trip status of the service,
There are also services with concurrent connections exceeding the threshold, and then access to the remaining list of services according to the polling policy.
The fourth is: Weightedresponsetimerule calculates the weight of all services based on the average response time, and the faster the response time, the higher the probability that the service weight is selected. If statistics are insufficient at startup, use the Roundrobinrule policy, and statistics are sufficient.
Will switch to Weightedresponsetimerule.
The fifth type is: Retryrule first to follow the Roundrobinrule policy to obtain services, if the failure to obtain a service will be retried within a specified time, to obtain the available services.
The sixth is: Bestavailablerule will first filter out due to multiple access failures in the circuit breaker trip status of the service, and then select a minimum number of concurrent services.
The seventh is: Zoneavoidancerule The default rule, compound to determine the performance of the server area and server availability.
So for now, we have implemented the first algorithm Roundrobinrule polling method.
Then let's do the implementation of the second stochastic algorithm.
A method of making a stochastic algorithm under the Configbean class of MICROSERVICECLOUD-CONSUMER-DEPT-80 Engineering
@Beanpublic IRule Myrule () {//replaces the default polling algorithm with a re-selected random algorithm. return new Randomrule ();}
Let's test it out:
1. Start 3 Eureka cluster configurations (MICROSERVICECLOUD-EUREKA-7001 series).
2. Start 3 dept microservices and test through each (MICROSERVICECLOUD-PROVIDER-DEPT-8001 series).
3. Start the MICROSERVICECLOUD-CONSUMER-DEPT-80 project for a random algorithm test.
Please input in browser: http://localhost/consumer/dept/list
Random effect I can not, because with the random algorithm, the random effect of the embodiment of you will be able to understand.
So some other algorithms, I don't show them all.
Ribbon customization Algorithm
If the above 7 algorithms are not enough to come out of the business logic, then you can customize the algorithm.
1. Modify the main startup class of the microservicecloud-consumer-dept-80
1). Add an annotation to the main startup class @ribbonclient ()
/* When you start the microservices, you can load our custom Ribbon configuration class so that the configuration takes effect.
and the official documentation gives a clear warning:
This custom configuration class cannot be placed under the current package scanned by @componentscan and under the sub-package.
Otherwise our custom configuration class will be shared by all Ribbon clients, which means
We cannot achieve the purpose of specialized customization. */
Then the solution is to re-create a package name under the Java package and put the Myselfrule class in the package.
@RibbonClient (name="microservicecloud-dept", Configuration=myselfrule.class)
Take a look at the following:
To write Myselfrule custom configuration classes:
@Configurationpublic class myselfrule{@Beanpublic IRule myrule () {return new Randomrule ();//ribbon default is poll, I am custom Random}}
Then test:
1. Start 3 Eureka cluster configurations (MICROSERVICECLOUD-EUREKA-7001 series).
2. Start 3 dept microservices and test through each (MICROSERVICECLOUD-PROVIDER-DEPT-8001 series).
3. Start the MICROSERVICECLOUD-CONSUMER-DEPT-80 project for a random algorithm test.
Please input in browser: HTTP://LOCALHOST/CONSUMER/DEPT/GET/1
The effect of the test is not, because the use of a custom random algorithm, the implementation of the random effect you can understand.
Custom Rule Depth Resolution
Requirements: The policy is still polled, but with the new requirements, each server requires 5 calls. That is, once each machine once, now is each machine 5 times.
Requirement Code implementation: Add the following to the Myrule method in the Myselfrule class:
@Configurationpublic class Myselfrule {@Beanpublic IRule myrule () {//return new Randomrule ();//ribbon default is polling, Custom is random return new Randomrule ();}
Then create a RANDOMRULE_HHF class under the Myrule package, and add the following:
Parse Source: https://github.com/Netflix/ribbon/blob/master/ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/ Randomrule.java
Import Com.netflix.client.config.IClientConfig;
Import Com.netflix.loadbalancer.AbstractLoadBalancerRule;
Import Com.netflix.loadbalancer.ILoadBalancer;
Import Com.netflix.loadbalancer.Server;
Import java.util.List;
Import Java.util.concurrent.ThreadLocalRandom;
The demand is 5 times, but the micro service only 8001,8002,8003 three machines
Public class RANDOMRULE_HHF extends abstractloadbalancerrule {
Total number of calls that are currently required to be called 5 times per set
Private int total = 0;
Machine number for the current service
Private int currentindex = 0;
Public Server Choose(iloadbalancer lb, Object key) {
Iloadbalancer which load-balancing algorithm returns null if it is equal to NULL, it is natural that it will load an algorithm, so it will not become null.
if (lb = = null) {
return null;
}
It is not yet known which algorithm responds to the server
Server server = null;
If the server equals null, then the thread is broken, and if it is interrupted, it returns null.
while (server = = null) {
if (thread.interrupted ()) {
return null;
}
Uplist means a machine that is now alive that can be supplied externally, and then the. Get () method is
int index = Rand.nextint (Servercount); So that's the number of random returns to the value of the first few
list<server> uplist = Lb.getreachableservers ();
list<server> alllist = Lb.getallservers ();
If Servercount currently has three, then it is not equal to 0, then is flase.
int servercount = Alllist.size ();
if (Servercount = = 0) {
/*
* No servers. End regardless of pass, because subsequent passes
* Only get more restrictive.
*/
return null;
}
This means that if Servercount has three, then index gets the array from subscript 0 and 1 and 2
int index = Rand.nextint (Servercount);
Server = Uplist.get (index);
When total < 5 was the first time
When the second total < 5
When the fifth time total < 5 (then the fifth time is not less than 5), then if (Total < 5) The code in this section will not be executed
if (Total < 5) {
So the first server is the number No. 0 machine.
So the second server is number No. 0.
Server = Uplist.get (currentindex);
The total count for the first time is plus one 1.
The second total count is plus one 1.
total++;
When the fifth time total < 5, go else.
}Else {
Then total equals 0.
Total = 0;
And Currentindex adds a 1.
currentindex++;
Then 1 is greater than or equal to Uplist.size (), now assume that there are three machines, then 1 is not equal to Uplist.size ()
So now is the number No. 0 machine to service 1th, and so on.
But if Currentindex is equal to subscript 3 and >= uplist.size (), but we follow the array subscript to calculate only//have 0 and 1 and 2 subscript, then when the currentindex equals subscript 3 This is more than the third one , then//currentindex equals 0 again. etc...
if (Currentindex >= uplist.size ())
{
Currentindex = 0;
}
}
If this server equals null, then the thread breaks for a while and the next round continues
if (server = = null) {
/*
* The should happen is if the server list were
* Somehow trimmed. This is a transient condition. Retry after
* Yielding.
*/
Thread.yield ();
Continue
}
If you're alive and well, go back to server.
if (server.isalive ()) {
return (server);
}
Shouldn ' t actually happen. But must is transient or a bug.
Server = null;
Thread.yield ();
}
Returns whether the response service is 8001 or 8002 or 8003
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) {
}
}
So after we've defined our custom algorithm, we'll go back to the Myselfrule class and add the RANDOMRULE_HHF class to test the custom algorithm.
Add the RANDOMRULE_HHF class to the Myselfrule class:
@Configuration
Public class Myselfrule {
@Bean
Public IRule myrule()
{
return new Randomrule ();//ribbon default is poll, custom is random
return new Randomrule ();
return new RANDOMRULE_HHF (); //Customize each machine 5 times
}
}
Enter the test:
1. Start 3 Eureka cluster configurations (MICROSERVICECLOUD-EUREKA-7001 series).
2. Start 3 dept microservices and test through each (MICROSERVICECLOUD-PROVIDER-DEPT-8001 series).
3. Start the MICROSERVICECLOUD-CONSUMER-DEPT-80 project to test the custom load balancing algorithm.
Please input in browser: HTTP://LOCALHOST/CONSUMER/DEPT/GET/1
Test the effect I can not, as long as the page refresh 5 times can see the effect!!
Springcloud Micro-Service Architecture third Chapter