"Ribbon Load Balancing, Retry"

Ribbon service

Ribbon 提供了负载均衡和重试功能, 它底层是使用 RestTemplate 进行 Rest api 调用


RestTemplate

RestTemplate is a Rest remote call tool provided by SpringBoot

Its common methods:

  • getForObject()-execute get request

  • postForObject()-execute post request

The previous system structure is that the browser directly accesses the background service

Insert picture description here

Later, we will demonstrate Spring Cloud remote invocation through a Demo project

Insert picture description here

After using RestTemplate, the load on the server is significantly reduced. SpringCloud's ribbon optimizes RestTemplate and the effect is improved several times.

接下来使用Ribbon来远程调用和负载均衡


ribbon load balancing and retry

Insert picture description here

Ribbon的底层包含RestTemplate远程调用工具


Ribbon load balancing

Steps:

  • New ribbon project
  • pom.xml add dependency
  • application.yml add configuration
  • Main program
  • controller
  • Start, and visit the test

1-Create project

创建项目是有两个依赖,如果使用eureka的话 加入eureka的依赖

Insert picture description here


2 - pom.xml

  • If there is a common module, such as common

  • Ribbon is already included in eureka dependencies

Add ribbon start-up dependency (optional)
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

3 - application.yml

Insert picture description here

spring:
  application:
    name: ribbon
    
server:
  port: 3001
  
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka

Insert picture description here


4-Main program

创建 RestTemplate 实例

RestTemplate is a tool class used to call other microservices. It encapsulates remote calling code and provides a set of template methods for remote calling, such as getForObject(), postForObject(), etc.
@EnableDiscoveryClient
@SpringBootApplication
public class Sp06RibbonApplication {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(Sp06RibbonApplication.class, args);
    }
    
    @LoadBalanced //负载均衡注解
    @Bean
    public RestTemplate restTemplate(){
    
    
        return new RestTemplate();
    }
}

RestTemplate 设置 @LoadBalanced

@LoadBalanced load balancing annotation will encapsulate the RestTemplate instance, create a dynamic proxy object, and cut into the (AOP) load balancing code to distribute the request to the servers in the cluster

Insert picture description here


5 - RibbonController

访问路径设置为服务id

@RestController
public class RibbonController {
    
    
	@Autowired
	private RestTemplate rt;
	
	@GetMapping("/item-service/{orderId}")
	public JsonResult<List<Item>> getItems(@PathVariable String orderId) {
    
    
	    //这里服务器路径用 service-id 代替,ribbon 会向服务的多台集群服务器分发请求
		return rt.getForObject("http://item-service/{1}", JsonResult.class, orderId);
	}

	@PostMapping("/item-service/decreaseNumber")
	public JsonResult decreaseNumber(@RequestBody List<Item> items) {
    
    
		return rt.postForObject("http://item-service/decreaseNumber", items, JsonResult.class);
	}

Insert picture description here
Insert picture description here


6-Access test

Start the ribbon server
Insert picture description here

访问测试,ribbon 会把请求分发到 8001 和 8002 两个服务端口上

Insert picture description here
Insert picture description here

Ribbon retry

What is retry?

Retry is an error mechanism, if 请求后台服务出错, or 服务器故障, you can retry access to another server

rely:

<dependency>
	<groupId>org.springframework.retry</groupId>
	<artifactId>spring-retry</artifactId>
</dependency>

Application.yml configure ribbon to retry:

Insert picture description here

spring:
  application:
    name: ribbon

server:
  port: 3001

eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka,http://eureka2:2002/eureka

ribbon:
  MaxAutoRetriesNextServer: 2
  MaxAutoRetries: 1
  OkToRetryOnAllOperations: true
MaxAutoRetriesNextServer-the number of times to replace the instance (2 times is enough)
MaxAutoRetries —— The number of retries for the current instance, if the attempt fails, the next instance will be replaced (1 time is enough)
OkToRetryOnAllOperations=true —— By default, only GET requests are retried, when set to true, all types of requests such as POST are retriedInsert picture description here

The main program sets the timeout of RestTemplate's request factory

@SpringBootApplication
@EnableDiscoveryClient
public class Sp06RibbonApplication {
    
    

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

    @LoadBalanced //负载均衡注解
    @Bean
    public RestTemplate restTemplate(){
    
    
        SimpleClientHttpRequestFactory f = new SimpleClientHttpRequestFactory();
        f.setConnectTimeout(1000);
        f.setReadTimeout(1000);
        return new RestTemplate();
    }

}

Insert picture description here

Use SimpleClientHttpRequestFactory API to set the timeout

setConnectTimeout(1000) —— link timeout 1000 milliseconds

setReadTimeout(1000) —— pause time 1000 milliseconds


Access, test the ribbon retry mechanism

In order to test, we add delay code to the ItemController of tem-service to test the retry mechanism of the ribbon (delete after the test is completed)

@Slf4j
@RestController
public class ItemController {
    
    
	@Autowired
	private ItemService itemService;
	
	@Value("${server.port}")
	private int port;
	
	@GetMapping("/{orderId}")
	public JsonResult<List<Item>> getItems(@PathVariable String orderId) throws Exception {
    
    
		log.info("server.port="+port+", orderId="+orderId);

        ///--设置随机延迟
		if(Math.random()<0.6) {
    
     
			long t = new Random().nextInt(5000);
			log.info("item-service-"+port+" - 暂停 "+t);
			Thread.sleep(t);
		}
		///~~
		
		List<Item> items = itemService.getItems(orderId);
		return JsonResult.ok(items).msg("port="+port);
	}

Insert picture description here

ribbon的重试机制,在 feign 和 zuul 中进一步进行了封装,后续可以使用feign或zuul的重试机制

Guess you like

Origin blog.csdn.net/weixin_45103228/article/details/114043046