Spring cloud ribbon load balancing service invocation practice

Posted by RyanSF07 on Tue, 04 Jan 2022 17:13:21 +0100

introduce

Spring Cloud Ribbon is a set of client-side load balancing tools based on Netflix Ribbon.

The main function is to provide the software load balancing algorithm and service call of the client. The Ribbon client component provides a series of complete configuration items, such as connection timeout, Retry, etc. Simply put, list all the machines behind the Load Balancer (LB) in the configuration file. The Ribbon will automatically help you connect these machines based on certain rules (such as simple polling, random connection, etc.). We can easily use Ribbon to implement a custom load balancing algorithm.

LB load balance

Simply put, the user's requests are evenly distributed to multiple services, so as to achieve the HA (high availability) of the system. Common load balancing include software Nginx, LVS, hardware F5, etc.

Ribbon vs Nginx

Nginx is server load balancing. All client requests will be handed over to nginx, and then nginx will forward the requests. That is, load balancing is realized by the server.

Ribbon local load balancing. When calling the micro service interface, it will obtain the registration information service list in the registry and cache it to the JVM local, so as to realize the RPC remote service call technology locally.

Centralized LB

That is, an independent LB facility (which can be hardware, such as F5, or software, such as nginx) is used between the service consumer and the service provider, and the facility is responsible for forwarding the access request to the service provider through some policy;

In process LB

Integrate LB logic into the consumer. The consumer knows which addresses are available from the service registry, and then selects an appropriate server from these addresses. Ribbon belongs to in-process lb, which is just a class library integrated into the consumer process, through which the consumer obtains the address of the service provider.

Actual combat steps

After we registered the two payment service modules into Eureka cluster in the previous article, this article modifies the order module to enable it to access the two payment service module interfaces in a load balanced manner.

1.RestTemplate configuration load balancing

@Configuration
public class ApplicationContextConfig
{
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate()
    {
        return new RestTemplate();
    }
}

2. Modify the transfer address

The previous address is dead. You can only access the 8001 payment service interface. Here you need to change it to the service name registered by the payment service in Eureka:

//public static final String PAYMENT_URL = "http://localhost:8001";

public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";

After modifying OrderController:

@RestController
@Slf4j
public class OrderController
{
    //public static final String PAYMENT_URL = "http://localhost:8001";

    public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";

    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/consumer/payment/create")
    public CommonResult<Payment> create(Payment payment)
    {
        return restTemplate.postForObject(PAYMENT_URL +"/payment/create",payment, CommonResult.class);
    }

    @GetMapping("/consumer/payment/get/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id") Long id)
    {
        return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
    }

    @GetMapping("/consumer/payment/getForEntity/{id}")
    public CommonResult<Payment> getPayment2(@PathVariable("id") Long id)
    {
        ResponseEntity<CommonResult> entity = restTemplate.getForEntity(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);

        if(entity.getStatusCode().is2xxSuccessful()){
            return entity.getBody();
        }else{
            return new CommonResult<>(444,"operation failed");
        }
    }
}

3. Test

Start 7001700280018002,80 modules in sequence:

To access the order module interface in the browser: http://localhost/consumer/payment/get/22

It is correct that the service ports in the multiple refresh return interface appear alternately in 8001 and 8002.

4. Improve actor information

Configure the instance ID S displayed in the Registration Center for 8001 and 8002 modules, modify their yml files respectively, and add the following configurations:

After modifying the configuration, restart and visit Eureka again to find that the instance ID has changed:

Load balancing algorithm replacement

As shown above, the Ribbon uses the polling algorithm by default.

So what if I want to change to something else? Look at the following:

1. Create a new rule

@Configuration
public class MyRule {
    @Bean(name = "rrRule")
    public IRule myRule()
    {
        return new RandomRule();//Defined as random
    }
}

2. Modify startup class

Add the following note:

@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration= MyRule.class)

It means using our custom random algorithm.

3. Test

Start the order service module and visit the following address several times: http://localhost/consumer/payment/get/22

It is found that ports 8001 and 8002 are returned irregularly.

Attention

After the integration of Ribbon and Eureka, consumers can directly call the service without caring about the address and port number, and the service also has load function.

  • Why is there no ribbon dependency configured in the order module pom?

Because the new spring cloud starter Netflix Eureka client comes with spring cloud starter ribbon dependency.

Topics: Load Balance ribbon