故障和带有Feign的断路器模式
默认情况下,Feign客户端与Ribbon和Hystrix集成在一起。这意味着,如果开发人员愿意的话,可以在使用该库时应用不同的方法来处理系统中的延迟和超时。第一种方法是Ribbon客户端提供的连接重试机制:第二种方法是断路器模式和Hystrix项目下可用的回退实现,这已在本章前面的章节中讨论过。
重试与Ribbon的连接
使用Feign库时,默认情况下会为应用程序启用Hystrix。 这意味着如果开发人员不想使用它,则应在配置设置中禁用它。为了使用Ribbon测试重试机制,建议禁用Hystrix。为了启用Feign的连接重试,只需设置两个配置属性-MaxAutoRetries和MaxAutoRetriesNextServer.在这种情况下,重要的设置也是ReadTimeout和ConnectTimeout。所有这些都可以在application.yml文件中覆盖。以下是最重要的Ribbon设置列表。
口MaxAutoRetries: 这是同一服务器或服务实例上的最大重试次数。第一次尝试被排除在此计数之外。
口MaxAutoRetriesNextServer: 这是要重试的下一个服务器或服务实例的最大数量,不包括第一个服务器。
口OkToRetryOnAllOperations:这表示可以为该客户端重试所有操作。
口ConnectTimeout:这是等待与服务器或服务实例建立连接的最长时间。
口ReadTimeout:这是建立连接后等待服务器响应的最长时间。
现在假设已经有两个目标服务的实例。与第一个服务实例的连接已经建立,但是响应速度太慢,发生超时。客户端将根据MaxAutoRetries=1属性对该服务实例执行一次重试。如果仍未成功,则尝试连接该服务的第二个可用实例。根据MaxAutoRetriesNextServer =2属性中设置的内容,在出现失败时,此操作将重复两次。如果上述描述的机制最终不成功,则会因为超时而返回到外部客户端。在这种情况下,即使超过4秒钟的情况也可能发生。看看以下配置。
ribbon:
eureka:
enabled: true
MaxAutoRetries: 1
MaxAutoRetriesNextServer: 2
ConnectTimeout: 500
ReadTimeout: 1000
feign:
hystrix:
enabled: false
该解决方案是为基于微服务的环境实现的标准重试机制。开发人员还可以了解一些与Ribbon的超时和重试的不同配置设置相关的其他方案。所以需要将这种机制与Hytrix的断路器一起使用。但是,开发人员必须记住,ribbonReadTimeout属性的值应该低于Hystrix的execution.isolation.thread.timeoutInMillseconds属性的值。
建议开发人员测试上述配置设置,并把它作为一项练习。可以使用先前介绍的Hoverly JUnit规则来模拟服务实例的延迟和存根。
Hystrix 对Feign的支持
如前文所述,在使用Feign库时,默认情况下会为应用程序启用Hystrix, 但这仅适用于旧版本的Spring Cloud. 根据最新版Spring Cloud 的说明文档,开发人员应该将feign.hystrix.cnabled属性设置为true,这会强制Feign用断路器包裹所有方法。
➊注意:
在Spring Cloud Dalston发布之前,如果Hytrix在类路径上,则Feign默认会将所有方法包裹在断路器中。
在Spring Cloud Dalston版本中更改了此默认行为,转而采用了选择性加入的方法。
将Hytrix与Feign 客户端一起使用时, 要提供以前在@HystrixCommand中使用@HystrixProperty设置的配置属性,最简单的方法是通过aplication.yml文件。以下是之前提供的示例的等效配置。
hystrix:
command:
default:
circuitBreaker:
requestVolumeThreshold: 10
errorThresholdPercentage: 30
sleepWi ndowInMilliseconds: 10000
execution:
isolation:
thread:
timeout InMilliseconds: 1000
metrics:
rollingstats:
timeInMilliseconds: 10000
Feign支持回退表示法。要为给定的@FeignClient启用回退机制,应该使用提供回退实现的类名设置fllback属性。该实现类应该定义为Spring Bean。
@FeignClient (name二"customer-service", fallback =
CustomerClientFallback.class)
public interface Customerclient {
@CachePut ("customers")
@GetMapping ("/wi thAccounts/ { customerId}")
Customer findByIdWi thAccounts (@PathVariable ("customerId") Long
customerId) ;
}
回退实现基于缓存,并且将实现使用@FeignClient注解的接口。
@Component
public class Custome rClientFallback implements CustomerClient {
@Autowired
CacheManager cacheManager;
@override
public Customer findByIdWithAccountsFallback (Long customerId) (
ValueWrapper W =
cacheManager .getCache ("customers") .get (customerId);
if (W != null) {
return (Customer) w.get();
} else {
return new Customer() ;
}
}
}
或者,也可以考虑实现FllbackFactory 类。这种方法有一个很大的优势,它使开发人员可以访问导致回退触发的原因。要为Feign声明FallbackFactory 类,只需使用@FeignClient中的fallbackFactory属性。
@FeignClient (name - "account-service", fallbackFactory
AccountClientFallbackFactory.class)
public interface AccountClient {
@CachePut
@GetMapping ("/customer/ (customerId)")
List<Account> findByCustomer (PathVariable ("customerId") Long
customerId) ;
}
自定义FallbackFactory 类需要实现一个FallbackFactory 接口,该接口将声明一个必须被覆盖的T create (Throwable cause)方法。
@Component
public class AccountClientFallbackFactory implements
FallbackFactory<AccountClient> {
@Autowired
CacheManager cacheManager;
@override
public AccountClient create (Throwable cause) {
return new AccountClient() {
@override
List<Account> findByCustomer (Long customerId) (
ValueWrapper W =
cacheManager .getCache ("accounts") .get (customerId) ;
if (w !m null) (
return (List<Account>) w.get():
} else
return new Customer() :
小结
如果开发人员常使用自动配置的客户端进行服务间通信,则可能不了解本章中介绍的配置设置或工具。但是,我们认为开发人员应该对这些高级机制有所了解,即使它们可以在后台运行或有现成可用的东西。本章尝试通过--些简单示例演示了它们的工作原理,使开发人员可以更详细地了解诸如负载均衡器、重试、回退或断路器之类的主题。阅读本章后,开发人员应该能够自定义Ribbon、Hystrix 或Feign客户端,以满足与微服务之间的通信相关的需求,无论是小规模还是大规模需求。开发人员还应该了解在系统中使用它们的时间和原因。到本章为止,基于微服务架构中核心元素的讨论就到此结束了。
接下来,我们将把目光放到系统之外,讨论一个更重要的组件: 网关。它可以从外部客户端隐藏系统的复杂性。
总结
因为文章包含的内容实在是太多了,就不给大家做过多的介绍了,需要这份文档来学习的小伙伴,可以转发此文关注小编。
扫码来获取就可以了!