SpringCloud梳理-hystrix断路器

1.Hyxtrix

系统容错工具

hystrix的主要功能:降级熔断

1.1降级

调用远程服务失败(异常、超时、服务不存在),可以通过执行当前服务中的一段代码来向客户端发回响应
降级响应
错误提示
返回缓存数据
快速失败
即使后台服务故障,也要让客户端尽快得到错误提示,而不能让客户端等待

1.2添加降级

1.添加 Hystrix 依赖
2.启动类添加 @EnableCircuitBreaker
3.添加降级代码 在远程调用方法上添加@HystrixCommand(fallbackMethod="降级方法")完成降级方法,返回降级响应.

1.2hystrix 超时

默认1秒超时,执行降级
如果配置了ribbon重试,重试还会继续执行,最终重试结果无效
Hystrix超时 >= Ribbon 总的超时时长

1.3hystrix 熔断

当请求量增大、出现过多错误,hystrix可以和后台服务断开连接(过热保护)
可以避免雪崩效应、故障传播
限流措施
流量过大时造成服务故障,可以断开服务,降低它的流量
在特定条件下会自动触发熔断
10秒内20次请求(必须首先满足)
50%出错,执行降级代码.
半开状态下可以自动恢复.
断路器打开几秒后,进入半开状态,尝试发送请求
如果请求成功自动关闭断路器恢复正常
如果请求失败,再保持打开几秒钟

1.4Hystrix Dashboard

Hystrix监控仪表盘,监控Hystrix降级和熔断的错误信息.

1.4.1 actuator

springboot提供的项目监控工具,提供了多种项目的监控数据.
1.健康状态
2.系统环境
3.beans-spring容器中所有的对象
4.mappings - spring mvc 所有映射的路径
......
hystrix在actuator中,添加了自己的监控数据.

1.4.2添加actuator

1.添加actuator依赖
2.yml配置暴露监控信息
m.e.w.e.i="*" - 暴露所有监控
m.e.w.e.i=["health", "beans", "mappings"]
m.e.w.e.i=bean
3.http://xxxxxxxxx/actuator/

1.5搭建Hystrix Dashboard

1.添加Hystrix Dashboard依赖
2.yml配置配置端口
3.添加@EnableHystrixDashboard注解
4.访问访问 http://xxxxxxx/hystrix在输入框填写要监控的数据路径.

2.代码演示

2.1、ribbon + hystrix 断路器

https://github.com/Netflix/Hystrix/wiki

SpringCloud梳理-hystrix断路器_第1张图片

2.2微服务宕机时,ribbon无法转发请求.

关闭item-service

SpringCloud梳理-hystrix断路器_第2张图片

SpringCloud梳理-hystrix断路器_第3张图片

2.3复制ribbon项目,改名为hytrix

image

2.3.1修改pom.xml文件

SpringCloud梳理-hystrix断路器_第4张图片

2.3.2添加hystrix起步依赖


    org.springframework.cloud
    spring-cloud-starter-netflix-hystrix

2.3.3修改application.yml文件

SpringCloud梳理-hystrix断路器_第5张图片


spring:
  application:
    name: hystrix
    
server:
  port: 3001
  
eureka:
  client:    
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka
      
ribbon:
  MaxAutoRetries: 1
  MaxAutoRetriesNextServer: 2
  OkToRetryOnAllOperations: true

2.3.4启动类添加@EnableCircuitBreaker注解启用hystrix断路器

启动断路器,断路器提供的两大核心
降级,超时 出错 不可到达时 对服务器降级 返回错误信息或者是缓存数据.
熔断当服务压力过大时 错误比例过多时 熔断有所请求时 所有请求直接降级.
package com.tedu.sp06;

import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

//@EnableCircuitBreaker
//@EnableDiscoveryClient
//@SpringBootApplication

@SpringCloudApplication
public class Sp06RibbonApplication {

    @LoadBalanced
    @Bean
    public RestTemplate getRestTemplate() {
        SimpleClientHttpRequestFactory f = new SimpleClientHttpRequestFactory();
        f.setConnectTimeout(1000);
        f.setReadTimeout(1000);
        return new RestTemplate(f);
        
        //RestTemplate 中默认的 Factory 实例中,两个超时属性默认是 -1,
        //未启用超时,也不会触发重试
        //return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(Sp06RibbonApplication.class, args);
    }

}

