工做中的微服务架构,某个服务一般会被多个服务调用或者多层调用完成需求,若是某个服务不可用,致使一个系统功能不可用或者服务直接没用了的状况,这种状况称为雪崩效应html
有A服务调用B服务,B服务调用C服务,若是B服务调用C服务出了问题,那么B服务会一直重试,等待会将资源耗尽,结果B服务也不可用,致使A服务调用B服务的时候,也出问题,这样的话,ABC服务都瘫了java
为预防以上问题,在下面学习Spring Cloud Hystrix,防雪崩,容错机制,基于NetFlix的Hystrixspring
Hystrix翻译中文是豪猪的意思,没见过也知道防护力很高的样子,还有以前学习的Eureka翻译中文的意思是找到了,就是后来词化成发现docker
Hystrix 供分布式系统使用,提供延迟和容错功能,隔离远程系统、访问和第三方程序库的访问设计模式
Spring Cloud Hystrix服务器
①服务降级网络
②服务熔断架构
③依赖隔离app
④监控(Hystrix Dashboard)maven
根据以上特性功能开始学习
这个功能其实咱们平时也都见过,好比访问某宝页面抢购,某奇艺看东西会提示: 网络开小差了,请稍后再试 等相似的提示
服务降级主导思想是区分业务,详细体如今优先核心服务,非核心服务不可用或放低其可用度,就有一种弃车保帅的意思,舍小保大
假设一个电商系统,某天的交易有巨大的流量出现,摆好的服务器资源就这么多,那么优先保证商品、订单、支付等服务的可用性,另外好比广告、积分等就属于非核心服务,那么就能够调度一下
细分到服务,好比商品服务,购买的时候,买家查询频繁度远高于卖家查询,那么就能够调度买家查询为核心服务,优先保证其可用性,另外买家查询服务就属于非核心服务,实际还须要根据业务场景调度
Hystrix的使用,经过@HystrixCommand注解,fallbackMethod回退函数实现降级逻辑
在以前的order服务和product服务进行学习,主要学习组件内容,按套路出牌
第一步maven加入Hystrix的依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
注意: 若是后面@DefaultProperties注解没法导入的话,在依赖上把版本号<version>加上
凡是遇到这样的问题,大多数缘由是官方把这个包名改过了,为了继续使用原来已经使用过的组件依赖,要求加上version指定版本,才能够
这边spring-cloud-starter-hystrix的名字在spring cloud 2.0.3发布的正式版中改为了spring-cloud-starter-netflix-hystrix
因此引入依赖,改为如下写法就能够了
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
第二步在启动类上,将以前的注解替换成@SpringCloudApplication,
该注解包含@SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker三个注解的效果
从这点你们就能够明白怎么整合注解功能的使用
@SpringCloudApplication @EnableFeignClients public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } }
第三步建立一个controller测试代码
/** * 测试 使用hystrix */ @RestController @DefaultProperties(defaultFallback = "defaultFallback") public class HystrixController { /** * HystrixCommandProperties 参数对应查看 * 下面超时配置 */ @HystrixCommand( commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000") } ) @GetMapping("/list") public String list() { RestTemplate restTemplate=new RestTemplate(); String s=restTemplate.postForObject("http://192.168.5.102:9001/product/list", Arrays.asList("1"),String.class); return s; } public String defaultFallback() { return "拼命加载中..."; } }
简单的测试降级,请求发送会触发defaultFallback的返回,相关配置信息也不用记,实在太长了,知道在哪里就能够了,若是不出现降级,能够去url请求的终端服务作点小手脚,好比thread.sleep(xxx)
依赖隔离就想到以前学习的docker,也具备隔离特性,docker实现进程的隔离,使容器以前互不影响,回来Hystrix,他使用的是线程池隔离方式,Hystrix会为每个hystrixcommand建立独立的线程池,你就像上面测试的某一个依赖服务,并不会拖慢影响其余的服务,Hystrix自动实现依赖隔离
微服务分布式容错机制必需要考虑,到目前知道的方式主要两种,
①重试机制: 对应预期短暂的故障问题
②断路器模式: 对应更长时间的故障问题,该模式是将受保护的服务封装在一个能够监控故障的断路器对象中,当该服务的故障达到阀值,断路器就会采起措施,跳闸断路,断路器对象被采起返回错误的方式告之
martin fowler发的一篇文章,关于CircuitBreaker(断路器),
URL: https://martinfowler.com/bliki/CircuitBreaker.html
拿其中的执行状态机制图,作一个翻译学习
以上解释到断路器设计模式---状态机制,能够看出有三种状态closed、open、half open, 顾名思义,以熔断路为主角
closed: 熔断器关闭状态,调用失败次数累计达到阀值,就会启动熔断机制
open/half open: 熔断器打开状态,此时对服务都直接返回错误,该处设计时钟概念,到了点就会进入half open状态,运行一些服务请求,若是请求是成功的,就认为服务恢复了,关闭熔断器closed,不然就继续fail回到open状态
代码中注解配置写法相似超时设置,主要参数以及说明 以下:
/** * HystrixCommandProperties 参数对应查看 * @return */ @HystrixCommand( commandProperties = { //超时设置 @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000"), //设置熔断 @HystrixProperty(name = "circuitBreaker.enabled",value = "true"), //设置滚动窗口中,断路器的最小请求数量 @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"), //断路器肯定是否须要打开统计请求和错误数据的时候,具备一个时间范围即时间窗口,当断路器打开, //对主逻辑进行熔断以后,hystrix会启动休眠时间窗,此时降级逻辑会称为主逻辑,当休眠时间窗到期,断路 //器就进入half open状态 //尝试释放请求到原主逻辑上,就想以前描述的,成功则断路器闭合closed,失败则继续打开open,休眠时间 //窗将从新计时 //如下设置休眠时间窗为10000毫秒 @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), //设置断路器打开的百分比条件, //好比此处设置为60,在滚动窗口中发生了10次request,有7次发生了异常,超出设置值,则断路器就进入 //open状态,反之即closed @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60") } ) @GetMapping("/list") public String list() { ...... }
以上是粗略学习hystrix,因此配置都写在了注解上面,下面转化配置文件,以超时设置为例,上面服务中的方法名字是list,下面设置一个默认超时设置和一个针对list方法的超时设置,在方法上须要加上@HystrixCommand注释,该注解有一个commandKey参数,指定该方法的key使用断路器,若是不设置默认是方法的名字,此处没有其余方法,图方便就直接用名字
hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 2500 list: execution: isolation: thread: timeoutInMilliseconds: 2800
关于Hystrix还有控制面板能够观察调控的更清晰,还有结合Hystrix+feign等方面的使用,继续学习
-------------------------------------------------------------