1: What is Ribbon?
Ribbon is an open source project released by Netflix. Its main function is to provide client-side software load balancing algorithms to connect Netflix's middle-tier services together. The Ribbon client component provides a series of complete configuration items such as connection timeout, retry, etc. Simply put, it is to list all the machines behind Load Balancer (LB for short) in the configuration file. Ribbon will automatically help you connect these machines based on certain rules (such as simple polling, instant connection, etc.). We also have a very easy way to implement custom load balancing algorithms using Ribbon.
Two: LB scheme classification
Currently, the mainstream LB scheme can be divided into two categories: one is centralized LB, that is, use independent LB facilities (can be hardware, such as F5, or software, such as nginx) between the service consumer and the provider, and the facility is responsible for forwarding access requests to the service provider through a certain policy; the other is in-process LB, which integrates the LB logic into the consumer, and the consumer knows from the service registration center which addresses are available, and then selects a suitable server from these addresses themselves. Ribbon belongs to the latter. It is just a class library that is integrated into the consumer process. Through it, consumers obtain the address of the service provider.
Three: Ribbon's main components and workflow
Ribbon's core components (all of which are interface types) have the following:
ServerList
Used to get the address list. It can be either static (providing a fixed set of addresses) or dynamic (recurring query for address lists from the registry).
ServerListFilter
Only used when using dynamic ServerList, it is used to use certain policies in the original service list to consider some addresses.
IRule
Select a final service address as the LB result. Select policies include polling, weighting based on response time, circuit breaker (when Hystrix is available), etc.
When Ribbon works, it is preferred to use ServerList to obtain all available services lists, then use ServerListFilter to consider some of the addresses, and finally select a server in the remaining addresses through IRule as the final result.
Four: Introduction to the main load balancing strategies provided by Ribbon
1: Simple polling load balancing (RoundRobin)
The requests are scheduled in turn in a polled manner, that is, each schedule is executed i = (i + 1) mod n, and the i-th server is selected.
2: Random load balancing (Random)
Randomly select Server with UP status
3: WeightedResponseTime Load Balancing (WeightedResponseTime)
A weight is allocated according to the corresponding time. The longer the corresponding time, the smaller the weight, and the lower the possibility of being selected.
4: ZoneAvoidanceRule
Comprehensively determine the performance of the server area and the server availability selection server
Comparison of Ribbon's own load balancing strategies
| Strategy name | Policy Statement | Policy description | Implementation instructions |
| BestAvailableRule | public class BestAvailableRule extends ClientConfigEnabledRoundRobinRule | Select a server with the smallest concurrent request | Check the server one by one. If the server is tripped, ignore it. Select the server with the smallest ActiveRequestsCount |
| AvailabilityFilteringRule | public class AvailabilityFilteringRule extends PredicateBasedRule | Filter out those backend servers marked as circuit tripped because of the connection failure, and filter out those backend servers with high concurrency (active connections exceed the configured threshold) | Using an AvailabilityPredicate to include the logic of filtering servers is actually to check the running status of each server recorded in status |
| WeightedResponseTimeRule | public class WeightedResponseTimeRule extends RoundRobinRule | A weight is allocated according to the corresponding time. The longer the corresponding time, the smaller the weight, and the lower the possibility of being selected. | A background thread regularly reads the evaluation response time from status and calculates a weight for each server. Weight's calculation is also relatively simple. Responsetime minus the average response time of each server is the server's weight. When the status is just started and no statistics are formed, use the roubine policy to select the server. |
| RetryRule | public class RetryRule extends AbstractLoadBalancerRule | Retry the mechanism on the machine for the selected load balancing policy. | During a configuration period, when the server selection is unsuccessful, you keep trying to select an available server using subRule |
| RoundRobinRule | public class RoundRobinRule extends AbstractLoadBalancerRule | RoundRobin method polling to select server | Poll index and select the server corresponding to index |
| RandomRule | public class RandomRule extends AbstractLoadBalancerRule | Randomly select a server | Randomly on index, select the server corresponding to index position |
| ZoneAvoidanceRule | public class ZoneAvoidanceRule extends PredicateBasedRule | Comprehensively determine the performance of the server area and the server availability selection server | Use ZoneAvoidancePredicate and AvailabilityPredicate to determine whether a server is selected. The previous one determines whether the operating performance of a zone is available. Exclude unavailable zones (all servers). AvailabilityPredicate is used to filter out servers with too many connections. |
5: Ribbon alone
Create a maven project name ribbon_client
pom content
<dependencies> <dependency> <groupId>com.netflix.ribbon</groupId> <artifactId>ribbon-core</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>com.netflix.ribbon</groupId> <artifactId>ribbon-httpclient</artifactId> <version>2.2.0</version> </dependency> </dependencies>
sample-client.properties configuration file
# Max number of retries sample-client.ribbon.MaxAutoRetries=1# Max number of next servers to retry (excluding the first server) sample-client.ribbon.MaxAutoRetriesNextServer=1# Whether all operations can be retried for this client sample-client.ribbon.OkToRetryOnAllOperations=true # Interval to refresh the server list from the source sample-client.ribbon.ServerListRefreshInterval=2000# Connect timeout used by Apache HttpClient sample-client.ribbon.ConnectTimeout=3000# Read timeout used by Apache HttpClient sample-client.ribbon.ReadTimeout=3000# Initial list of servers, can be changed via Archaius dynamic property at runtime sample-client.ribbon.listOfServers=www.sohu.com:80,www.163.com:80,www.sina.com.cn:80sample-client.ribbon.EnablePrimeConnections=true
RibbonMain Code
import java.net.URI;import com.netflix.client.ClientFactory;import com.netflix.client.http.HttpRequest;import com.netflix.client.http.HttpResponse;import com.netflix.config.ConfigurationManager;import com.netflix.loadbalancer.ZoneAwareLoadBalancer;import com.netflix.niws.client.http.RestClient;public class RibbonMain { public static void main( String[] args ) throws Exception { ConfigurationManager.loadPropertiesFromResources("sample-client.properties"); System.out.println(ConfigurationManager.getConfigInstance().getProperty("sample-client.ribbon.listOfServers")); RestClient client = (RestClient)ClientFactory.getNamedClient("sample-client"); HttpRequest request = HttpRequest.newBuilder().uri(new URI("/")).build(); for(int i = 0; i < 4; i ++) { HttpResponse response = client.executeWithLoadBalancer(request); System.out.println("Status for URI:" + response.getRequestedURI() + " is :" + response.getStatus()); } ZoneAwareLoadBalancer lb = (ZoneAwareLoadBalancer) client.getLoadBalancer(); System.out.println(lb.getLoadBalancerStats()); ConfigurationManager.getConfigInstance().setProperty("sample-client.ribbon.listOfServers", "ccblog.cn:80,www.linkedin.com:80"); System.out.println("changing servers..."); Thread.sleep(3000); for(int i = 0; i < 3; i ++) { HttpResponse response = client.executeWithLoadBalancer(request); System.out.println("Status for URI:" + response.getRequestedURI() + " is :" + response.getStatus()); } System.out.println(lb.getLoadBalancerStats()); } }Code parsing
Use Archaius ConfigurationManager to load properties;
Use ClientFactory to create clients and load balancers;
Use builder to build http requests. Note that we only support the path of the "/" part of the URI. Once the server is selected by the load balancer, the client will calculate the complete URI;
Calling API client.executeWithLoadBalancer() is not the exeucte() API;
Dynamically correct the server pool in the configuration;
Wait for the server list to refresh (the refresh interval defined in the configuration file is 3 seconds);
Print out the server statistics recorded by the load balancer.
Six: Ribbon combined with eureka
First, start the eureka_register_service project (registration center) and biz-service-0 project (service producer)
Create a maven project eureka_ribbon_client This project starts and related configurations depend on eureka_register_service and biz-service-0
pom join
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --></parent><dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency></dependencies><dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Brixton.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement>
In the application main class, add discovery service capabilities through the @EnableDiscoveryClient annotation. Create a RestTemplate instance and enable balancing load capacity through the @LoadBalanced annotation.
@SpringBootApplication@EnableDiscoveryClientpublic class RibbonApplication { @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(RibbonApplication.class, args); }}Create a ConsumerController to consume the getuser service of biz-service-0. Calling the service by directly RestTemplate
@RestControllerpublic class ConsumerController { @Autowired RestTemplate restTemplate; @RequestMapping(value = "/getuserinfo", method = RequestMethod.GET) public String add() { return restTemplate.getForEntity("http://biz-service-0/getuser", String.class).getBody(); }} Configure eureka service registration center in application.properties
spring.application.name=ribbon-consumerserver.port=8003eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
After completion, you can open http://localhost:8003/getuserinfo to see the results
Summary: Ribbon is actually a soft load balancing client component. It can be used in combination with other required requests. Combining it with eureka is just an example of it.
Code address: https://github.com/zhp8341/SpringCloudDemo
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.