服务容错-Hystrix与聚合服务信息-Turbine

一、服务雪崩、降级与熔断

1、服务雪崩

  假设我们有个微服务调用链 ServiceA 调用 ServiceB 调用 ServiceC,而此时,Service A的流量波动很大,流量经常会突然性增加!那么在这种情况下,就算Service A能扛得住请求,Service B和Service C未必能扛得住这突发的请求。此时,如果Service C因为抗不住请求,变得不可用。那么Service B的请求也会阻塞,慢慢耗尽Service B的线程资源,Service B就会变得不可用。紧接着,Service A也会不可用。
  一个服务失败,导致整条链路的服务都失败的情形,我们称之为服务雪崩。

2、服务降级与熔断

这里有两种场景:

  • 服务降级:当下游的服务因为某种原因响应过慢,下游服务主动停掉一些不太重要的业务,释放出服务器资源,增加响应速度!
  • 服务熔断:当下游的服务因为某种原因不可用,上游主动调用本地的一些降级逻辑,避免卡顿,迅速返回给用户!

两者其实从有些角度看是有一定的类似性的:

  • 目的很一致,都是从可用性可靠性着想,为防止系统的整体缓慢甚至崩溃,采用的技术手段;
  • 最终表现类似,对于两者来说,最终让用户体验到的是某些功能暂时不可达或不可用;
  • 粒度一般都是服务级别,当然,业界也有不少更细粒度的做法,比如做到数据持久层(允许查询,不允许增删改);
  • 自治性要求很高,熔断模式一般都是服务基于策略的自动触发,降级虽说可人工干预,但在微服务架构下,完全靠人显然不可能,开关预置、配置中心都是必要手段;

而两者的区别也是明显的:

  • 触发原因不太一样,服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;
  • 管理目标的层次不太一样,熔断其实是一个框架级的处理,每个微服务都需要(无层级之分),而降级一般需要对业务有层级之分(比如降级一般是从最外围服务开始)

二、Hystrix

Hystrix中三个特色功能

  • 断 - 熔断
  • 舍 - 降级
  • 离 - 线程隔离

1、Hystrix工作原理

  1. @HystrixCommand: 在方法上安插监视器,标识此方法由Hystrix监管
  2. AspectJ:运用Spring的切面能力,给带有@HystrixCommand注解的方法配置了切面点,在方法调用的时候,将首先执行切面逻辑。
  3. Request Cache:
    • 如果处于开启状态,则尝试用CacheKey从本地缓存中获取数据,也就不用发起方法调用了
    • 如果处于关闭状态,就继续往下走到最烧脑的部分,Observer
  1. 注册Observer:Observer是观察者模式(在RxJava中又叫Observable),但这里只是一个幌子,这个Observer背后运用RxJava注册了一堆异步回调函数,当方法正常执行、异常抛出、结束或其他状态的时候,将会触发对应的回调函数进行处理,而且回调函数里面还会嵌套回调函数。
  2. 发起调用:在发起调用之前,将会检查熔断状态,如果断路器当前处于开启的状态,那么将直接走向fallback流程。如果断路器处于关闭,则发起真正的调用
  3. 异常,又见异常:前面你来我往这么久,就是等方法调用抛异常。异常触发了步骤4中注册的回调函数,然后直接转给了降级方法
  4. 异常发生后计算Metrics,这里的Metrics指的是衡量指标,在异常情况发生后,将会根据断路器的配置计算当前服务健康程度,如果达到熔断标准,则开启断路开关,后续的请求将直接进入fallback流程里

三、Hystrix服务降级

1、服务降级常用方案

(1)静默处理

  所谓的静默处理,就是什么也不干,在fallback逻辑中直接返回一个空值Null。

