复杂的分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。

服务雪崩

多个微服务之间调用的时候,假设微服务调用服务B和微服务C,微服务B和微服务C又调用其他服务,这就是所谓的"扇出"。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的“雪崩效应”。

对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。

一.Hystrix是什么

Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。

"断路器"本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方法返回一个符合预期的、可以处理的备选响应(Fallback),而不是长时间的等待或者抛出调用方法无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统的蔓延,乃至雪崩。

二.服务熔断

服务熔断

熔断机制是应对雪崩效应的一种微服务链路保护机制。

当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回"错误"的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败就会启动熔断机制。熔断机制的注解是@HystrixCommand。

参考microservice-provider-dept-8001项目,新建microservice-provider-dept-hystrix-8001项目

pom修改

主要修改的是artifactId以及引入hystrix的依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <parent>
<groupId>com.wang.springcloud</groupId>
<artifactId>microservice</artifactId>
<version>1.0-SNAPSHOT</version>
</parent> <artifactId>microservice-provider-dept-hystrix-8001</artifactId> <dependencies>
<!-- 引入自己定义的api通用包,可以使用Dept部门Entity -->
<dependency>
<groupId>com.wang.springcloud</groupId>
<artifactId>microservice-api</artifactId>
<version>${project.version}</version>
</dependency>
<!-- actuator监控信息完善 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 将微服务provider注册进eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- 修改后立即生效,热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!--hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
</dependencies> </project>

yml文件修改

文件的其他配置不变,只需要修改instance-id以及info的名称就可以了

eureka:
client:
service-url:
#defaultZone: http://localhost:7001/eureka
defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka,http://localhost:7002/eureka
instance:
instance-id: microservice-dept-hystrix-8001
prefer-ip-address: true #访问路径可以显示ip地址 info:
app.name: microservice
company.name: www.waaaa.com
build.artifactId: microservice-provider-dept-hystrix-8001
build.version: 1.0-SNAPSHOT

修改DeptController

package com.wang.springcloud.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.wang.springcloud.entities.Dept;
import com.wang.springcloud.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*; import java.util.List; @RestController //自带@ResponseBody,无法返回页面
public class DeptController {
@Autowired
private DeptService service = null; @RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
//一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法
@HystrixCommand(fallbackMethod = "processHystrix_Get")
public Dept get(@PathVariable("id") Long id)
{ Dept dept = this.service.get(id); if (null == dept) {
throw new RuntimeException("该ID:" + id + "没有没有对应的信息");
} return dept;
} public Dept processHystrix_Get(@PathVariable("id") Long id)
{
return new Dept().setDeptno(id).setDname("该ID:" + id + "没有没有对应的信息,null--@HystrixCommand")
.setDb_source("no this database in MySQL");
}
}

主启动类开启服务熔断

@SpringBootApplication
@EnableEurekaClient //本服务启动后会自动注册进Eureka服务中
@EnableDiscoveryClient //服务发现
@EnableHystrix //开启Hystrix服务熔断
public class DeptProviderHystrix8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProviderHystrix8001.class,args);
}
}

启动所有项目,访问http://172.16.80.15:8001/dept/get/234,查找一个不存在的数据,观察返回信息是否正确。

三.服务降级

整体资源快不够了,先将某些服务关掉,等资源足够了,再重新开启。

服务的降级是客户端完成的,与服务端没有关系。

修改microservice-api项目

新增DeptClientServiceFallbackFactory类。

package com.wang.springcloud.service;

import java.util.List;
import com.wang.springcloud.entities.Dept;
import org.springframework.stereotype.Component;
import feign.hystrix.FallbackFactory; @Component // 不要忘记添加
public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService>
{
@Override
public DeptClientService create(Throwable throwable)
{
return new DeptClientService() {
@Override
public Dept get(long id)
{
return new Dept().setDeptno(id).setDname("该ID:" + id + "没有没有对应的信息,Consumer客户端提供的降级信息,此刻服务Provider已经关闭")
.setDb_source("no this database in MySQL");
} @Override
public List<Dept> list()
{
return null;
} @Override
public boolean add(Dept dept)
{
return false;
}
};
}
}

修改DeptClientService接口

@FeignClient(value = "MICROSERVICE-DEPT",fallbackFactory=DeptClientServiceFallbackFactory.class)
public interface DeptClientService
{
@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
public Dept get(@PathVariable("id") long id); @RequestMapping(value = "/dept/list", method = RequestMethod.GET)
public List<Dept> list(); @RequestMapping(value = "/dept/add", method = RequestMethod.POST)
public boolean add(Dept dept);
}

