preface

There are several Ribbon load balancing solutions. This article introduces the Ribbon+RestTemplate solution. However, RestTemplate is not very convenient to use. In actual development, we usually use OpenFeign solution, so this article focuses on the configuration of the Ribbon, and RestTemplate is briefly introduced.

Load balancing

In order to improve service availability, we generally deploy a service to multiple servers to form multiple instances. The function of load balancing is to evenly distribute requests to each instance. Load balancing is generally divided into server load balancing and client load balancing. The server load balancing is implemented through hardware (such as F5) or software (such as Nginx). The Ribbon implements client load balancing. Server load balancing is to maintain a list of available services in hardware devices or software modules, and then clients send service requests to these load balancing devices, which forward the requests in a balanced manner according to some algorithms. In client load balancing, the client obtains the service list from the service registry (such as Eureka Server) and stores it locally. Then, the client accesses these services through the Ribbon algorithm.

Start the configuration

Configuring the service Provider

Here we configure two service providers. The service provider only needs to provide an HTTP interface and register with Eureke or another registry, as described in the SpringCloud Eureka tutorial

@RestController
public class Controller {

    @RequestMapping("/getUser")
    public String getUser(a) throws InterruptedException {
        // Returns the instance port number that distinguishes which instance the ribbon accesses
        return "8082"; }}Copy the code

Another service provider, note that thread sleep is turned on for 3 seconds to test the Ribbon’s timeout retry feature.

@RestController
public class Controller {

    @RequestMapping("/getUser")
    public String getUser(a) throws InterruptedException {
        System.out.println("getUser");
        TimeUnit.SECONDS.sleep(3);
        return "8084"; }}Copy the code

Service consumer configuration

Related,

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <! <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>Copy the code

The Service consumer usually only needs to register with Eureka or another registry and use the RestTemplate at the Controller or Service layer to access the Service provider’s interface with load-balancing capability.

Ribbon configuration

Injection RestTemplate

Put this code into a startup or configuration class

@Bean
@LoadBalanced
public RestTemplate restTemplate(a) {
    return new RestTemplate();
}
Copy the code

For example, put it in a startup class

@EnableEurekaClient
@SpringBootApplication
public class RibbonConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(RibbonConsumerApplication.class, args);
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(a) {
        return newRestTemplate(); }}Copy the code

If you do not configure this step, you cannot import the RestTemplate through @Autowrite.

Access the interface through RestTemplate

@RestController
public class Controller {
    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("/getUser")
    public String getUser(a) throws InterruptedException {
    	// Note that the service name is used here, not the specific address, port
        return restTemplate.getForObject("http://provider/getUser",String.class); }}Copy the code

The configuration file

  • Otherwise, the client or restClient function is enabled
# client/ restClient Select one of these Settings astrueRibbon: HTTP: client: enabled ribbon: HTTP: client: enabled ribbon: HTTP: enabled ribbon: HTTP: enabledtrue
  restclient:
    enabled: true
Copy the code
  • Open the retry
spring:
  cloud:
    loadbalancer:
      retry:
        enabled: true
Copy the code
  • The timeout period and retry times are specified
*** ribbon: # ribbon provider: # ribbon provider: # ribbon provider: # ribbon provider: # ribbon provider: # ribbon provider: # ribbon provider: # ribbon provider: # ribbon provider: # ribbon provider: # ribbon provider: # ribbon provider: # ribbon provider: # ribbon provider:100ReadTimeout:100# load balancing strategy, if use Ribbon to own, just change the name of the last paragraph, in front of the package name need not change NFLoadBalancerRuleClassName: Com.net flix. Loadbalancer. RandomRule # all request fails retry OkToRetryOnAllOperations:true# switch case retries MaxAutoRetriesNextServer:2MaxAutoRetries:2
Copy the code
  • ConnectTimeout is the timeout period for establishing a connection with the server. ReadTimeout is the timeout period for reading resources from the server after establishing a connection.
  • The difference between MaxAutoRetries and MaxAutoRetriesNextServer is that: After the request times out, retry is performed on the current instance. If the request still fails, the instance is switched and retry is performed. If the request still fails, an error is reported. So the total number of retries is equal to MaxAutoRetries+MaxAutoRetriesNextServer

The Ribbon provides load balancing policies

strategy named describe Implementation notes
RandomRule Random strategy Randomly select available servers Randomly select the server corresponding to index
RoundRobinRule Polling strategy Select servers in a sequential cycle Poll index and select the server corresponding to index
RetryRule Retry strategy Add a retry mechanism to the selected load balancing policy When the server selection fails during a configuration period, always try to use subRule to select an available server
BestAvailableRule Minimum concurrency strategy Select a server with the fewest concurrent requests Check each server one by one. If the circuit breaker of the server is on, ignore it and select another server with the lowest number of concurrent connections
AvailabilityFilteringRule Available filtering policies Filter out servers that consistently fail to connect and are marked circuit tipped, filter out servers that have high concurrent connections (active connections exceed the configured threshold) Use an AvailabilityPredicate to include the logic for filtering servers, which checks the running status of each server recorded in status
WeightedResponseTimeRule Response time weighting policy Assign weights based on the response time of the server. The longer the response time, the lower the weight, the lower the probability of being selected; The shorter the response time, the higher the weight, the higher the probability of being selected. This strategy is appropriate because it integrates various factors, such as network, disk, CPU, etc., that directly affect response time A background thread periodically reads the rating response time from status, calculating a weight for each server; The responseTime minus the average responsetime of each server is the weight of the server. When you start running and no status is formed, select the server using a polling strategy
ZoneAvoidanceRule Regional tradeoff strategy Select servers based on the performance and availability of servers in the region where the server resides, determine whether the operating performance of a Zone is available, and exclude all servers in the unavailable Zone Use ZoneAvoidancePredicate and AvailabilityPredicate to determine whether a server is selected, the former determines whether a zone’s operational performance is available, and excludes all servers in the zone that is not available, AvailabilityPredicate is used to filter out servers that have too many connections

The effect

Registration of Eureka

Accessing the consumer interface

The random strategy is used in this paper

  • Access instance 8082

  • Failed to access instance 8084. Procedure

The 8084 instance is asleep internally for 3 seconds, so it will time out and will display this error if the retry still fails.

  • Instance 8084 is accessed. Retry successful

Note in the request list, these two requests are successfully retried. The following requests are requests that access instance 8082 in about 20ms. The retry duration is about 900ms.