Springcloud--Hystrix

一、Hystrix

Hystrix是一个技术解决方案。通过服务隔离,服务熔断,服务降级等方式提供整个系统弹性。

首先在消费端和服务端进行导入Hystrix的jar包

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

配置yml文件,并没有hystrix的相关配置

server:
  port: 8081

spring:
  application:
    name: cloud-provider-hystrix

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka

1. 服务降级:当服务不可用,客户端就会一直等待到超时为止,系统应该直接返回一个服务暂时不可用提示,让客户端不用等待。这样也可以防止雪崩效应。

在服务端的服务降级:

controller进行调用服务

@RestController
public class PaymentController {
    @Resource
    private PaymentService paymentService;

    @GetMapping("/payment/hystrix_fail/{id}")
    public String payinfo_fail(@PathVariable("id") Integer id) throws InterruptedException {
        return paymentService.payinfo_fail(id);
    }
}

在service层进行服务降级

@Service
public class PaymentService {
    // 出现服务降级会去找paymentHandler方法,超时时间定义为3秒
    @HystrixCommand(fallbackMethod = "paymentHandler",
            commandProperties ={@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")})
    public String payinfo_fail(Integer id) throws InterruptedException {
        Thread.sleep(5000);
        return "线程池fail"+Thread.currentThread().getName();
    }

    public String paymentHandler(Integer id){
        return "接口调用异常";
    }
}

主启动类:

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker  // 开启Hystrix
public class Hystrixmain {
    public static void main(String[] args) {
        SpringApplication.run(Hystrixmain.class, args);
    }
}

在消费端进行1对1的服务降级:

@RestController
public class OrderHystrixController {
    @Resource
    private PaymentService paymentService;

    @GetMapping("/consumer/payment/hystrix_fail/{id}")
    // 一对一形式的服务降级,当前方法出错就会找fallbackMethod定义好的方法
    @HystrixCommand(fallbackMethod = "holdpayment", commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")})
    public String payinfo_fail(@PathVariable("id") Integer id) throws InterruptedException {
        return paymentService.payinfo_fail(id);
    }

    public String holdpayment(@PathVariable("id") Integer id){
        return "gogoggo";
    }
}

在消费端进行1对多的服务降级:

为了防止同一类的方法都要定义服务降级这种代码冗余出现,出现了一对多的服务降级

@RestController
@DefaultProperties(defaultFallback = "gTest") // 一对多降级,只要添加了HystrixCommand注解服务降级的方法都是defaultFallback 定义的方法
public class OrderHystrixController {

    @Resource
    private PaymentService paymentService;

    @GetMapping("/consumer/payment/hystrix_fail/{id}")
    @HystrixCommand
    public String payinfo_fail(@PathVariable("id") Integer id) throws InterruptedException {
        return paymentService.payinfo_fail(id);
    }

    public String gTest(){
        return "fafafafafaf";
    }
}

在消费端进行通配的服务降级:

为了防止代码冗余以及结构混乱所以出现了此方法,首先需要进行yml文件的添加

feign:
  hystrix:
    enabled: true

在OpenFeign接口中@FeignClient注解的fallback进行定义,首先创建一个OpenFeign接口的实现类

/**服务降级类,这个类中每一个方法都对应一个服务降级的方法*/
@Component
public class FallBackSService implements PaymentService{
    public String payinfo_Ok(Integer id) {
        return "--------payinfo_Ok";
    }

    public String payinfo_fail(Integer id) {
        return "-------payinfo_fail";
    }
}

主启动类:

@SpringBootApplication
@EnableFeignClients
@EnableHystrix  // 启用Hystrix客户端
public class OrderHystrix {
    public static void main(String[] args) {
        SpringApplication.run(OrderHystrix.class, args);
    }
}

2. 服务熔断:服务中的熔断产生的原因就是并发过大。

服务熔断一般发生在服务端,Controller进行service调用

@RestController
public class PaymentController {
    @Resource
    private PaymentService paymentService;

    @GetMapping("/payment/circuit/{id}")
    public String paymentCircuitBreaker(@PathVariable("id") Integer id) {
        String result = paymentService.paymentCircuitBreaker(id);
        log.info("*****result: " + result);
        return result;
    }
}

在service层进行熔断规则定义:

@Service
public class PaymentService {
    // 这个断路器的意思是在10秒钟内10次请求有60%的错误率就跳闸
    @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),              //是否开启断路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),    //请求数达到后才计算
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), //休眠时间窗
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),  //错误率达到多少跳闸
    })
    public String paymentCircuitBreaker(@PathVariable("id") Integer id) {
        if(id < 0){
            throw  new RuntimeException("****id 不能为负数");
        }
        String serialNumber = IdUtil.simpleUUID();

        return  Thread.currentThread().getName() + "\t" + "调用成功,流水号:" + serialNumber;
    }

    public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id){
        return "id 不能为负数,请稍后再试, o(╥﹏╥)o id: " + id;
    }
}

熔断条件以及定义都在HystrixCommandProperties这个类中,这里列举一小部分

protected HystrixCommandProperties(HystrixCommandKey key, HystrixCommandProperties.Setter builder, String propertyPrefix) {
        this.key = key;
        this.circuitBreakerEnabled = getProperty(propertyPrefix, key, "circuitBreaker.enabled", builder.getCircuitBreakerEnabled(), default_circuitBreakerEnabled);
        this.circuitBreakerRequestVolumeThreshold = getProperty(propertyPrefix, key, "circuitBreaker.requestVolumeThreshold", builder.getCircuitBreakerRequestVolumeThreshold(), default_circuitBreakerRequestVolumeThreshold);
        this.circuitBreakerSleepWindowInMilliseconds = getProperty(propertyPrefix, key, "circuitBreaker.sleepWindowInMilliseconds", builder.getCircuitBreakerSleepWindowInMilliseconds(), default_circuitBreakerSleepWindowInMilliseconds);
}

3. Hystrix仪表盘

为了更好的图形化展示服务调用的过程,我们可以用Hystrix Dashboard进行展示

首先我们需要导入Hystrix Dashboard相关的jar包

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
   <version>2.2.2.RELEASE</version>
</dependency>

在yml文件进行端口号的定义,在主启动类开启仪表盘注解

@SpringBootApplication
@EnableHystrixDashboard  // 开启豪猪哥仪表盘
public class Dashboard {
    public static void main(String[] args) {
        SpringApplication.run(Dashboard.class, args);
    }
}

然后在需要监视的服务上进行 bean的注册,这是spring cloud升级的一个坑

/**这是服务监控而 配置,与服务容错无关,这是一个坑,因为springboot的默认配置不是/hystrix.stream,在自己项目下配置servlet即可**/
    @Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet() ;
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return  registrationBean;
    }

然后开启服务,访问http://localhost:9001/hystrix 就能看到豪猪哥的主页面了, 此时就成功了。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值