首页 > 其他 > 详细

Hystrix原理及使用

时间:2021-05-26 21:50:39      阅读:28      评论:0      收藏:0      [点我收藏+]

背景介绍

1. 服务雪崩

分布式系统环境下,服务间类似依赖非常常见,一个业务调用通常依赖多个基础服务。 

一个服务失败,导致整条链路的服务都失败的情形,我们称之为服务雪崩

 

2.引起服务雪崩和服务雪崩的三个阶段

原因大致有四:

硬件故障

程序bug

缓存击穿(用户大量访问缓存中没有键值,导致大量请求数据库,使数据库压力过大)

用户大量请求

 

服务雪崩的第一阶段:

服务不可用

调用端重试加大流量

服务调用者不可用

 

 

3.解决方案

应用扩容(加机器;升级硬件)

流量控制(限流;关闭重试)

缓存(将用户可能大量访问的数据放入缓存,减少数据库压力)

服务降级

  1. 服务接口拒绝服务
  2. 页面拒绝服务
  3. 延迟持久化
  4. 随机拒绝服务

服务熔断

 

 

入门

Hystrix是一个用于处理分布式系统延期和容错的开源库,Hystrix能保证在一个依赖出问题的情况下,不会导致整体服务失败,提高分布式弹性。

服务降级: 假设对方系统不可用了,向调用方返回一个符合预期的,可处理的备选响应,而不是长时间等待或者抛出无处理的异常。这样就保证了服务方的线程不会被长时间不必要的占用,从而避免故障在分布式系统中蔓延,乃至雪崩。

服务熔断:达到最大访问后直接拒绝访问

服务限流:秒杀高并发等操作,排队有序进行

 

代码

1.没有引入hystrix的准备工作

技术分享图片

 

 

 建这三个工程模拟Hystrix服务降级

EurekaMain7001代码:

pom:

        <!--Eureka server-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

yml:

server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com
  client:
    #表示不往注册中心注册自己
    register-with-eureka: false
    #表示自己端就是注册中心,我的职责就是维护实例
    fetch-registry: false
    #设置地址
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/

主启动类:

@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7001 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaMain7001.class, args);
    }
}

 

HystrixPaymentMain8001代码:

pom:

        <!--Eureka server-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

yml:

server:
  port: 8001

spring:
  application:
    name: cloud-payment-hystrix-service
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka/
  instance:
    instance-id: hystrix-payment8001
    prefer-ip-address: true

service层:

@Service
public class HystrixPaymentService {
    public String getPaymentInfoSuccess() {
        return "thread poor: " + Thread.currentThread().getName() + " success";
    }

    public String getPaymentInfoTimeout() {
        try {
            int spendTime = 3000;
            TimeUnit.MILLISECONDS.sleep(spendTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "thread poor: " + Thread.currentThread().getName() + " timeout";
    }
}

controller:

@RestController
@Slf4j
public class HystrixPaymentController {
    @Resource
    HystrixPaymentService service;

    @GetMapping("/payment/hystrix/ok")
    public String getPaymentInfoSuccess() {
        return service.getPaymentInfoSuccess();
    }

    @GetMapping("/payment/hystrix/timeout")
    public String getPaymentInfoTimeout() {
        return service.getPaymentInfoTimeout();
    }
}

主启动类:

@SpringBootApplication
@EnableEurekaClient
public class HystrixPaymentMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(HystrixPaymentMain8001.class, args);
    }
}

 

HystrixOrderMain80代码:

pom:

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

yml:

server:
  port: 80

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://localhost:3306/db2021?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: root

eureka:
  client:
    register-with-eureka: false
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/

ribbon:
  ReadTimeout: 5000
  ConnectTimeout: 5000

service接口:

@Component
@FeignClient(value = "CLOUD-PAYMENT-HYSTRIX-SERVICE")
public interface HystrixService {
    @GetMapping("/payment/hystrix/ok")
    public String getPaymentInfoSuccess();
    @GetMapping("/payment/hystrix/timeout")
    public String getPaymentInfoTimeout();
}

controller:

@RestController
public class HystrixController {
    @Resource
    private HystrixService hystrixService;

    @GetMapping("/consumer/payment/hystrix/ok")
    public String getPaymentInfoSuccess() {
        return hystrixService.getPaymentInfoSuccess();
    }
    @GetMapping("/consumer/payment/hystrix/timeout")
    public String getPaymentInfoFail() {
        return hystrixService.getPaymentInfoTimeout();
    }
}

主启动类:

@SpringBootApplication
@EnableFeignClients
public class HystrixOrderMain80 {
    public static void main(String[] args) {
        SpringApplication.run(HystrixOrderMain80.class, args);
    }
}

到此,payment注册到eureka, order用openFeign调用payment过程已经完成。

技术分享图片

 

 

 

 

2.压力测试

用jmeter两万个线程调用timeout接口,再通过chrome访问ok接口,会发现chrome访问的ok接口也会响应过慢。

技术分享图片

 

 技术分享图片

 

ok过慢

 技术分享图片

 

 

解决:

 

Hystrix原理及使用

原文:https://www.cnblogs.com/dayanjing/p/14814589.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!