上面修改好后记得clean,package一下,更新jar包,方便其他项目调用

修改microservice-consumer-dept-feign项目

修改yml文件

feign:
hystrix:
enabled: true

启动项目,访问http://localhost/consumer/get/1,看看是否正确返回数据,关掉服务提供者项目,再次访问该接口,观察返回的结果。

四.服务熔断/降级总结

服务熔断

一般是某个服务故障或异常引起,类似现实世界中的"保险丝",当某个异常条件被触发,直接熔断整个服务,而不是一直等到此服务超时。

服务降级

所谓降级,一般是从整体负荷考虑。就是当某个服务熔断后,服务器不再被调用,此时客户端可以自己准备一个本地的fallback回调,返回一个缺省值。这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强。

五.服务监控Hystrix Dashboard

除了隔离依赖服务的调用之外,Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求多少成功,多少失败等。Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合,对监控内容转化成可视化界面。

工程搭建

1.新建microservice-consumer-hystrix-dashboard模块

2.pom文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <parent>
<groupId>com.wang.springcloud</groupId>
<artifactId>microservice</artifactId>
<version>1.0-SNAPSHOT</version>
</parent> <artifactId>microservice-consumer-hystrix-dashboard</artifactId> <dependencies>
<!-- 自己定义的api -->
<dependency>
<groupId>com.wang.springcloud</groupId>
<artifactId>microservice-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 修改后立即生效,热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- Ribbon相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- feign相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<!-- hystrix和 hystrix-dashboard相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
</dependencies>
</project>

3.主启动类注解

开启HystrixDashboard的相关注解。

package com.wang.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; @SpringBootApplication
@EnableHystrixDashboard
public class DeptConsumerHystrixDashboard {
public static void main(String[] args) {
SpringApplication.run(DeptConsumerHystrixDashboard.class,args);
}
}

4.yml文件配置

server:
port: 9001

上述步骤配置完成后,启动项目,访问http://localhost:9001/hystrix,若一切顺利,就可以看到Hystrix Dashboard的首页了。

那么该如何使用Hystrix Dashboard呢?

启动3个eureka集群,启动microservice-provider-dept-hystrix-8001。

填写监控地址

首先填写好监控地址:http://要监控的主机名:要监控的端口号/hystrix.stream

Delay:该参数用来控制服务器上轮询监控信息的延迟时间,默认为2000毫秒,可以通过配置该属性来降低客户端的网络和CPU消耗。

Title:该参数对应了头部标题Hystrix Stream之后的内容,默认会使用具体监控实例的URL,可以通过配置该信息来展示更合适的标题。

查看图形化页面

上述信息填写好后,点击Monitor Stream按钮,来到图形监控页面。

不断刷新http://localhost:8001/dept/get/2页面,然后观察下面的图形变化。

七色:左边七个颜色的数字分别对应右边七种颜色说明。

Success成功| Short-Circuited短路 | Bad Request请求无效 | Timeout超时 | Rejected拒绝| Failure失败 | Error %错误

一圈:左边实心圆有两种含义,它通过颜色的变化代表了实例的健康程度,它的健康度从绿色<黄色<橙色<红色递减。该实心圆除了颜色的变化之外,它的大小也会根据实例的请求流量发生变化,流量越大该实心圆越大,所以通过实心圆的展示就可以在大量实例中快速的发现故障实例和高压力实例。

一线:用来监控2分钟内流量的相对变化,可以通过它观察到流量的上升和下降趋势。

