应对微服务调用时的雪崩效应

简介

本文是看b站视频的笔记,需要项目代码的话,可以此链接视频(https://www.bilibili.com/video/BV15K4y1h7Di?p=1)中边观看边搭建。

相关文章

https://zhuanlan.zhihu.com/p/69879180

什么是雪崩效应

微服务间彼此调用时,个别微服务阻塞,导致整个调用链阻塞,进而导致大量类似的请求资源阻塞,使得服务不可用。

应对方法

使用redis作为缓存
.pom依赖,spring-boot-starter-data-redis、commons-pool2依赖

.yml文件,配置spring.redis

自定义配置Redis,(写一个配置类)(重写redisTemplate序列化、cache序列化...)

添加注解

	在启动类上注解@EnableCaching
	
	在consumer调用方的调用serviceImpl类的方法上,打注解@Cacheable(cacheNames="orderService:product:single", key="#id")
请求合并
(一个比喻:安排一组人过安检,让 十个人/60s内的人 按照 一波/一批 的量来处理,按批过安检)

.pom添加依赖,spring-cloud-starter-netflix-hystrix依赖
	
添加注解 
	
	在启动类上注解@EnableCircuitBreaker(官网使用) 或者 @EnableHystrix
	
	在consumer调用方的调用serviceImpl类的方法上,(比如要合并byId方法,批量成byIds方法),
	
	在byId方法上加注解:
	@HystrixCollapser(
		batchMethod="byIds",//合并请求方法
		scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,//请求方式
		collapserProperties = {
			//间隔多久的请求会进行合并,默认10ms
			@HystrixProperty(name="timerDelayInMilliseconds", value="20")
			//批处理之前,批处理中允许的最大请求数
			@HystrixProperty(name="maxRequestsInBatch", value="200")
		}
	)
	
	在byIds方法上加注解:
	@HystrixCommand
服务隔离
线程池隔离
	
	多个接口,在一个线程池中 --> 把接口放在不同的线程池中
	请求线程和调用Provider线程不是同一条线程
	
线程池隔离实现
	
	添加注解,在ProductServiceImpl.java[远程调用者实现类]的方法上
	@HystrixCommand(
		groupKey = "order-productService-listPool", //服务名称
		threadPoolKey = "order-productService-listPool",//线程池名称
		commandKey = "selectProductList",//接口名称,默认为(注解下的)方法名
		threadPoolProperties = {
			//线程池大小
			@HystrixProperty(name="coreSize", value="6")
			//队列等待阈值(最大队列长度,默认-1)
			@HystrixProperty(name="maxQueueSize", value="100")
			//线程存活时间,默认 1min
			@HystrixProperty(name="keepAliveTimeMinutes", value="2")
			//超出队列等待阈值执行拒绝策略
			@HystrixProperty(name="queueSizeRejectionThreshold", value="100")
		}
		commandProperties = {
			//熔断多少秒后请求重试,默认5s
			@HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value="5000"),
		},
		//服务降级方法
		fallbackMethod = "selectProductByIdFallback"
	)
	
信号量隔离

	信号量总数有上限0,一个请求拿到信号量才能继续访问,请求完成归还信号量;没有信号量,则信号量获取失败,直接fallback;
	不支持超时,没有办法异步。
	请求线程和调用Provider线程是同一条线程
	
信号量隔离实现

	添加注解,在ProductServiceImpl.java[远程调用者实现类]的方法上
	@HystrixCommand(
		commandProperties = {
			//超时时间(远程调用者对被调用者的同步等待时间,超过这个时间就不等了),默认1000ms。
			@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="5000"),
			//信号量隔离,该策略默认值是THREAD,所以要手动配置
			@HystrixProperty(name="HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY", value="SEMAPHORE"),
			//信号量最大并发,调小一些方便模拟高并发
			@HystrixProperty(name="HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS", value="6"),
		},
		//服务降级方法
		fallbackMethod = "selectProductByIdFallback"
	)
	
简单对比 

			是否支持超时	是否支持熔断	隔离原理				是否是异步调用			资源消耗
线程池隔离	支持			支持 			每个服务单独用线程池	支持同步或异步				大
信号量隔离	不支持			支持			通过信号量的计数器		同步调用,不支持异步		小
服务熔断

参考图 (熔断,是一种牺牲局部保证全体的思想)在这里插入图片描述

//熔断开启状态:直接快速失败,五秒后尝试进入熔断关闭
//熔断关闭状态:获得前十秒的失败率,达到一定程度,进入熔断开启

.pom依赖 
	<!-- spring-cloud netflix hystrix 依赖 -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
	</dependency>
	
托底方法
	private Product selectProductByIdFallback(Integer id){retrun new Product();}

添加注解 

	在byId方法上加注解:
	@HystrixCommand(
		commandProperties = {
			//10s内请求数大于10个就启动熔断器,当请求符合熔断条件触发fallbackMethod,默认20个
			@HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD, value="10"),
			//(10s内)请求错误率大于50%就启动熔断器
			@HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value="50"),
			//熔断多少秒后请求重试,默认5s
			@HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value="5000"),
		},
		//服务降级方法
		fallbackMethod = "selectProductByIdFallback"
	)

//添加异常,视频p13 5.10
服务熔断[openfeign版本]
.pom文件,
	<!-- 如果使用openfeign,则默认集成了 hystrix 依赖,无需在此添加 -->

.yml文件,开启feign对hystrix支持(如果使用feign)
	feign.hystrix.enabled = true
	
写一个"服务熔断处理处理类" -- fallback.ProductServiceFallback.java
	//视频p15 5.00 ,实现接口ProductService<T>,T在这里就是ProductService
	添加@Component注解
	
写一个"捕获异常类", -- fallback.ProductServiceFallbackFactory.java
	//视频p16 0.23,实现接口FallbackFactory<T>
	添加@Component注解
	
	/** 用ProductServiceFallback替换上面的ProductServiceFallbackFactory */
	
添加注解
	@FeignClient(value="xxx", fallback=ProductServiceFallback.class) 或者
	@FeignClient(value="xxx", fallbackFactory=ProductServiceFallbackFactory.class)
服务降级
触发条件 
	方法抛出 非HystrixBadRequestException异常 时;
	方法调用超时;
	熔断器开启拦截;
	线程池/队列/信号量跑满了;

使用(已包含于"服务熔断"),
	@HystrixCommand(
		//服务降级方法
		fallbackMethod = "selectProductByIdFallback"

	方法抛出 非HystrixBadRequestException异常 时;
	方法调用超时;
	熔断器开启拦截;
	线程池/队列/信号量跑满了;

使用(已包含于"服务熔断"),
	@HystrixCommand(
		//服务降级方法
		fallbackMethod = "selectProductByIdFallback"
	)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值