微服务Spring Cloud (四)服务熔断 Hystrix Dashboard Turbin

转载请表明出处 https://blog.csdn.net/Amor_Leo/article/details/87879522 谢谢

Spring Cloud Hystrix概述

在微服务中,各个微服务之间通过网络进行通信,从而支撑起整个应用系统,所以,各个微服务之间不可避免的存在耦合依赖关系。但任何的服务应用实例都不可能永远的健康或网络不可能永远的都相安无事,所以一旦某个服务或局部业务发生了故障,会导致系统的不可用,我们知道当故障累积到一定程度就会造成系统层面的灾害,也就是级联故障,也叫雪崩效应,Spring Cloud Hystrix可以进行FallBack操作来服务降级,实现一个fallback方法, 当请求后端服务出现异常的时候, 可以使用fallback方法返回的值。
Spring Cloud Hystrix实现了断路器、线路隔离等一系列服务保护功能。它也是基于 Netflix 的开源框架 Hystrix 实现的,该框架的目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix 具备服务降级、服务熔断、线程和信号隔离、请求缓存、请求合并以及服务监控等强大功能。

  1. 请求熔断: 当Hystrix Command请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open). 这时所有请求会直接失败而不会发送到后端服务. 断路器保持在开路状态一段时间后(默认5秒), 自动切换到半开路状态(HALF-OPEN).这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回闭路状态(CLOSED), 否则重新切换到开路状态(OPEN). Hystrix的断路器就像我们家庭电路中的保险丝, 一旦后端服务不可用, 断路器会直接切断请求链, 避免发送大量无效请求影响系统吞吐量, 并且断路器有自我检测并恢复的能力.
  2. 服务降级:Fallback相当于是降级操作. 对于查询操作, 我们可以实现一个fallback方法, 当请求后端服务出现异常的时候, 可以使用fallback方法返回的值. fallback方法的返回值一般是设置的默认值或者来自缓存.告知后面的请求服务不可用了,不要再来了。

Spring Cloud Hystrix搭建

与Ribbon整合

  • pom
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
  </dependency>
  • yml
spring:
  application:
    name: consumer-service
server:
  port: 8080
eureka:
  client:
    service‐url:
      defaultZone: http://localhost:8761/eureka
  instance:
    prefer‐ip‐address: true  #访问路径可以显示ip地址
  • Application类
@EnableDiscoveryClient
@SpringBootApplication
@EnableCircuitBreaker  //开启Hystrix
public class ConsumerApplication {
  @Bean
  @LoadBalanced
  public RestTemplate restTemplate() {
    return new RestTemplate();
  }

  public static void main(String[] args) {
    SpringApplication.run(ConsumerMovieApplication.class, args);
  }
}
  • Controller
  	@Autowired
    private RestTemplate restTemplate;

	@HystrixCommand(fallbackMethod = "getDefaultUser")
	@GetMapping("/get/provider/test")
	public String rpc() {                  
		String forObject = restTemplate.getForObject("http://PROVIDER-SERVICE/test", String.class);
		return forObject;
	}
	
	private String getDefaultUser() {
        System.out.println("熔断,默认回调函数");
        return "Hystrix熔断";
    }

与Feign整合

  • pom
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
  </dependency>
  • yml
server:
  port: 8010
spring:
  application:
    name: consumer-service
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
feign:
  hystrix:
    enabled: true
# 请务必注意:从Spring Cloud Dalston开始,Feign默认是不开启Hystrix的。
# 因此,如使用Dalston(包括)之后请务必额外设置属性:feign.hystrix.enabled=true,否则断路器不会生效。
# 而,Spring Cloud Angel/Brixton/Camden中,Feign默认都是开启Hystrix的。无需设置该属性。
  • Application类上
@EnableDiscoveryClient
@EnableFeignClients  // 开启Feign
  • 自定义Controller
@RestController
public class ConsumerController {
  @Autowired
  private FeignClient feignClient;

  @GetMapping("/{id}")
  public String findById(@PathVariable Long id) {
    return this.feignClient.findById(id);
  }

Fallback回退