(2)默认值

  在并不确定真实结果的情况下返回一个默认值。
  打个比方,假如在商品详情页调用营销优惠接口时发生了故障,无法返回正确的计算结果,这里我们就可以在fallback逻辑中返回商品原价,作为打折后的价格,这样就相当于返回了一个没有打折优惠的计算结果。
  这种方式下接口的返回值并不是真实的,因此不能应用在某些核心主链路中。举个例子,比如下单页面就是核心主链路,是最终确定订单价格的关键步骤。假如我们对订单优惠计算采用了这种瞒天过海的默认值,那么就会实际造成用户损失。因此,这里面的优惠计算决不能返回默认值,一定要得出真实结果,如果无法获取那么宁可返回异常中断下单操作。
  那为什么商品详情页可以用默认值降级,而下单页面不能呢?这就要讲到主链路的规划,简单来说,电商平台的用户购物行为是一个漏斗模型,上宽下窄,用户流量在漏斗口最多,在尾部最少,越接近尾部的流量被转化为购物行为的比例就越高,因此越到后面对降级的容忍度就越低。商品搜索和商品详情页处于漏斗的上部,主要是导流端,在没有发生金钱往来的情况下我们可以容忍一定程度的降级误差。但对于下单页,这是整个漏斗模型的尾部,直接发生交易的环节,绝不能容忍任何金钱上的误差。在实际工作里设计商品详情页服务的时候,规定了淘系营销服务接口响应时间的上限是1000ms,超过这个数字则自动降级为0优惠。

(3)缓存异常

  假如因为缓存故障无法获取数据,在fallback逻辑中可以转而访问底层数据库(这个方法不能用在热点数据上,否则可能把数据库打挂,或者引发更大范围的服务降级和熔断,要谨慎使用)。反过来如果数据库发生故障,也可以在fallback里访问缓存,但要注意数据一致性

(4)切换备库

  一般大型应用都会采用主从+备库的方式做灾备,假如我们的主从库都发生了故障,往往需要人工将数据源切换到备份数据库(参考支付宝2015年的挖掘机事故),我们在fallback中可以先于人工干预之前自动访问备库数据。这个场景尽量限定在核心主链路接口上,不要动不动就去访问备库,以免造成脏读幻读

(5)重试

  Ribbon可以处理超时重试,但对于异常情况来说(比如当前资源被暂时锁定),我们可以在fallback中自己尝试重新发起接口调用

(6)人工干预

  有些极其重要的接口,对异常不能容忍,这里可以借助fallback启动人工干预流程,比如做日志打点,通过监控组件触发报警,通知人工介入

2、服务降级 Fallback降级小demo

(1)创建hystrix-fallback模块,修改pom文件
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- feign -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
    <!-- hystrix ,实际上feign中就集成了 hystrix-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>
(2)修改启动类
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
//启动断路器判断
@EnableCircuitBreaker
public class HystrixFallbackApplication{
    public static void main(String[] args){
        new SpringApplicationBuilder(HystrixFallbackApplication.class)
            .web(WebApplicationType.SERVLET)
            .run(args);
    }
}
(3)创建fallback降级处理类
1)其他模块的代码
  1. feign模块的接口
@FeignClient(name = "feign-client")
public interface Iservice{
   @GetMapping("/error")
   String error();
}

2.fegin模块对应的实现和接口
controller层接口

@RestController
public class MyController {
   @Autowired
   public Iservice iservice;

   @GetMapping("/error")
   public String error(){
       return iservice.error();
   }
}

service层实现

public class MyService implements Iservice{
    @Override
    public String error(){
        //添加一个报错,检查到报错就会调转到服务降级上去
        int i = 1/0;
        return "MyService:这是正常的调用返回";
    }
}
2)hystrix模块的代码

1.创建Fallback降级处理的接口,重写Iservice接口,覆盖@FeignClient注解

@FeignClient(name = "test-http",fallback = Fallback.class)
public interface MyFallbackService extends Iservice {
}

2.创建Fallback降级处理的实现类

@Component
public class Fallback implements MyFallbackService{
   @Override
   public String error(){
       return "Fallback:这是fallback的返回";
   }
}

3.创建Controller

@RestController
public class Controller{

   @Autowired
   private Iservice iservice;
   
   @GetMapping("/fallback")
   @HystrixCommand(
       commandProperties={
           //指定超时时间,一共有3中方式 ,后面都会提到
           @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value="3000")
       }
   )
   public String fallback(){
       //如果进行了全局超时配置,那么这个方法也会有超时时间,我下方的配置文件中配置了2秒超时
       //所有上面设置的3秒超时,实际上是不起作用的,在工作中需要多多注意
       return iservice.error();
   }

}
(4)修改配置传文件
spring.application.name=hystrix-consumer
server.port=50000