2.4RibbonController中添加降级方法

为每个方法添加降级方法.
添加@HystrixCommand注解,指定降级方法名
package com.tedu.sp06.consoller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.tedu.sp01.pojo.Item;
import com.tedu.sp01.pojo.Order;
import com.tedu.sp01.pojo.User;
import com.tedu.web.util.JsonResult;

@RestController
public class RibbonController {
    @Autowired
    private RestTemplate rt;
    
    @GetMapping("/item-service/{orderId}")
    @HystrixCommand(fallbackMethod = "getItemsFB") //指定降级方法的方法名
    public JsonResult> getItems(@PathVariable String orderId) {
        return rt.getForObject("http://item-service/{1}", JsonResult.class, orderId);
    }

    @PostMapping("/item-service/decreaseNumber")
    @HystrixCommand(fallbackMethod = "decreaseNumberFB")
    public JsonResult decreaseNumber(@RequestBody List items) {
        return rt.postForObject("http://item-service/decreaseNumber", items, JsonResult.class);
    }

    /
    
    @GetMapping("/user-service/{userId}")
    @HystrixCommand(fallbackMethod = "getUserFB")
    public JsonResult getUser(@PathVariable Integer userId) {
        return rt.getForObject("http://user-service/{1}", JsonResult.class, userId);
    }

    @GetMapping("/user-service/{userId}/score") 
    @HystrixCommand(fallbackMethod = "addScoreFB")
    public JsonResult addScore(@PathVariable Integer userId, Integer score) {
        return rt.getForObject("http://user-service/{1}/score?score={2}", JsonResult.class, userId, score);
    }
    
    /
    
    @GetMapping("/order-service/{orderId}")
    @HystrixCommand(fallbackMethod = "getOrderFB")
    public JsonResult getOrder(@PathVariable String orderId) {
        return rt.getForObject("http://order-service/{1}", JsonResult.class, orderId);
    }

    @GetMapping("/order-service")
    @HystrixCommand(fallbackMethod = "addOrderFB")
    public JsonResult addOrder() {
        return rt.getForObject("http://order-service/", JsonResult.class);
    }
    
    /

    //降级方法的参数和返回值,需要和原始方法一致,方法名任意
    public JsonResult> getItemsFB(String orderId) {
        return JsonResult.err("获取订单商品列表失败");
    }
    public JsonResult decreaseNumberFB(List items) {
        return JsonResult.err("更新商品库存失败");
    }
    public JsonResult getUserFB(Integer userId) {
        return JsonResult.err("获取用户信息失败");
    }
    public JsonResult addScoreFB(Integer userId, Integer score) {
        return JsonResult.err("增加用户积分失败");
    }
    public JsonResult getOrderFB(String orderId) {
        return JsonResult.err("获取订单失败");
    }
    public JsonResult addOrderFB() {
        return JsonResult.err("添加订单失败");
    }

}

2.5hystrix短路超时设置

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds
为了测试hystrix短路功能,我们把hystrix等待超时设置得非常小(500毫秒)
此设置一般应大于ribbon的重试超时时长,例如10秒

spring:
  application:
    name: hystrix
    
server:
  port: 3001
  
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka
      
ribbon:
  MaxAutoRetriesNextServer: 2
  MaxAutoRetries: 1
  OkToRetryOnAllOperations: true
  
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 500
            

2.6启动项目测试

SpringCloud梳理-hystrix断路器_第6张图片

通过hystrix服务,访问可能超时失败的item-service(设置了延迟)

http://localhost:3001/item-service/35

通过hystrix服务,访问未启动的user-service

http://localhost:3001/user-service/7

可以看到,如果item-service请求超时时,hystrix会立即执行降级方法.
访问user-service,由于该服务未启动,hystrix也会立即执行降级方法.

SpringCloud梳理-hystrix断路器_第7张图片

3.hystrix dashboard 断路器仪表盘

SpringCloud梳理-hystrix断路器_第8张图片