  • 回退类配置
/**
 * 回退类FeignClientFallback需实现Feign Client接口
 */
@Component
public class FeignClientFallback implements FeignClient {
  @Override
  public String findById(Long id) {
    return "Hystrix 熔断"+id;
  }
}
  • 自定义Feign接口
@FeignClient(name = "provider-service", fallback = FeignClientFallback.class)
public interface FeignClient {
	
    @RequestMapping(value = "/provider/{id}", method = RequestMethod.GET)
    public String findById(@PathVariable("id") Long id);
}

通过FallBack Factory检查回退原因

  • 自定义Feign接口
@FeignClient(name = "provider-service", fallbackFactory = FeignClientFallbackFactory.class)
public interface FeignClient {
	
    @RequestMapping(value = "/provider/{id}", method = RequestMethod.GET)
    public String findById(@PathVariable("id") Long id);
}
  • FallbackFactory 配置
/**
 * FeignClient的fallbackFactory类,该类需实现FallbackFactory接口,并覆写create方法
 */
@Component
class FeignClientFallbackFactory implements FallbackFactory<FeignClient> {

  private static final Logger LOGGER = LoggerFactory.getLogger(FeignClientFallbackFactory.class);

  @Override
  public FeignClient create(Throwable cause) {
    return new FeignClient() {
      @Override
      public String findById(Long id) {
        // 日志最好放在各个fallback方法中,而不要直接放在create方法中.
        // 否则在引用启动时,就会打印该日志
        FeignClientFallbackFactory.LOGGER.info("fallback; reason was:", cause);
        
        return  "Hystrix 熔断"+id;
      }
    };
  }
}

Feign的Hystrix的监控:

  • pom
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
  </dependency>
  • Application类上
@EnableDiscoveryClient
@EnableFeignClients
@EnableCircuitBreaker

使用dashboard可视化

  • pom
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <!--Feign支持Hystrix的监控-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    <!--Hystrix的监控可视化界面-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>
  • yml
server:
  port: 8010
spring:
  application:
    name: consumer-service
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
feign:
  hystrix:
    enabled: true   #开启熔断器
management:
  endpoints:
    web:
      exposure:
        include: "*"  #因为springboot2.1.必须加上,支持访问/actuator/hystrix.stream
  • Application类上
@EnableDiscoveryClient
@EnableFeignClients
@EnableHystrixDashboard
@EnableCircuitBreaker
  • 自定义Controller
@RestController
public class ConsumerController {
  @Autowired
  private FeignClient feignClient;

  @GetMapping("/{id}")
  public String findById(@PathVariable Long id) {
    return this.feignClient.findById(id);
  }
  • 回退类配置
/**
 * 回退类FeignClientFallback需实现Feign Client接口
 */
@Component
public class FeignClientFallback implements FeignClient {
  @Override
  public String findById(Long id) {
    return "Hystrix 熔断"+id;
  }
}
  • 自定义Feign接口
@FeignClient(name = "provider-service", fallback = FeignClientFallback.class)
public interface FeignClient {
	
    @RequestMapping(value = "/provider/{id}", method = RequestMethod.GET)
    public String findById(@PathVariable("id") Long id);
}

http://192.168.0.1:8010/hystrix/ 进入可视化界面,输入: http://192.168.0.1:8010/actuator/hystrix.stream

Turbin

  • 消费者
    • pom
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!--Hystrix的监控可视化界面-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>
    
    • yml
    management:
      endpoints:
        web:
          exposure:
            include: "*"  #因为springboot2.1.必须加上,支持访问/actuator/hystrix.stream
    
    • Application类上
    @EnableCircuitBreaker
    
  • Turbin Server
    • pom
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-turbine</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-turbine</artifactId>
    </dependency>
    
