Ribbon(二)负载均衡和重试

本文详细介绍了如何使用Ribbon进行负载均衡和重试操作。在Eureka环境中,Ribbon通过获取服务清单实现负载均衡。配置包括@LoadBalanced注解的RestTemplate,以服务ID替换具体路径。在重试部分,文章阐述了重试作为容错机制的作用,详细讲解了如何配置重试次数、超时时间,并通过模拟延迟测试重试功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇文章中,重点说明了Ribbon中封装了RestTempalte,是通过Rest api进行远程调用。这篇文章则会使用Ribbon进行负载均衡和重试的操作。

现在使item-service服务分别使用8001和8002启动,搭建集群

一、负载均衡

由于在Eureka中已经包含了Ribbon的相关依赖,所以配置了Eureka实际上已经可以进行Ribbon的负载均衡。

原理解释

其中的原理是:

Ribbon会从Eureka服务器上获取所有服务主机的清单,从而进行负载均衡操作。

配置说明

1、添加ribbon依赖(可选)

Eureka中默认包含了Ribbon的依赖

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

2、RestTemplate添加@LoadBalanced

@LoadBalanced 负载均衡注解,会对 RestTemplate 实例进行封装,创建动态代理对象,并切入(AOP)负载均衡代码,把请求分发到集群中的服务器

package cn.tedu.sp06;

...

@EnableDiscoveryClient //都是能够让注册中心能够发现,扫描到该服务
@SpringBootApplication
public class Sp06RibbonApplication {

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

    //创建 RestTemplate 实例,并存入 spring 容器
    @LoadBalanced
    //@LoadBalanced 负载均衡注解,会对 RestTemplate 实例进行封装,创建动态代理对象,并切入(AOP)负载均衡代码,把请求分发到集群中的服务器
    @Bean
    public RestTemplate restTemplate() {
        SimpleClientHttpRequestFactory f = new SimpleClientHttpRequestFactory();

        return new RestTemplate();
    }
}

3、访问路径修改为服务id

将RibbonController中每个方法中getForObject或postForObject发送的具体路径修改为服务的id,ribbon会实现负载均衡

package cn.tedu.sp06.controller;

...

@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);
	}

	//
	
	@GetMapping("/user-service/{userId}")
	public JsonResult<User> getUser(@PathVariable Integer userId) {
		return rt.getForObject("http://user-service/{1}", JsonResult.class, userId);
	}

	@GetMapping("/user-service/{userId}/score") 
	public JsonResult addScore(
			@PathVariable Integer userId, Integer score) {
		return rt.getForObject("http://user-service/{1}/score?score={2}", JsonResult.class, userId, score);
	}
	
	//
	
	@GetMapping("/order-service/{orderId}")
	public JsonResult<Order> getOrder(@PathVariable String orderId) {
		return rt.getForObject("http://order-service/{1}", JsonResult.class, orderId);
	}

	@GetMapping("/order-service")
	public JsonResult addOrder() {
		return rt.getForObject("http://order-service/", JsonResult.class);
	}
}

4、测试负载均衡

访问

http://localhost:3001/item-service/34

多次访问此路径,会发现访问到不同的服务器

 

 

二、重试

简介

重试是一种容错机制,如果请求后台服务出错,或者服务器故障,会向另一台服务器重试访问。

配置说明

1、pom文件添加retry依赖

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

2、yml配置ribbon重试

ribbon:
  #单台服务器的重试次数
  MaxAutoRetries: 1
  #更换服务器次数
  MaxAutoRetriesNextServer: 2
  OkToRetryOnAllOperations: true
  #OkToRetryOnAllOperations 是否对所有类型请求都重试,默认只对GET重试
  #ConnectTimeout 建立连接等待超时时间(不能再yml中配置,需要些Java代码进行配置)
  #ReadTimeout 连接已建立并已发送请求,等待接收响应的超时时间(不能再yml中配置,需要些Java代码进行配置)

其中

  • ribbon.MaxAutoRetries=1

表示单台服务器重试一次

  • ribbon.AutoRetriesNextServer=2

表示更换服务器的次数为两次

  • ribbon.OkToRetryOnAllOperations=true

表示对所有类型的请求都进行重试,默认只对GET请求重试

另外在ribbon中

ConnectTimeoutReadTimeout是需要Java去配置的

ConnectTimeout表示建立来等待超时时间

ReadTimeout表示连接已建立并已发送请求,等待接收响应的超时时间

3、主程序中RestTemplate的超时设置

其中,需要创建一个SimpleClientHttpRequestFactory的实例对象,并分别使用setReadTimeout()和setConnectTimeout()的方法设置超时时间为1s

package cn.tedu.sp06;

...

@EnableDiscoveryClient //都是能够让注册中心能够发现,扫描到改服务
@SpringBootApplication
public class Sp06RibbonApplication {

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

    //创建 RestTemplate 实例,并存入 spring 容器
    @LoadBalanced
    //@LoadBalanced 负载均衡注解,会对 RestTemplate 实例进行封装,创建动态代理对象,并切入(AOP)负载均衡代码,把请求分发到集群中的服务器
    @Bean
    public RestTemplate restTemplate() {
        SimpleClientHttpRequestFactory f = new SimpleClientHttpRequestFactory();
        //设置超时时间1s
        //连接已建立并发送请求,等待响应结果的超时时间
        f.setReadTimeout(1000);
        //建立连接等待超时时间为1s
        f.setConnectTimeout(1000);
        return new RestTemplate(f);


        //RestTemplate 中默认的 Factory 实例中,两个超时属性默认是 -1,
        //未启用超时,也不会触发重试
        //return new RestTemplate();
    }
}

4、模拟延迟

在item-service服务中通过Tread.sleep()的方式设置延迟,再通过random产生随机数的方法概率差生延迟,测试超时。如果超时,则会将访问请求到另外一个服务器上。

模拟随机延迟代码

        ///--设置随机延迟
		if(Math.random()<0.6) { 
			long t = new Random().nextInt(5000);
			log.info("item-service-"+port+" - 暂停 "+t);
			Thread.sleep(t);
		}

测试发送

http://localhost:3001/item-service/30

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值