如果存在大量的已有系统,新系统需要调用已有系统。某些已有系统会出现网络延迟甚至中断,或者需要定期重启。这时可以在新系统中使用服务降级/熔断,实现快速失败Fast Fail。当已有系统恢复工作,新系统再重新恢复正常调用。
采用服务熔断,可以实现快速失败,避免连续失败重试。
服务熔断并没有提高并发处理的能力,而是通过快速失败,避免故障范围的扩大和传递。
另一种方式是改成异步调用,包括异步重试。
是否使用服务熔断?
首先是被调用的服务B可能出现故障。其次是业务上允许熔断处理。进而考虑在服务A上使用服务熔断。
另一方面,从微服务的角度,任何一个微服务都有可能出现故障。从这个角度,服务熔断又是普遍有用的。或者说,需要普遍考虑的,服务A调用任何一个服务,如果对方出现故障,应该如何处理。
如果考虑使用熔断,需要考虑熔断策略和恢复策略。
如果已有系统的并发处理能力有限,可以在新系统中使用服务限流。当出现高并发请求时,对调用的线程数进行限制,比如线程隔离(该调用使用单独的线程池),或者信号量隔离(该调用共享web容器线程池,但是有最大限制)等,避免对已有系统的冲击。
如果对于已有系统只是读取信息,而且相同的请求参数,会得到相同的返回。则可以在调用方使用请求缓存;如果在一定时间段后返回可能更新,则可以设置请求缓存的过期时间。
适用于可能出现大量并发的相同的请求参数的场景。
服务熔断:服务A调用B,因为B发生故障,服务A暂停调用B,直至B恢复。
服务降级:服务A的整体负荷过高,选择暂停非核心业务/接口,直至负荷降低。
信号量隔离
@HystrixCommand(
commandKey = "createOrder",
commandProperties = {
@HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE"),
@HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests", value = "6")
},
fallbackMethod = "createOrderFallbackMethod4semaphore"
)
线程池隔离
@HystrixCommand(
commandKey = "createOrder",
commandProperties = {
@HystrixProperty(name = "execution.isolation.strategy", value = "THREAD")
},
threadPoolKey = "createOrderThreadPool",
threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "3"),
@HystrixProperty(name = "maxQueueSize", value = "5"),
@HystrixProperty(name = "queueSizeRejectionThreshold", value = "7")
},
fallbackMethod = "createOrderFallbackMethod4Thread"
)
超时熔断
@HystrixCommand(
commandKey = "createOrder",
commandProperties = {
@HystrixProperty(name = "execution.timeout.enabled", value = "true"),
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"),
},
fallbackMethod = "createOrderFallbackMethod4Timeout"
)