SpringCloud与微服务Ⅷ --- Hystrix断路器的更多相关文章

  1. SpringCloud与微服务系列专栏

    一. 前置知识 学习SpringCloud之前需要具备和掌握如下框架和工具的使用:SpringMVC,Spring,Spring Boot,Mybatis,Maven,Git. SpringCloud ...

  2. 用SpringCloud进行微服务架构演进

    在<架构师必须要知道的阿里的中台战略与微服务> 中已经阐明选择SpringCloud进行微服务架构实现中台战略,因此下面介绍SpringCloud的一些内容,SpringCloud已经出来 ...

  3. SpringCloud学习--微服务架构

    目录 微服务架构快速指南 SOA Dubbo Spring Cloud Dubbo与SpringCloud对比 微服务(Microservice)架构快速指南 什么是软件架构? 软件架构是一个包含各种 ...

  4. springCloud进阶(微服务架构&Eureka)

    springCloud进阶(微服务架构&Eureka) 1. 微服务集群 1.1 为什么要集群 为了提供并发量,有时同一个服务提供者可以部署多个(商品服务).这个客户端在调用时要根据一定的负责 ...

  5. 基于Spring-Cloud的微服务框架设计

    基于Spring-Cloud的微服务框架设计 先进行大的整体的框架整理,然后在针对每一项进行具体的详细介绍

  6. springCloud搭建微服务集群+Zuul服务器端负载均衡

    概述 最近研究了一下springCloud的微服务集群,主要用到了SpringCloud的服务发现和服务器端负载均衡,所有的项目都是用的springboot,可以和springCloud无缝对接. 技 ...

  7. 一个C#开发者学习SpringCloud搭建微服务的心路历程

    前言 Spring Cloud很火,很多文章都有介绍如何使用,但对于我这种初学者,我需要从创建项目开始学起,所以这些文章对于我的启蒙,帮助不大,所以只好自己写一篇文章,用于备忘. SpringClou ...

  8. 【SpringCloud构建微服务系列】学习断路器Hystrix

    一.Hystrix简介 在微服务架构中经常包括多个服务层,比如A为B提供服务,B为C和D提供服务,如果A出故障了就会导致B也不可用,最终导致C和D也不可用,这就形成了雪崩效应. 所以为了应对这种情况, ...

  9. java框架之SpringCloud(1)-微服务及SpringCloud介绍

    微服务概述 是什么 业界大牛 Martin Fowler 这样描述微服务: 参考[微服务(Microservices)-微服务原作者Martin Flower博客翻译]. 下面是关于上述博客中的部分重 ...

随机推荐

  1. 22.文本框验证和外部url的调用

    面板可以右键固定到浏览器并且横向纵向都剧中 如果要在图片上进行点击或者其他操作 可以覆盖一个图片热区或者矩形(透明的)充当一个按钮的操作 这个提示的图片是默认隐藏的 通过右上角那个隐藏的勾 文本框右边 ...

  2. jsp中获取页面的相对路径

    1.在jsp页面的上方加上这段java代码 <%//        request.getContextPath() 返回当前页面所在的应用的名字://        request.getSc ...

  3. linux下tomcat相关的命令

    1.查看Tomcat是否以关闭 ps -ef|grep tomcat 2.直接干掉Tomcat可以使用kill命令,直接杀死Tomcat进程(这个命令用在当你关闭tomcat报错的时候直接杀死进程) ...

  4. DOCKER学习_010:Docker的文件系统以及制作镜像

    一 文件系统简介 1.1 Linux文件系统 LInux空间组成分为内核空间和用户空间(使用rootfs) linux文件系统由 bootes和 rootfs组成, bootes主要包含boot1 o ...

  5. 聊一聊 MySQL 中的事务及其实现原理

    说到数据库,那就一定会聊到事务,事务也是面试中常问的问题,我们先来一个面试场景: 面试官:"事务的四大特性是什么?" 我:"ACID,即原子性(Atomicity).隔离 ...

  6. Python 进程、线程、协程的介绍与使用

    一.必备的理论基础 二.操作系统发展史 三.进程理论 四.线程理论 五.协程 一.必备的理论基础 操作系统理论: 操作系统是一个协调\管理\控制计算机硬件资源与应用软件资源的控制程序 操作系统的两大功 ...

  7. $Noip2014/Luogu2312$ 解方程

    $Luogu$ $Sol$ 枚举解+秦九韶公式计算+取模. $Code$ #include<iostream> #include<cstdio> #include<cst ...

  8. PrototypePattern(原型模式)-----Java/.Net

    原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式.

  9. Maven 生命周期的概念(指令默认顺序执行)

    生命周期的概念 IDEA中使用maven构建项目都集中放到了窗口右侧"Maven Projects"中,点击该区域可以直观的看到,maven中几个常用指令都归类为LifeCycle ...

  10. Codeforces Round #524 (Div. 2)(前三题题解)

    这场比赛手速场+数学场,像我这样读题都读不大懂的蒟蒻表示呵呵呵. 第四题搞了半天,大概想出来了,但来不及(中途家里网炸了)查错,于是我交了两次丢了100分.幸亏这次没有掉rating. 比赛传送门:h ...