#允许注解重载  这个很重要,不然覆盖@FeignClient注解会报错
spring.main.allow-bean-definition-overriding=true
#eureka地址
eureka.client.serviceUrl.defaultZone=http://localhost:20000/eureka

#开启feign下的HyStrix功能
feign.hystrix.enabled=true
#是否开启服务降级
hystrix.command.default.fallback.enabled=true

#全局超时配置
hystrix.command.default.execution.timeout.enabled=true
#超时时间
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=2000
#超时以后终止线程
hystrix.command.default.execution.isolation.thread.interruptOnTimeout=true
#取消的时候终止线程
hystrix.command.default.execution.isolation.thread.interruptOnFutureCancel=true
#设置单个方法超时实例     MyFallbackService的retry方法 里面有个一个int型参数
hystrix.command.MyFallbackService#retry(int).execution.isolation.thread.timeoutInMilliseconds=4000



feign-client是服务器名称
#每台机器最大重试次数
feign-client.ribbon.MaxAutoRetries=0
#可以再重试几台机器
feign-client.ribbon.MaxAutoRetriesNextServer=0
#连接超时
feign-client.ribbon.ConnectTimeout=1000
#业务超时时间
feign-client.ribbon.ReadTimeout=8000
#在所有HTTP Method进行重试
feign-client.ribbon.OkToRetryOnAllOperations=false

3、多次降级

  总有那么几个顽固分子,在fallback里不好好改造,又捣鼓出一个异常来。这时候我们可以做二次降级,也就是在fallback中再引入一个fallback。当然,你也可以引入三四五六七八更多层的降级,对应一些复杂的大型应用,比如淘系很多核心系统,多级降级是很常见的,根据系统故障的严重程度采取更精细粒度的降级方案。

(1)多次降级小demo

1.修改之前的降级处理类

@Component
public class Fallback implements MyFallbackService{
   @Override
   //如果这个方法发生错误就去执行  error2方法
   //注意:这里error方法和error2方法的参数要保持一致
   @HystrixCommand(fallbackMethod = "error2")
   public String error(){
       int i = 1/0;
       return "Fallback:这是fallback的返回";
   }
   
   @HystrixCommand(fallbackMethod = "error3")
   public String error2(){
       int i = 1/0;
       return "Fallback:这是第二次发生错误";
   }
   
    public String error3(){
       return "Fallback:这是第三次发生错误";
   }
}

4、Request Cache减压

(1)Request Cache使用小demo

1.编写Service层

@Slf4j
@Service
public class RequestCacheService{
    @Autowired
    private MyFallbackService service;
    
    //开启结果缓存
    @CacheResult
    //针对单个方法进行降级的配置,commandKey:设置这个方法的hystrixKey  用于配置文件中设定降级配置
    //配置文件中设置如下  设置超时时间
    //hystrix.command.cacheKey.execution.isolation.thread.timeoutInMilliseconds=4000
    @HystrixCommand(commandKey = "cacheKey")
    //@CacheKey  缓存的key 当name一样的时候 使用缓存
    public Friend requestCache(@CacheKey String name){
        Friend friend = new Friend();
        friend.setName(name);
        //打印输入的名字,输出多次的话,说明执行了多次
        friend=service.sayName(friend);
        return friend;
    }
}

2.编写controller层

@RestController
public class Controller{
    @Autowired
    private RequestCacheService requestCacheService;
    
    @GetMapping("/cache")
    public Friend cache(String name){
        HystrixRequestContext context = HystrixRequestContext.initializeContext();
        //如果使用了lombok,可以这样写,就不用写try-finally,在方法结束的时候会自动调用close方法
       // @Cleanup HystrixRequestContext context = HystrixRequestContext.initializeContext();
        
        try{
        Friend friend = requestCacheService.requestCacha(name);
        //这里同一个方法调用两次,执行后可以查看是在一个上下文环境中requestCacha被执行了几次
        friend = requestCacheService.requestCacha(name);
        return friend;
        }finally{
            context.close;
        }
    }
}

3.修改配置传文件

