likes
comments
collection
share

Hystrix是什么?

作者站长头像
站长
· 阅读数 17

Hystrix 的主要工作原理基于 "断路器" 和 "降级" 两个概念。以下我会一步步详细地解释这两个概念,以及 Hystrix 是如何通过这两个机制来提供延迟和容错的。

1. 断路器(Circuit Breaker)

  • 原理:断路器是一种自动化的保护机制,当 Hystrix 检测到一个服务出现问题(例如,连续多次请求失败)时,会自动"断开"这个服务,防止更多的请求发送到这个服务。这样,系统其他部分可以继续运行,不会因为一个服务的故障而全部崩溃。
  • 状态
    • 关闭状态(CLOSED):默认状态,请求可以正常访问服务。
    • 开启状态(OPEN):当错误率超过预定阈值时,断路器开启,阻止请求访问。
    • 半开状态(HALF-OPEN):经过一定时间后,允许部分请求访问,检测服务是否恢复正常。
  • 实现:通过滑动窗口算法来计算连续错误的次数和比率。如果在一个时间窗口内,错误率超过了设定的阈值,断路器就会转到开启状态。

2. 降级(Fallback)

  • 原理:当 Hystrix 断开一个服务时,它可以自动调用一个备用服务或返回一个预设的错误信息。这样用户或其他服务就不会受到影响。
  • 实现:开发者需要为每个 Hystrix 命令提供一个 fallback 方法,当断路器开启或者是命令执行出现错误时,就会自动调用这个 fallback 方法。

3. Hystrix 命令(Hystrix Command)

  • 原理:Hystrix 使用命令模式来封装每一个远程调用或者可能会失败的操作。每个 Hystrix 命令在一个独立的线程中执行,这样即使命令执行失败或者超时,也不会影响主线程和其他操作。
  • 实现:Hystrix 命令是通过继承 HystrixCommand 类或者 HystrixObservableCommand 类来实现的。

源码和实现

这里提供一个简单的示例,通过源码的方式来展示 Hystrix 如何实现以上原理:

public class CommandHelloWorld extends HystrixCommand<String> {

    private final String name;

    public CommandHelloWorld(String name) {
        super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
        this.name = name;
    }

    @Override
    protected String run() {
        // 这里是可能会失败的操作
        return "Hello " + name + "!";
    }

    @Override
    protected String getFallback() {
        // 这里是 fallback 方法,当 run 方法失败时,会自动调用这个方法
        return "Fallback Hello " + name + "!";
    }
}

在这个例子中:

  • CommandHelloWorld 类继承自 HystrixCommand 类,并重写了 run()getFallback() 方法。
  • run() 方法中包含了可能会失败的操作。
  • getFallback() 方法是一个备用方案,当 run() 方法失败时,会自动调用这个方法。

Hystrix 的源码实现是基于 Java 语言的,并且其代码库是开源的,你可以在 Hystrix 的 GitHub 仓库 中找到源码和更多的细节。在源码中,你可以详细地了解 Hystrix 的工作原理和实现细节。 在微服务架构中,服务之间的调用是非常常见的。然而,任何一个服务都有可能失败或者出现延迟,这就需要有一个机制来保护服务消费者免受这些问题的影响。Hystrix 提供了这样的机制。下面是一个具体的示例,说明如何在一个简单的 Spring Boot 微服务中使用 Hystrix。

4. 场景描述

假设我们有一个微服务,它需要从另一个微服务获取一些信息。我们将使用 Hystrix 来保护这个调用,确保即使远程服务出现问题,我们的服务也能继续运行。

步骤 1:添加依赖

首先,我们需要在项目的 pom.xml 文件中添加 Spring Cloud Starter Hystrix 的依赖。因为 Hystrix 已经进入维护模式,我们还需要添加 Spring Cloud 的依赖管理。

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    <!-- 其他依赖 -->
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2020.0.3</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

步骤 2:启用 Hystrix

在主应用类上添加 @EnableCircuitBreaker@EnableHystrix 注解来启用 Hystrix。

@SpringBootApplication
@EnableHystrix
public class Application {

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

步骤 3:创建一个服务

假设我们要调用的远程服务提供了一个 API,可以根据 ID 获取用户的信息。我们将创建一个服务来调用这个 API,并使用 Hystrix 来保护这个调用。

@Service
public class UserService {

    @HystrixCommand(fallbackMethod = "defaultUser")
    public String getUser(String id) {
        // 这里是一个模拟的远程调用
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.getForObject("http://example.com/users/" + id, String.class);
    }

    public String defaultUser(String id) {
        return "Default User";
    }
}

在这个例子中,getUser 方法用来调用远程服务的 API。我们使用 @HystrixCommand 注解来告诉 Hystrix 需要保护这个方法,并提供了一个 fallbackMethod 参数,指定了当调用失败时需要调用的备用方法。

步骤 4:测试服务

最后,我们可以创建一个 REST 控制器来测试我们的服务。

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/users/{id}")
    public String getUser(@PathVariable String id) {
        return userService.getUser(id);
    }
}

当我们通过 /users/{id} 端点来获取用户信息时,如果远程服务正常,我们将得到远程服务返回的用户信息;如果远程服务出现问题,Hystrix 会自动调用 defaultUser 方法,我们将得到 "Default User" 这个结果,从而保证了我们的服务的可用性。

5.Hystrix 和 Sentinel简单对比

Hystrix 和 Sentinel 都是流行的微服务容错框架,它们都可以帮助开发者增加服务的可靠性和可用性。然而,两者之间存在一些区别,我将通过以下几个方面来进行比较。

1. 来源和维护

  • Hystrix:
    • 由 Netflix 开发。
    • 已经停止了新的特性开发,进入维护模式。
  • Sentinel:
    • 由阿里巴巴开发。
    • 活跃的社区和持续的更新。

2. 功能

  • Hystrix:
    • 主要专注于延迟和容错保护,提供断路器、降级和隔离机制。
    • 提供了较为简单的实时监控功能。
  • Sentinel:
    • 不仅提供延迟和容错保护,还包括流量控制、系统负载保护等功能。
    • 提供更丰富的实时监控和控制台。

3. 配置和扩展性

  • Hystrix:
    • 配置相对简单,扩展性较差。
    • 主要通过代码注解来配置规则。
  • Sentinel:
    • 提供更丰富的配置选项和更好的扩展性。
    • 支持热更新的规则配置。

4. 性能

  • Hystrix:
    • 有一定的性能开销,尤其在高并发的情况下。
  • Sentinel:
    • 设计上更注重性能,性能开销较小。

5. 社区和生态

  • Hystrix:
    • 社区不再活跃,文档和资料相对有限。
  • Sentinel:
    • 活跃的社区,持续的更新,更丰富的资料和文档。

6. 实时监控

  • Hystrix:
    • 提供了基本的监控功能,但较为简单。
  • Sentinel:
    • 提供更复杂、完整的实时监控功能和可视化控制台。

总结

  • 选择 Hystrix 的理由:
    • 如果你的项目已经在使用,并且没有遇到明显的限制或问题,可以继续使用。
    • 对 Netflix 生态有更好的集成。
  • 选择 Sentinel 的理由:
    • 需要更丰富的功能,如流量控制和系统负载保护等。
    • 需要更好的性能和扩展性。
    • 希望得到更好的社区支持和更丰富的文档。

通过一步步分析,可以看出 Hystrix 和 Sentinel 在功能、性能、扩展性等方面有一些区别,可以根据项目的具体需求和场景来选择更适合的方案。

转载自:https://juejin.cn/post/7283766466084159524
评论
请登录