栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Ribbon(二)负载均衡和重试

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Ribbon(二)负载均衡和重试

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

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

一、负载均衡

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

原理解释

其中的原理是:

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

配置说明

1、添加ribbon依赖(可选)

Eureka中默认包含了Ribbon的依赖


	org.springframework.cloud
	spring-cloud-starter-netflix-ribbon

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> 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 items) {
		return rt.postForObject("http://item-service/decreaseNumber", items, JsonResult.class);
	}

	//
	
	@GetMapping("/user-service/{userId}")
	public JsonResult 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 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依赖

	org.springframework.retry
	spring-retry

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中

ConnectTimeout和ReadTimeout是需要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

 

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/845627.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号