hystrix对请求的熔断和断路处理,可以产生监控信息,提供了各种监控信息的监控端点.
management.endpoints.web.exposure.include 配置选项,可以指定端点名,来暴露监控端点.
如果要暴露全部端点可以用"*"

3.1修改pom.xml文件


    org.springframework.boot
    spring-boot-starter-actuator

3.2调整application配置,并暴露hystrix监控端点

spring:
  application:
    name: hystrix
    
server:
  port: 3001
  
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka
      
ribbon:
  MaxAutoRetriesNextServer: 1
  MaxAutoRetries: 1
  OkToRetryOnAllOperations: true
  
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 2000

management:
  endpoints:
    web:
      exposure:
        include: hystrix.stream

3.3访问actuator路径,查看监控端点

http://localhost:3001/actuator

SpringCloud梳理-hystrix断路器_第9张图片

4.新建hystrix-dashboard项目

SpringCloud梳理-hystrix断路器_第10张图片

SpringCloud梳理-hystrix断路器_第11张图片

4.1修改pom.xml文件



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.4.RELEASE
         
    
    com.tedu
    sp08-hystrix-dashboard
    0.0.1-SNAPSHOT
    sp08-hystrix-dashboard
    Demo project for Spring Boot

    
        1.8
        Greenwich.SR1
    

    
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-hystrix-dashboard
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    

    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                ${spring-cloud.version}
                pom
                import
            
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    




4.2修改application.yml

spring:
  application:
    name: hystrix-dashboard
    
server:
  port: 4001

eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka

4.3修改启动类添加@EnableHystrixDashboard注解和@EnableDiscoveryClient注解

package com.tedu.sp08;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;

@EnableDiscoveryClient
@EnableHystrixDashboard
@SpringBootApplication
public class Sp08HystrixDashboardApplication {

    public static void main(String[] args) {
        SpringApplication.run(Sp08HystrixDashboardApplication.class, args);
    }

}

4.4启动,访问测试

SpringCloud梳理-hystrix断路器_第12张图片

访问hystrix dashboard

http://localhost:4001/hystrix
SpringCloud梳理-hystrix断路器_第13张图片

填入hystrix的监控点 开启监控

http://localhost:3001/actuator/hystrix.stream
SpringCloud梳理-hystrix断路器_第14张图片

通过hystrix多次访问 观察监控信息

http://localhost:3001/item-service/35

http://localhost:3001/user-service/7

http://localhost:3001/user-service/7/score?score=100

http://localhost:3001/order-service/123abc

http://localhost:3001/order-service/

SpringCloud梳理-hystrix断路器_第15张图片

SpringCloud梳理-hystrix断路器_第16张图片

4.5hystrix熔断

整个链路达到一定的阀值,默认情况下 10秒内产生超过20次请求,则符合第一个条件.
满足第一个条件的情况下,如果请求的错误百分比大于阈值,则会打开断路器,默认为50%.
hystrix逻辑,先判断是否满足第一个条件,在判断第二个条件,如果两个条件都满足,则会开启断路器.
短路器开启5秒后,会处于半开状态,会尝试转发请求,如果仍然失败,保持打开状态,如果成功,则关闭断路器.

4.6使用apache的并发访问测试工具ab

http://httpd.apache.org/docs/current/platform/windows.html#down
SpringCloud梳理-hystrix断路器_第17张图片

使用ab工具,以并发50次,来发送2000个请求.
ab -n 20000 -c 50 http://localhost:3001/item-service/35
断路器状态为Open,所有请求会被短路,直接降级执行fallback方法.

SpringCloud梳理-hystrix断路器_第18张图片

4.7hystrix配置

https://github.com/Netflix/Hystrix/wiki/Configuration

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 请求超时时间,超时后触发失败降级.
hystrix.command.default.circuitBreaker.requestVolumeThreshold 10秒内请求数量,默认20,如果没有达到改数量,既使请求全部失败,也不会触发断路器打开.
hystrix.command.default.circuitBreaker.errorThresholdPercentage 失败请求百分比,达到该比例则触发断路器打开.
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds 断路器打开多长时间后,再次允许访问尝试(半开),仍失败则继续保持打开状态,如果成功访问关闭断路器,默认5000.

你可能感兴趣的:(java)