微服务架构带来许多优势,例如:
- 易于部署
- 有效缩放
- 技术采用
但是,在实现它时,我们应该考虑一下整体架构中没有的东西。
每个微服务应专注于其特定任务。 因此,在许多情况下,一个以上的微服务可以协同工作来完成一项工作。 但是,当其中之一发生故障时会发生什么?
众所周知,依赖关系中的故障不应导致整个应用程序崩溃。 我们应该以这样一种方式设计系统,即每个微服务可以在这种情况下采取纠正措施。 但是,我们如何实现这一目标?
断路器模式
- 当您的某个依赖项发生故障时,请给它一些时间来恢复,并在这段时间内执行后备策略。
- 定期检查失败的依赖项是否可用。 当您看到它已经启动并正在运行时,您可以打开它的流量。
Netflix Hystrix(Netflix OSS的另一个很棒的库)为我们实现断路器模式做出了所有繁重的工作。 我们只需要:
- 将所有对外部系统的调用包装在HystrixCommand或HystrixObservableCommand中
- 超时时间超出我们的阈值
- 启用断路器
- 当对外部系统的请求失败时,执行回退功能。
样例应用
我已经用Netflix Hystrix,Netflix Eureka,Spring Framework和REDIS实现了一个示例应用程序。 在此应用程序中:
- 我有一个Spring Boot模块(主模块),该模块具有一个Sample端点,客户端可以在其中发送请求。 它还会使用Eureka自动发现服务(已注册到服务注册表)。
- 我有一个用Eureka Server实现的服务注册表
- 我还有一个包含示例REST端点的Spring Boot模块。 启动时,它将自动向Eureka注册到服务注册表
- 我使用REDIS作为外部缓存系统。
当主模块收到请求时,它将调用REST端点(通过Eureka @FeignClient),并将响应返回给客户端。
后备政策
- 当服务不可用时,处理程序将查找缓存(REDIS)
- 如果高速缓存也不处于活动状态,则返回null。

下面,我给出了实现该体系结构的源代码的链接,但在深入研究之前,如果您没有经验,我建议您看一下有关Netflix Eureka的故事。
源代码中的模块
- sample-dto:包含示例DTO类的共享模块
- eureka-server:服务注册表。
- eureka-client:包含示例REST端点的示例应用程序。
- feign-client:与Eureka Service注册表集成的主应用程序,使用HystrixCommands调用外部系统,并将REDIS用作外部缓存系统。
注意:在运行代码之前,请确保您的本地主机中具有REDIS实例,其端口为6379。
配置命令属性
我们可以从代码或bootstrap.yml / bootstrap.properties文件中自定义@HystrixCommand。 如果选择使用@HystrixCommand,则可以设置诸如commandPropeties
或commandPropeties
属性。
@HystrixCommand(
fallbackMethod = “ readUserFromDatabase” ,
commandKey =“ ... ” ,
threadPoolKey =“ ...”,
commandProperties = {
@HystrixProperty(name = “ execution.isolation.thread.timeoutInMilliseconds” ,value = “ 100” )
})
public UserEntity getUserFromCache(String username){
...
}
当然,在代码中进行这样的配置不是最好的方法,因为当这些值更改时,需要重新编译和重新部署。 最好将它们放在.properties / .yml文件中,以便我们可以为不同的配置文件/环境使用不同的值。
从.yml / .properties文件进行此类配置时,我们应该注意的事情是使用提供给@HystrixCommand的命令键,如下所示:
hystrix.command。 .execution.isolation.thread.timeoutInMilliseconds = 100
github的:https://github.com/fdanismaz/java/tree/master/hystrix