Spring Cloud load balancing Ribbon implementation

Commonly used components in Spring Cloud components also include Ribbon to perform load balancing functions.

Table of contents

 

(1) Introduction

(2) Realization

1. Configure multiple servers

 2.Configure ribbon

(3) Comparison between Ribbon and Nginx


(1) Introduction

Spring Cloud Ribbon is a client-side load balancer that provides access control to a large number of HTTP and TCP clients.

Client load balancing means that when the browser sends a request to the background, the client will read the list of available service information registered to the server from Eureka Server , and then according to the set load balancing policy (if not set, the default will be used). Decide which server to send the request to.

(2) Realization

The project continues to be implemented based on the previous eureka project. The previous eureka project

Here, the web Controller class is added to the project to facilitate viewing results from the browser and postman tool.

1. Configure multiple servers

A Controller has been added to the SPRING-CLIENT-01 service:

package com.cloud.client.controller;

import com.cloud.client.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;

@RestController
@RequestMapping("/getInfo")
public class Controller {
    
    @Value("${server.port}")
    String port;

    @Value("${spring.application.name}")
    String serviceName;

    @RequestMapping("/show")
    public String getInfo(){
        return "I'm form service:"+serviceName+",port:"+port;
    }

    @RequestMapping(value = "no/{no}", method = RequestMethod.GET)
    public String getPolicyFileByPolicyNo(@PathVariable String no,HttpServletResponse httpServletResponse){

        try {
            String  result = "I'm form service:"+serviceName+",port:"+port;
            if (result == null){
                httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
                return null;
            } else
                return result;
        } catch (Exception e) {
            e.printStackTrace();
            httpServletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return e.getMessage();
        }
    }

    @RequestMapping("/port")
    public String findInfo(){
        return "I'm form service:"+serviceName+",port:"+port;
    }

}

Start eureka server, start SPRING-CLIENT-01, and then enter it on the web page or postman

http://localhost:10001/getInfo/show

got the answer:

Then check Single instance Only in the edit Configurations of IDEA, enter different port numbers for the configuration port of the SPRING-CLIENT-01 service, and start, you can start multiple different port numbers but the service names are all SPRING-CLIENT-01 of service.

 

I started the services with port numbers 10001 and 10002 respectively, and then you can see the service list in the configuration center.

 2.Configure ribbon

The next step is to configure the ribbon service.

Create a new module before the project. The creation method is the same as the eureka server and client before, except that the ribbon component is added when selecting components.

After generation, the corresponding pom.xml file also contains ribbon configuration.

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

 As for the content of the configuration file application.properties, because I configured mysql here, I have a local mysql configuration. If you do not select the jpa and mysql components, you don’t need this part.

server.port = 11000

eureka.client.serviceUrl.defaultZone= http://localhost:12345/eureka/
spring.application.name= SPRING-CLIENT-02

SPRING-CLIENT-01.ribbon.NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testmysql
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5

Ribbon's startup class RibbonserviceApplication:

package com.cloud.ribbonservice;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestOperations;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
public class RibbonserviceApplication {

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

    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    public IRule ribbonRule() {
        return new RandomRule();	//这里配置策略,和配置文件对应
    }

}

 I added a RibbonService and IRibbonService here

package com.cloud.ribbonservice.service;

public interface IRibbonService {
}
package com.cloud.ribbonservice.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

@Service
public class RibbonService implements IRibbonService {

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    LoadBalancerClient loadBalancerClient;

    public String port() {
        this.loadBalancerClient.choose("SPRING-CLIENT-01");
        String info = restTemplate.getForObject("http://SPRING-CLIENT-01/getInfo/port", String.class);
        return restTemplate.getForObject("http://SPRING-CLIENT-01/getInfo/port", String.class);
    }

}

Accessing other services in SpringCloud can be achieved through RestTemplate. 

RestTemplate has many ways to perform rest requests. For this, you can look at the specific interface of the RestTemplate class.

 Directly add the name of the corresponding microservice to the RestTemplate in Spring Cloud and then connect it to the Web interface of the corresponding Controller.

The corresponding Controller in the Ribbon service here is:

package com.cloud.ribbonservice.controller;

import com.cloud.ribbonservice.service.RibbonService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/getInfo")
public class Controller {

    @Autowired
    RibbonService ribbonService;

    private static final Logger logger = LoggerFactory.getLogger(Controller.class);


    @Value("${server.port}")
    String port;

    @Value("${spring.application.name}")
    String serviceName;

    @RequestMapping("/show")
    public String getInfo(){
        return "I'm form service:"+serviceName+",port:"+port;
    }

    @RequestMapping("/hellol")
    public String showInfol(){
        System.out.println("find port");
        logger.info("find port");
        return ribbonService.port();

    }


}

Then run and start RibbonserviceApplication. After starting, you can see that the corresponding Ribbon service is also registered in the eureka service center.

Then wait a moment (it should take a small amount of time to add the service registration to the Ribbon), enter in the browser or postman 

http://localhost:11000/getInfo/hellol

 Call RestTemplate in ribbon service

After swiping a few more times, you can see the result switching between port numbers 10001 and 10002, which is to achieve the effect of debt balance.

(3) Comparison between Ribbon and Nginx

It can be seen from the above results that Ribbon implements client load balancing, which can balance calling services on the client through a series of algorithms. Ribbon is more focused than Nginx on concurrency rather than request distribution. Ribbon works in two steps:

Step 1: Select Eureka Server, which gives priority to servers in the same Zone and with less load.

Step 2: According to the user-specified strategy, select an address from the service registration list obtained from the Server. Ribbon provides a variety of strategies, such as RoundRobinRule, RandomRule, etc.

The above source code github address:  Source code address

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/harryptter/article/details/88075239