如果存在大量的已有系统,新系统需要调用已有系统。某些已有系统会出现网络延迟甚至中断,或者需要定期重启。这时可以在新系统中使用服务降级/熔断,实现快速失败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"
)