#开启访问缓存功能
hystrix.command.default.requsetCache.enabled=true

  有人就要问了,那个渣渣程序员,会把同一个方法执行两次呢??其实不然,如果在当前上下文调用了其他方法,我们就叫这个方法为ABC()好了,但是方法ABC是一个公用方法 中间也执行了一次requestCacha方法,这时就不能把friend修改成入参传入,不然会破会方法,可能影响到其他代码,但是可以通过使用HystrixRequestContext,可以减少服务的调用,同时并且不会影响其他代码。

四、Hystrix服务熔断

  当下游的服务因为某种原因不可用,上游主动调用本地的一些降级逻辑,避免卡顿,迅速返回给用户!不再等待发生异常后才进入降级逻辑,而是直接进入

1、熔断状态

  1. 熔断器open状态:当服务多次失败之后,服务在一定时间内不得发起外部调用,调用对象一律去fallback里
  2. 熔断器half-open状态:在fallback里待的也够久了,给一个改过自新的机会,可以尝试发起真实的服务调用,但这一切都在监视下进行
  3. 熔断器closed:无罪释放,上一步的调用成功了,那便关闭熔断,开始正常使用

2、熔断器的判断阀值

  1. 在一定时间窗口内,发生异常的请求数量达到临界值
  2. 在一定时间窗口内,发生异常的请求数量占请求总数量达到一定比例

  其中时间窗口的大小也是可以配置的,而且我们还可以指定half-open判定的时间间隔,比如说熔断开启10秒以后进入half-open状态,此时就会让一个请求发起调用,如果成功就关闭熔断器

3、熔断器相关配置参数

#熔断器全局开关  默认为true
hystrix.command.default.circuitBreaker.enabled=true
#强制开启熔断  开启后所有请求都熔断
hystrix.command.default.circuitBreaker.forceOpen=false
#强制关闭熔断  开启后所有请求都不会发生熔断
hystrix.command.default.circuitBreaker.forceClosed=false

#熔断的前提条件(请求的数量),在一定的时间窗口内,请求达到5个以后,才开始进行熔断判断
hystrix.command.default.circuitBreaker.requestVolumeThreshold=5
#当有50%的请求失败,开启熔断
hystrix.command.default.circuitBreaker.errorThresholdPercentage=50
#当熔断开启以后,经过多少秒在进入半开状态(half-open)
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=1500
#配置时间窗口,类似滑动窗口
hystrix.command.metrics.rollingStats.timeInMilliseconds=20000
#滑动窗口的统计桶,要能和上面的参数整除
hystrix.command.metrics.rollingStats.numBuckets=10

五、线程隔离

1、什么是线程隔离、为什么要线程隔离

  比如我们现在有3个业务调用分别是查询订单、查询商品、查询用户,且这三个业务请求都是依赖第三方服务-订单服务、商品服务、用户服务。三个服务均是通过RPC调用。当查询订单服务出现问题,所有的请求线程都会阻塞,这个时候后续有大量的查询订单请求过来,那么容器中的线程数会被查询订单服务一直占用,导致其他服务没有线程可用,直致CPU资源耗尽到100%,整个服务对外不可用,集群环境下就是雪崩。
  那什么是线程隔离呢,就是我们限制单个服务可以调用的线程上限,保证其他服务有着线程可有,不会因为一个服务的出现问题导致,整个系统无法使用。

2、线程隔离的三种手段

  1. 线程池拒绝:这一步是线程隔离机制直接负责的,假如当前商品服务分配了10个线程,那么当线程池已经饱和的时候就可以拒绝服务,调用请求会收到Thread Pool Rejects,然后将被转到对应的fallback逻辑中
  2. 线程Timeout:我们通常情况下认为延迟只会发生在网络请求上,其实不然,在Netflix设计Hystrix的时候,就有一个设计理念:调用失败和延迟也可能发生在远程调用之前(比如说一次超长的Full GC导致的超时,或者方法只是一个本地业务计算,并不会调用外部方法),这个设计理念也可以在Hystrix的Github文档里也有提到。因此在方法调用过程中,如果同样发生了超时,则会产生Thread Timeout,调用请求被流转到fallback
  3. 服务异常/超时:这就是我们前面学习的的服务降级,在调用远程方法后发生异常或者连接超时等情况,直接进入fallback

3、线程隔离小demo

1.实现服务线程管理类

