转自:http://www.javashuo.com/article/p-nqbejqdw-gx.htmlhtml
服务熔断的做用相似于咱们家用的保险丝,当某服务出现不可用或响应超时的状况时,为了防止整个系统出现雪崩,暂时中止对该服务的调用。java
服务降级是从整个系统的负荷状况出发和考虑的,对某些负荷会比较高的状况,为了预防某些功能(业务场景)出现负荷过载或者响应慢的状况,在其内部暂时舍弃对一些非核心的接口和数据的请求,而直接返回一个提早准备好的fallback(退路)错误处理信息。这样,虽然提供的是一个有损的服务,但却保证了整个系统的稳定性和可用性。git
相同点:github
目标一致 都是从可用性和可靠性出发,为了防止系统崩溃;web
用户体验相似 最终都让用户体验到的是某些功能暂时不可用;spring
不一样点:api
触发缘由不一样 服务熔断通常是某个服务(下游服务)故障引发,而服务降级通常是从总体负荷考虑;app
管理目标的层次不太同样,熔断实际上是一个框架级的处理,每一个微服务都须要(无层级之分),而降级通常须要对业务有层级之分(好比降级通常是从最外围服务开始); 框架
Hystrix:英 [hɪst'rɪks] 美 [hɪst'rɪks] ,翻译过来是“豪猪”的意思。 在分布式环境中,不可避免地会出现某些依赖的服务发生故障的状况。Hystrix是这样的一个库,它经过添加允许时延和容错逻辑来帮助你控制这些分布式服务之间的交互。Hystrix经过隔离服务之间的访问点,阻止跨服务的级联故障,并提供了退路选项,全部这些均可以提升系统的总体弹性。分布式
Hystrix的设计目的:
经过第三方客户端的库来为访问依赖服务时的潜在故障提供保护和控制;
防止在复杂分布式系统中出现级联故障;
快速失败和迅速恢复;
在容许的状况下,提供退路对服务进行优雅降级;
提供近实时的监控、报警和操做控制;
接下来咱们将经过对《模拟RPC调用(Feign)》一章中的 message-center 项目进行改造,演示如何使用Hystrix,eureka服务注册中心以及message-service服务提供者无需更改。
在 pom.xml 文件中引入Hystrix依赖:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> </parent> <properties> <spring-cloud.version>Finchley.SR2</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Eureka-Client 依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- Feign 依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- Hystrix 依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <!-- SpringCloud 版本控制依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
在MessageCenterApplication启动类上增长@EnableCircuitBreaker注解:
@SpringBootApplication @EnableFeignClients @EnableCircuitBreaker public class MessageCenterApplication { public static void main(String[] args) { new SpringApplicationBuilder(MessageCenterApplication.class).web(WebApplicationType.SERVLET).run(args); } }
这里咱们在启动类中又增长了@EnableCircuitBreaker注解,用来开启断路器功能。若是你以为启动类上的注解个数有点多的话,可使用一个@SpringCloudApplication 注解来代替@SpringBootApplication(或者@EnableEurekaServer)、@EnableDiscoveryClient、@EnableCircuitBreaker这三个注解。
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker public @interface SpringCloudApplication { }
接下来,咱们为MessageCenterController中的getMsg()接口增长断路器功能,修改部分代码以下:
@GetMapping("/msg/get") @HystrixCommand(fallbackMethod = "getMsgFallback") public Object getMsg() { String msg = messageService.getMsg(); return msg; } public Object getMsgFallback() { return "祝您 2019 猪年大吉,'猪'事如意!"; }
先启动Eureka,再启动一个8771端口的message-service服务,最后启动message-center。待启动完成以后,Eureka注册中心实例注册信息以下:
此时,访问 http://localhost:8781/api/v1/center/msg/get ,返回以下结果代表服务调用成功:
而后,停掉message-service服务,再次请求 http://localhost:8781/api/v1/center/msg/get ,返回结果以下:
能够看出fallback中的信息被直接返回了,代表Hystrix断路器调用成功。
注意:fallback方法的签名须要和原方法保持一致。
/** * 获取消息详情 */ @GetMapping("/api/v1/msg/detail/{id}") @HystrixCommand(fallbackMethod = "getDetailFallback") public MessageEntity getDetail(@PathVariable(name = "id") Long id) { return messageService.getById(id); } /** * 获取消息详情退路 */ public MessageEntity getDetailFallback(Long id){ return null; }
以MessageService的Feign客户端为例,为其添加Hystrix断路器功能。
经过配置@FeignClient注解的fallback属性来位MessageServiceClient指定一个自定义的fallback处理类(MessageServiceFallback)。
@FeignClient(name = "message-service", fallback = MessageServiceFallback.class) public interface MessageServiceClient { @GetMapping("/api/v1/msg/get") public String getMsg(); }
MessageServiceFallback须要实现MessageServiceClient接口,而且在Spring容器中必须存在一个该类型的有效Bean。在这里,咱们使用@Component注解将其注入到Spring容器中。
@Component public class MessageServiceFallback implements MessageServiceClient { @Override public String getMsg() { System.out.println("调用消息接口失败,对其进行降级处理!"); return "消息接口繁忙,请稍后重试!"; } }
在新版本的Springcloud中,Feign默认关闭了对Hystrix的支持,须要在application.yml进行配置:
feign: hystrix: enabled: true
当message-service服务不可用时,请求 http://localhost:8781/api/v1/center/msg/get,返回结果以下:
查看后台日志,打印以下内容,代表fallback方法被成功调用了:
Actuator是Springboot提供的用来对应用系统进行自省和监控的功能模块,借助于Actuator开发者能够很方便地对应用系统某些监控指标进行查看、统计等。
若要使用Actuator对Hystrix 流进行监控,除了需在工程POM文件中引入spring-boot-starter-actuator依赖:
<!-- Actuator 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
还须要在application.yml 中添加以下配置:
management: endpoints: web: exposure: include: hystrix.stream
使用Hystrix一个最大的好处就是它会为咱们自动收集每个HystrixCommand的信息,并利用Hystrix-Dashboard经过一种高效的方式对每个断路器的健康状态进行展现。
值得注意的是,在使用HystrixCommand对RibbonClient进行包装的时候,你须要确保你配置的Hystrix超时时间要比Ribbon的超时时间长,包括由它们引发的重试时间,举个例子:若是你的Ribbon链接超时时间是1秒,而且Ribbon会连续重试请求3次,那么你的Hystrix链接超时时间须要配置成稍大于3秒。
在 pom.xml 文件中引入Hystrix-Dashboard依赖:
<!-- Hystrix Dashboard 依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency>
在MessageCenterApplication启动类上增长@EnableHystrixDashboard注解:
@EnableFeignClients @SpringCloudApplication @EnableHystrixDashboard public class MessageCenterApplication { public static void main(String[] args) { new SpringApplicationBuilder(MessageCenterApplication.class).web(WebApplicationType.SERVLET).run(args); } }
启动应用,访问 http://localhost:8781/hystrix ,打开Hystrix-Dashboard监控首页。
在这里配置好须要监控的Hystrix流地址 http://localhost:8781/actuator/hystrix.stream ,开始监控。
参考文章
https://github.com/netflix/hystrix/wiki
https://github.com/netflix/hystrix
https://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html