SpringCloud-Hystrix熔断(Netflix)

1.介绍

Hystrix是由Netflix公司开源的一个延迟和容错库,它通过隔离远程系统、服务或者第三方库之间的访问,防止级联失败并提供回退选项,从而提升系统的可用性、容错性与局部应用的弹性。

在分布式系统下,微服务之间不可避免地会发生相互调用,但每个系统都无法百分之百保证自身运行不出问题。在服务调用中,很可能面临依赖服务失效的问题(网络延时,服务异常,负载过大无法及时响应)。因此需要一个组件,能提供强大的容错能力,为服务间调用提供保护和控制。
我们的目的:当我自身 依赖的服务不可用时,服务自身不会被拖垮。防止微服务级联异常
本质:就是隔离坏的服务,不让坏服务拖垮其他服务(调用坏服务的服务)。

2.功能介绍

2.1舱壁模式(资源隔离)

舱壁模式是一种隔离策略,隔离了每个工作负载或者说服务的关键资源,如连接池、内存、CPU和硬盘。每个工作单元都有独立的 连接池,内存,CPU。

  • 使用舱壁避免了单个服务消耗掉所有资源,从而导致其他服务出现故障的场景。这种模式主要是通过防止由一个服务引起的级联故障来增加系统的弹性。

举例:
当UserController的请求过多,可能PersonController服务就没办法进行处理,也就是不让一个资源影响到其他资源模块。
思路:
可以对每个请求设置,单独的连接池,配置连接数,不要影响 别的请求。

优点:

  1. 服务提供者高延迟或异常,不会影响到整个系统的失败。
  2. 能够控制每个调用者的并发度。因为有独立的线程池。

2.2雪崩效应

在这里插入图片描述

如果服务提供者响应非常缓慢,那么服务消费者调用此提供者就会一直等待,直到提供者响应或超时。在高并发场景下,此种情况,如果不做任何处理,就会导致服务消费者的资源耗竭甚至整个系统的崩溃。一层一层的崩溃,导致所有的系统崩溃

雪崩三个流程(不可用的范围 被逐步放大):

  • 服务提供者不可用:
  • 重试会导致网络流量加大,更影响服务提供者。
    导致服务调用者不可用,由于服务调用者 一直等待返回,一直占用系统资源。

服务不可用原因:

  • 服务器宕机
  • 网络故障
  • 宕机
  • 程序异常
  • 负载过大,导致服务提供者响应慢
  • 缓存击穿导致服务超负荷运行

2.3容错机制

容错性是一种特性,它使系统能够在某些组件发生错误时仍能继续正常地运行。

容错性一般包括:

  • 超时(Timeouts)
  • 重试(Retries)
  • 熔断机制(Circuit Breaker)
  • 截止时间(Deadlines)
  • 限流器(Rate limiters)

2.4断路器(熔断)

当请求某个服务有大量的超时(说明该服务不可用)。再次请求也没有意义的,只会消耗资源,微服务在高并发场景中,因为对服务请求时间过长,可能就会出现雪崩

  1. 断路器是对容易导致错误的操作的代理。这种代理能统计一段时间内的失败次数,并依据次数决定是正常请求依赖的服务还是直接返回。

  2. 断路器可以实现快速失败,如果它在一段时间内检测到许多类似的错误(超时),就会在之后的一段时间,强迫对该服务的调用快速失败,即不再请求所调用的服务。这样对于消费者就无须再浪费CPU去等待长时间的超时。

  3. 断路器也可自动诊断依赖的服务是否恢复正常。如果发现依赖的服务已经恢复正常,那么就会恢复请求该服务。通过重置时间来决定断路器的重新闭合。

    这样就实现了微服务的“自我修复”:当依赖的服务不可用时,打开断路器,让服务快速失败,从而防止雪崩。当依赖的服务恢复正常时,又恢复请求。

2.5降级

当前服务无法处理调用方法,向调用方法返回一个预期且可备选的响应方案。

2.6熔断vs降级

共同点:
1、为了防止系统崩溃,保证主要功能的可用性和可靠性。
2、用户体验到某些功能不能用。
不同点:
1、熔断由下级故障触发,主动惹祸。
2、降级由调用方从负荷角度触发,无辜被抛弃。

3.使用

3.1整合Resttemplate

服务调用方

	@HystrixCommand(fallbackMethod = "back")
	public String alive() {
		// 自动处理URL
		
		RestTemplate restTemplate = new RestTemplate();
		
		String url ="http://user-provider/User/alive";
		String object = restTemplate.getForObject(url, String.class);
		
		return object;
		
	}
	
	
	public String back() {
		
		return "请求失败~bbb...";
	}