public class CommandOrder extends HystrixCommand<String> {
    private final static Logger LOGGER = LoggerFactory.getLogger(CommandOrder.class);
    private String orderName;
    public CommandOrder(String orderName) {
        //初始化
        super(Setter.withGroupKey(
                //服务分组
                HystrixCommandGroupKey.Factory.asKey("OrderGroup"))
                //线程分组
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("OrderPool"))

                //线程池配置
                .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
                        .withCoreSize(10)
                        .withKeepAliveTimeMinutes(5)
                        .withMaxQueueSize(10)
                        .withQueueSizeRejectionThreshold(10000))

                .andCommandPropertiesDefaults(
                        HystrixCommandProperties.Setter()
                                .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD))
        )
        ;
        this.orderName = orderName;
    }


    @Override
    public String run() throws Exception {
        //这里是写业务的,正常情况下可以下一些服务调用啊
        LOGGER.info("orderName=[{}]", orderName);
        TimeUnit.MILLISECONDS.sleep(100);
        return "OrderName=" + orderName;
    }
}

2.Controller的使用

@RestController
public class OrderController {

    @RequestMapping("/order")
    public String order(){
        CommandOrder commandPhone = new CommandOrder("手机");
        CommandOrder command = new CommandOrder("电视");


        //阻塞方式执行
        String execute = commandPhone.execute();
        LOGGER.info("execute=[{}]", execute);

        //异步非阻塞方式
        Future<String> queue = command.queue();
        String value = queue.get(200, TimeUnit.MILLISECONDS);
        LOGGER.info("value=[{}]", value);
    }
}

3.注解的方式

@RestController
public class OrderController {

    @RequestMapping("/order")
    @HystrixCommand(
        commandKey = "orderFail",//全局唯一的标识服务,默认函数名称
        groupKey = "OrderGroup",//全局服务分组,用于组织仪表盘,统计信息,默认为类名
        fallbackMethod = "orderFail",//同一个类里的降级方法,public private都可以
        //在列表中的exception,不会触发降级
        ignoreExceptions = {IllegalAtgumentException.class}
        //线程有关的属性
        //线程组,多个服务可以共用一个线程组
        threadPoolKey = "threadPoolA",
        threadPoolProperties ={
            //核心线程数
            @HystrixProperty(name = "coreSize",value = "20"),
            //最大线程排队数目
            //默认为-1,低层实现使用的是SynchronousQueue,不存储元素的阻塞队列
            //当size>0,低层实现使用的是LinkedBlockingQueue,请求等待队列
            @HystrixProperty(name = "maxQueueSize",value = "40")
            //即使maxQueueSize没有达到,达到queueSizeRejectionThreshold该值后,请求也会被拒绝
            //默认为5
            //在maxQueueSize为-1的时候无效
            @HystrixProperty(name = "queueSizeRejectionThreshold",value = "15"),
        }
    )
    public String order(){
        ...
    }
    
    /**
     * 降级逻辑,参数要和被降级的方法一致,要多一个Throwable作为参数接收错误信息
     */
    public String orderFail(Throwable throwable){
        return "订单错误";
    }
}

4、线程池与信号量

  Hystrix中的线程隔离,通常我们都采用基于线程池的实现方式,这也是最容易理解的方案。Hystrix还提供了另一种底层实现,那就是信号量隔离。

  • 线程池技术:它使用Hystrix自己内建的线程池去执行方法调用,而不是使用Tomcat的容器线程
  • 信号量技术:它直接使用Tomcat的容器线程去执行方法,不会另外创建新的线程,信号量只充当开关和计数器的作用。获取到信号量的线程就可以执行方法,没获取到的就转到fallback

从性能角度看

  • 线程池技术:涉及到线程的创建、销毁和任务调度,而且CPU在执行多线程任务的时候会在不同线程之间做切换,我们知道在操作系统层面CPU的线程切换是一个相对耗时的操作,因此从资源利用率和效率的角度来看,线程池技术会比信号量慢
  • 信号量技术:由于直接使用Tomcat容器线程去访问方法,信号量只是充当一个计数器的作用,没有额外的系统资源消费,所以在性能方面具有明显的优势

超时判定

  • 线程池技术:相当于多了一层保护机制(Hystrix自建线程),因此可以直接对“执行阶段”的超时进行判定
  • 信号量技术:只能等待诸如网络请求超时等“被动超时”的情况

  根据官方建议,信号量适用在超高并发的非外部接口调用上,在其他场景上尽量使用线程池做线程隔离。

