使用Hystrix 、Feign 和 Ribbon构建微服务-spring cloud 入门教程
可能你读过一些关于 Hystrix 的文章,你知道它的用途是什么。今天我想向您展示一个具体如何使用它的示例,它使您能够与来自 Netflix OSS 堆栈的其他工具(如 Feign 和 Ribbon)结合使用。我假设您对微服务、负载平衡、服务发现等主题有基本的了解。如果没有,我建议您阅读一些关于它的文章,例如,我对微服务架构的简短介绍可在此处获得:使用 Zuul、Ribbon、Feign、Eureka 和 Sleuth、Zipkin 创建简单spring cloud微服务用例-spring cloud 入门教程。那篇文章中使用的代码示例有助于你快速了解本文。
让我们看一些使用回退和断路器的场景。我们有客户服务,它从Account Service调用 API 方法。有两个正在运行的Account Service实例。对Account Service实例的请求由 Ribbon 客户端 50/50 进行负载平衡。
场景一
对 Feign 客户端 (1) 禁用了 Hystrix,对本地实例 (2) 和其他实例 (3) 上的 Ribbon 客户端禁用了自动重试机制。功能区读取超时比请求最大处理时间 (4) 短。这种情况也发生在没有 Hystrix 的默认 Spring Cloud 配置中。当您调用客户测试方法时,您有时会收到完整响应,有时会收到 500 HTTP 错误代码 (50/50)。
ribbon:
eureka:
enabled: true
MaxAutoRetries: 0 #(2)
MaxAutoRetriesNextServer: 0 #(3)
ReadTimeout: 1000 #(4)
feign:
hystrix:
enabled: false #(1)
场景二
对于 Feign 客户端 (1) 仍然禁用 Hystrix,在本地实例 (2) 上为 Ribbon 客户端禁用自动重试机制,但在其他实例上启用一次 (3)。您总是会收到完整的回复。如果您的请求由具有延迟响应的实例接收,它会在 1 秒后超时,然后 Ribbon 调用另一个实例 - 在这种情况下不会延迟。您可以随时更改MaxAutoRetries
为正值,但在该示例中没有给我们任何内容。
ribbon:
eureka:
enabled: true
MaxAutoRetries: 0 #(2)
MaxAutoRetriesNextServer: 1 #(3)
ReadTimeout: 1000 #(4)
feign:
hystrix:
enabled: false #(1)
场景3
这里不是一个非常优雅的问题解决方案。我们设置ReadTimeout
的值大于 API 方法中的延迟(5000 毫秒)。
ribbon:
eureka:
enabled: true
MaxAutoRetries: 0
MaxAutoRetriesNextServer: 0
ReadTimeout: 10000
feign:
hystrix:
enabled: false
一般来说,场景 2和3 的配置是正确的,你总是得到完整的响应。但是在某些情况下,您会等待超过 1 秒(场景 2)或超过 5 秒(场景 3),并且延迟实例收到来自 Ribbon 客户端的 50% 请求。但幸运的是,有 Hystrix——断路器。
场景 4
让我们通过删除feign
属性来启用 Hystrix 。Ribbon 客户端 (1) 没有自动重试,其读取超时 (2) 大于 Hystrix 的超时 (3)。1000ms 也是 HystrixtimeoutInMilliseconds
属性的默认值。Hystrix 断路器和回退将适用于帐户服务的延迟实例。对于一些第一次请求,您会收到来自 Hystrix 的回退响应。然后延迟的实例将从请求中切断,其中大部分将被定向到未延迟的实例。
ribbon:
eureka:
enabled: true
MaxAutoRetries: 0 #(1)
MaxAutoRetriesNextServer: 0
ReadTimeout: 2000 #(2)
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000 #(3)
场景5
这个场景是场景 4的更高级的开发。现在 Ribbon 超时 (2) 低于 Hystrix 超时 (3),并且还为本地实例和其他实例 (4) 启用了自动重试机制 (1)。结果与场景 2和3 相同——您收到完整的响应,但启用了 Hystrix 并且它从未来的请求中切断了延迟的实例。
ribbon:
eureka:
enabled: true
MaxAutoRetries: 3 #(1)
MaxAutoRetriesNextServer: 1 #(4)
ReadTimeout: 1000 #(2)
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 10000 #(3)
我可以想象其他一些场景。但这个想法只是在修改application.yml
.
Hystrix
让我们仔细看看场景 4 中描述的标准 Hystrix 断路器和用法。要在 Spring Boot 应用程序中启用 Hystrix,您必须将以下依赖项添加到pom.xml
. 第二步是向@EnableCircuitBreaker
主应用程序类添加注释,@EnableHystrixDashboard
如果您希望 UI 仪表板可用。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
Hystrix 回退设置在客户服务内部的 Feign 客户端上。
@FeignClient(value = "account-service", fallback = AccountFallback.class)
public interface AccountClient {
@RequestMapping(method = RequestMethod.GET, value = "/accounts/customer/{customerId}")
List<Account> getAccounts(@PathVariable("customerId") Integer customerId);
}
回退实现非常简单。在这种情况下,我只返回一个空列表,而不是从帐户服务收到的客户帐户列表。
@Component
public class AccountFallback implements AccountClient {
@Override
public List<Account> getAccounts(Integer customerId) {
List<Account> acc = new ArrayList<Account>();
return acc;
}
}
现在,我们可以进行一些测试。让我们启动发现服务,不同端口上的两个帐户服务实例(启动期间的-DPORT VM 参数)和客户服务。测试的端点是/customers/{id}。还有 JUnit 测试类,它向客户服务模块中提供的此端点发送多个请求pl.piomin.microservices.customer.ApiTest
。
@RequestMapping("/customers/{id}")
public Customer findById(@PathVariable("id") Integer id) {
logger.info(String.format("Customer.findById(%s)", id));
Customer customer = customers.stream().filter(it -> it.getId().intValue()==id.intValue()).findFirst().get();
List<Account> accounts = accountClient.getAccounts(id);
customer.setAccounts(accounts);
return customer;
}
我在account-service主类上启用了 Hystrix Dashboard 。如果您想访问它,请从您的 Web 浏览器调用http://localhost:2222/hystrix地址,然后从客户服务 http://localhost:3333/hystrix.stream键入 Hystrix 的流地址。当我运行测试向客户服务发送 1000 个请求时;其中大约 20 (2%) 个转发到延迟的帐户服务实例,其余为未延迟的实例。该测试期间的 Hystrix 仪表板如下所示。有关更高级的 Hystrix 配置,请参阅其可用文档:Hystrix 简介-spring cloud 入门教程 Hystrix 原理深入分析-spring cloud 入门教程
使用 Zuul、Ribbon、Feign、Eureka 和 Sleuth、Zipkin 创建简单spring cloud微服务用例-spring cloud 入门教程
微服务集成SPRING CLOUD SLEUTH、ELK 和 ZIPKIN 进行监控-spring cloud 入门教程
使用Hystrix 、Feign 和 Ribbon构建微服务-spring cloud 入门教程
使用 Spring Boot Admin 监控微服务-spring cloud 入门教程