启动类要配置

@EnableCircuitBreaker

3.2整合Feign

配置

feign.hystrix.enabled=true

接口

@FeignClient(name = "user-provider",fallback = AliveBack.class)
public interface ConsumerApi {

	@RequestMapping(value = "/User/alive",method = RequestMethod.GET)
	public String alive();
	
	@RequestMapping(value = "/User/getById",method = RequestMethod.GET)
	public String getById(Integer id);
}

实现

package com.mashibing.UserConsumer;

import java.util.Map;

import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
@Component
public class AliveBack implements ConsumerApi{

	@Override
	public String alive() {
		// TODO Auto-generated method stub
		return "aaa";
	}

	@Override
	public String getById(Integer id) {
		// TODO Auto-generated method stub
		return null;
	}

}

3.3使用fallbackFactory检查具体错误

实现类

@Component
public class WebError implements FallbackFactory<ConsumerApi> {

	@Override
	public ConsumerApi create(Throwable cause) {
		// TODO Auto-generated method stub
		return new ConsumerApi() {
			
			@Override
			public Person postPserson(Person person) {
				// TODO Auto-generated method stub
				return null;
			}
			
			@Override
			public String getById(Integer id) {
				// TODO Auto-generated method stub
				return null;
			}
			
			@Override
			public String alive() {
				// TODO Auto-generated method stub
				System.out.println(cause.getLocalizedMessage());
				cause.printStackTrace();
				return ToStringBuilder.reflectionToString(cause);
			}
			
			@Override
			public Map<Integer, String> postMap(Map<String, Object> map) {
				// TODO Auto-generated method stub
				return null;
			}
			
			@Override
			public Map<Integer, String> getMap3(Map<String, Object> map) {
				// TODO Auto-generated method stub
				return null;
			}
			
			@Override
			public Map<Integer, String> getMap2(Integer id, String name) {
				// TODO Auto-generated method stub
				return null;
			}
			
			@Override
			public Map<Integer, String> getMap(Integer id) {
				// TODO Auto-generated method stub
				return null;
			}
		};
	}

}

针对不同异常返回响应

			@Override
			public String alive() {
				// TODO Auto-generated method stub
				System.out.println(cause);
				if(cause instanceof InternalServerError) {
					System.out.println("InternalServerError");
					return "远程服务报错";
				}else if(cause instanceof RuntimeException) {
					
					return "请求时异常:" + cause;
				}else {
					return "都算不上";
				}
			}

3.4信号量隔离与线程隔离

默认情况下hystrix使用线程池控制请求隔离

线程池隔离技术,是用 Hystrix 自己的线程去执行调用;而信号量隔离技术,是直接让 tomcat 线程去调用依赖服务。信号量隔离,只是一道关卡,信号量有多少,就允许多少个 tomcat 线程通过它,然后去执行。

信号量隔离主要维护的是Tomcat的线程,不需要内部线程池,更加轻量级。

配置

hystrix.command.default.execution.isolation.strategy 隔离策略,默认是Thread, 可选Thread|Semaphore
thread 通过线程数量来限制并发请求数,可以提供额外的保护,但有一定的延迟。一般用于网络调用
semaphore 通过semaphore count来限制并发请求数,适用于无网络的高并发请求
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 命令执行超时时间,默认1000ms
hystrix.command.default.execution.timeout.enabled 执行是否启用超时,默认启用true
hystrix.command.default.execution.isolation.thread.interruptOnTimeout 发生超时是是否中断,默认true
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests 最大并发请求数,默认10,该参数当使用ExecutionIsolationStrategy.SEMAPHORE策略时才有效。如果达到最大并发请求数,请求会被拒绝。理论上选择semaphore size的原则和选择thread size一致,但选用semaphore时每次执行的单元要比较小且执行速度快(ms级别),否则的话应该用thread。
semaphore应该占整个容器(tomcat)的线程池的一小部分。

Feign下配置

hystrix.command.default.execution.isolation.strategy=SEMAPHORE

可视化界面
启动类

@EnableHystrixDashboard

引入依赖

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>
				spring-cloud-starter-netflix-hystrix-dashboard
			</artifactId>
		</dependency>
		<dependency>
		    <groupId>org.springframework.boot</groupId>
		    <artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>

健康上报

http://localhost:90/actuator/hystrix.stream

图形化

http://localhost:90/hystrix

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值