    • yml
    spring:
      application:
        name: dashboard-turbine
    server:
      port: 8020
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
      instance:
        prefer-ip-address: true
    turbine:
      app-config: consumer-service # 配置Eureka中的serviceId列表,表明监控哪些服务
      aggregator:
        clusterConfig:  default
      cluster-name-expression: new String("default")  # 表示集群的名字为default,当服务数量非常多的时候,可以启动多个Turbine服务来构建不同的聚合集群
      combine-host-port: true # 表示同一主机上的服务通过host和port的组合来进行区分,默认情况下是使用host来区分,这样会使本地调试有问题
    management:
      endpoints:
        web:
          exposure:
            include: "*"
    
    • Application类上
    @EnableTurbine
    
    访问 : http://192.168.0.1:8020/turbine.stream进入页面

Turbin+Dashboard

  • 消费者(Feign+熔断器)
    • pom
     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <!--Feign支持Hystrix的监控-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    <!--Hystrix的监控可视化界面-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>
    
    • yml
    server:
      port: 8010
    spring:
      application:
        name: consumer-service
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
      instance:
        prefer-ip-address: true
    feign:
      hystrix:
        enabled: true   #开启熔断器
    management:
      endpoints:
        web:
          exposure:
            include: "*"  #因为springboot2.1.必须加上,支持访问/actuator/hystrix.stream
    
    • Application类上
    @EnableDiscoveryClient
    @EnableFeignClients
    @EnableHystrixDashboard
    @EnableCircuitBreaker
    
  • dashboard+turbine server:
    • pom
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-turbine</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-turbine</artifactId>
    </dependency>
    
    • yml
    spring:
      application:
        name: dashboard-turbine-server
    server:
      port: 8020
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
      instance:
        prefer-ip-address: true
    turbine:
      app-config: consumer-service # 配置Eureka中的serviceId列表,表明监控哪些服务
      aggregator:
        clusterConfig:  default
      cluster-name-expression: new String("default")  # 表示集群的名字为default,当服务数量非常多的时候,可以启动多个Turbine服务来构建不同的聚合集群
      combine-host-port: true # 表示同一主机上的服务通过host和port的组合来进行区分,默认情况下是使用host来区分,这样会使本地调试有问题
    management:
      endpoints:
        web:
          exposure:
            include: "*"
    
    • Application类上
    @EnableHystrixDashboard
    @EnableTurbine
    

可以直接访问 http://192.168.0.1:8020/turbine.stream
也可以 http://192.168.0.1:8020/hystrix/ 再输入 http://192.168.0.1:8020/turbine.stream
也可以通过消费者 http://192.168.0.1:8010/hystrix/ 再输入 http://192.168.0.1:8020/turbine.stream

Turbine+Dashboard+RabbitMQ

  • 消费者
    • pom
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <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-dashboard</artifactId>
    </dependency>
    <!--Feign支持Hystrix的监控-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    <!--MQ-->	
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-netflix-hystrix-stream</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
    </dependency>
    
    • yml
    server:
      port: 8010
    spring:
      application:
        name: consumer-service
      rabbitmq:
        host: 192.168.0.111
        port: 5672
        username: admin
        password: admin
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
      instance:
        prefer-ip-address: true
    feign:
      hystrix:
        enabled: true
    management:
      endpoints:
        web:
          exposure:
            include: "*"
    
    • Application类上
    @EnableDiscoveryClient
    @EnableFeignClients
    @EnableHystrixDashboard
    @EnableCircuitBreaker
    
  • turbine+mq+dashboard server
    • pom
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-turbine-stream</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
    </dependency>
    
    • yml
    server:
      port: 8020
    spring:
      application:
        name: turbine-server
      rabbitmq:
        host: 192.168.0.111
        port: 5672
        username: admin
        password: admin
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka/
      instance:
        prefer-ip-address: true
    management:
      endpoints:
        web:
          exposure:
            include: "*"
    
    • Application类上
    @EnableTurbineStream
    @EnableHystrixDashboard
    

直接访问 http://192.168.0.1:8020/turbine.stream
先访问 http://192.168.0.1:8020/hystrix/ 再输入 http://192.168.0.1:8020/turbine.stream
先通过消费者访问 http://192.168.0.1:8010/hystrix 再输入 http://192.168.0.1:8020/turbine.stream

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值