六、Turbine聚合Hystrix信息

Turbine的使用分成2个部分:收集器和监控大盘展示

1、Turbine收集器

Turbine其实也是一个服务节点,它正是借助Eureka的服务发现来完成信息聚合

  1. 配置监控服务和集群:在Turbine里我们需要配置目标服务,也就是需要Turbine实时监控的服务名称。如果应用的部署结构比较复杂,比如说分了几个大集群,这时一个Turbine节点可能就无法监管这么多的服务节点了。我们可以启用多个Turbine聚合服务,每个服务指定一个集群,用来聚合这个集群下所有服务节点的Hystrix状态。在默认单cluster的部署结构下,Turbine默认监管default cluster(课程也是采用默认配置)。
  2. 服务发现:连接Eureka注册中心,利用服务发现机制拉取服务节点列表,从中找到上一步中配置的指定服务都有哪些服务节点。
  3. 聚合信息:这一步聚合操作是Turbine的核心功能,它并不是让各个服务节点把自己的信息上报给Turbine,因为对服务节点来说它们并不知道自己是否在Turbine的监控名单上。这一步其实是由Turbine主动发起的,从服务节点的指定"/actuator"路径下的Hystrix监控接口获取信息。

2、监控大盘

Hystrix提供了一个监控大盘的服务叫Dashboard,可以简单地通过@EnableHystrixDashboard注解直接开启,它会采用图形化的方式将每个服务的运行状态显示出来,它提供了两个维度的监控:

  1. 单一节点监控:通过直接访问服务节点的“/actuator”接口,获取当前节点的Hystrix监控信息
  2. Turbine聚集信息监控:通过访问Turbine服务的“/actuator”接口,获取经过聚合后的Hystrix监控信息

3、Turbine小demo

1.一个turbine模块,修改pom文件

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
    
<!-- hystrix ,实际上feign中就集成了 hystrix-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
    
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2.修改启动类

@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
@EnableTurbine
public class TurbineApplication{
    public static void main(String[] args){
        new SpringApplicationBuilder(TurbineApplication.class)
            .web(WebApplicationType.SERVLET)
            .run(args);
    }
}

3.修改配置文件

spring.application.name=hystrix-turbine
server.port=52000
#管理端的端口
management.port=52001

#eureka地址
eureka.client.serviceUrl.defaultZone=http://localhost:20000/eureka

#指定了所需要监控的服务名
turbine.app-config=test-http
#所在集群的名字为default
turbine.cluster-name-expression="default"
#根据host和port进行数据的服务数据聚合,默认仅为host
turbine.combine-host-port=true
#服务实例的收集信息的端点地址
turbine.instanceUrlSuffix.default=actuator/hystrix.steam
#指定聚合哪些集群,多个使用”,”分割,默认为defaul,与turbine.cluster-name-expression配合使用
turbine.aggregator.clusterConfig=default

4.修改被监控的服务的配置文件
这些服务全部由spring-boot-starter-actuator提供需要在maven中添加这个jar

#actuator 暴露接口
#不需要进行security检查
management.security.enabled=false
#需要暴露的端口,这里全部暴露
management.endpoints.web.exposure.include=*
#显示所有的health信息
management.endpoint.health.show-details=always

到这里为止 数据收集的配置全部完成了 下面就是需要配置大盘展示了

5.再创建一个模块,叫做hystrix-dashboard好了,然后我们修改以下pom的引用

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-dashboard</artifactId>
</dependency>
    
<!-- hystrix ,实际上feign中就集成了 hystrix-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
    
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

6.修改启动类

@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashboardApplication{
    public static void main(String[] args){
        new SpringApplicationBuilder(HystrixDashboardApplication.class)
            .web(WebApplicationType.SERVLET)
            .run(args);
    }
}

7.修改配置文件

spring.application.name=hystrix-dashboard
server.port=53000

#除了这两个配置,还需要知道两个路径
#单服务的监控路径
#http://ip:port/actuator/hystrix.stream
#Turbine的汇总过的监控路径
#http://ip:port/turbine.stream

8.查看监控数据
访问地址:localhost:53000/hystrix
在text框中输入需要监看的地址,就是第7步中的地址
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值