转载

从0开始用SpringCloud搭建微服务系统【四】

基本的容错模式有:

  • 主动超时:
  • 限流:限制最大并发数
  • 熔断:错误数达到阈值时,类似保险丝熔断
  • 隔离:隔离不同的依赖调用或者隔离不同的线程
  • 降级:服务降低

容错理念:

  • 凡是依赖都可能会失败
  • 凡是资源都有限制
    • CPU/Memory/Threads/Queue
  • 网络并不可靠
  • 延迟是应用稳定性杀手

Netflix Hystrix

Hystrix实现了 超时机制和断路器模式。

Hystrix是Netflix开源的一个类库,用于隔离远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性与容错性。主要有以下几点功能:

  • 为系统提供保护机制。在依赖的服务出现高延迟或失败时,为系统提供保护和控制。
  • 防止雪崩。
  • 包裹请求:使用HystrixCommand(或HystrixObservableCommand)包裹对依赖的调用逻辑,每个命令在独立线程中运行。
  • 跳闸机制:当某服务失败率达到一定的阈值时,Hystrix可以自动跳闸,停止请求该服务一段时间。
  • 资源隔离:Hystrix为每个请求都的依赖都维护了一个小型线程池,如果该线程池已满,发往该依赖的请求就被立即拒绝,而不是排队等候,从而加速失败判定。防止级联失败。
  • 快速失败:Fail Fast。同时能快速恢复。侧重点是:(不去真正的请求服务,发生异常再返回),而是直接失败。
  • 监控:Hystrix可以实时监控运行指标和配置的变化,提供近实时的监控、报警、运维控制。
  • 回退机制:fallback,当请求失败、超时、被拒绝,或当断路器被打开时,执行回退逻辑。回退逻辑我们自定义,提供优雅的服务降级。
  • 自我修复:断路器打开一段时间后,会自动进入“半开”状态,可以进行打开,关闭,半开状态的转换。

Hystrix设计原理

Hystrix的工作原理可以可以参考官网的 How it Works 。如果要看中文版,可以参考: Hystrix工作原理 。

信号量隔离与线程隔离

默认情况下hystrix使用线程池控制请求隔离

线程池隔离技术,是用 Hystrix 自己的线程去执行调用;而信号量隔离技术,是直接让 tomcat 线程去调用依赖服务。信号量隔离,只是一道关卡,信号量有多少,就允许多少个 tomcat 线程通过它,然后去执行。

信号量隔离主要维护的是Tomcat的线程,不需要内部线程池,更加轻量级。

优点 不足 适用
信号量隔离 轻量,无额外开销 不支持任务排队和主动超时
不支持异步调用
受信客户
高扇出(网关)
高频高速调用(cache)
线程池隔离 支持排队和超时
支持异步调用
线程调用会产生额外的开销 不受信客户
有限扇出

使用Hystrix

独立使用

独立使用Hystrix可以参考 How To Use 。

如果想要中文,可以参考: Hystrix都停更了,我为什么还要学?

与Resttemplate整合

引入依赖 spring-cloud-starter-netflix-hystrix

在Service中:

@Service
public class GreetingService{
    @HystrixCommand(fallbackMethod = "defaultGreeting")
    public String getGreeting(String username){
        return new RestTemplate()
          .getForObject("http://localhost:9090/greeting/{username}", 
          String.class, username);
    }
  
    private String defaultGreeting(String username){
        return "Hello User!";
    }
}

在Application中:

@SpringBootApplication
@EnableCircuitBreaker
public class RestConsumerApplication{
    public static void main(String[] args){
        SpringApplication.run(RestConsumerApplication.class, args);
    }
}

@EnableCircuitBreaker注释将扫描类路径以查找任何兼容的Circuit Breaker实现。

与Feign整合

在集成Feign的基础上修改如下:

@FeignClient(name = "statistics-service", fallback = StatisticsServiceClientFallback.class)
public interface StatisticsServiceClient{
	@RequestMapping(method = RequestMethod.PUT, value = "/statistics/{accountName}")
	void updateStatistics(@PathVariable("accountName")String accountName, Account account);
}

@Component
@Slf4j
public class StatisticsServiceClientFallbackimplements StatisticsServiceClient{
    @Override
    public void updateStatistics(String accountName, Account account){
        log.error("Error during update statistics for account: {}", accountName);
    }
}

然后在配置文件中打开:

feign.hystrix.enabled=true

使用fallbackFactory检查具体错误

在一些场景中,简单的触发在 FeignClient 加入 Fallback 属性即可,而另外有一些场景需要访问导致回退触发的原因,那么这个时候可以在 FeignClient 中加入 FallbackFactory 属性即可;

  1. 定义一个类,实现FallbackFactory
@Component
public class WebErrorimplements FallbackFactory<ConsumerApi>{

	@Override
	public ConsumerApi create(Throwable cause){

		return new ConsumerApi() {
			@Override
			public String getById(Integer id){
        //针对不同异常返回响应
				if(cause instanceof InternalServerError) {
					System.out.println("InternalServerError");
					return "远程服务报错";
				}else if(cause instanceof RuntimeException) {
					return "请求时异常:" + cause;
				}else {
					return "都算不上";
				}
				return null;
			}
		};
	}

}
  1. @Feign中的使用 @FeignClient(name = "statistics-service", fallbackFactory = WebError.class)

主要配置项

配置项(前缀hystrix.command.*.) 含义
execution.isolation.strategy 线程“THREAD”或信号量“SEMAPHORE”隔离(Default: THREAD)
execution.isolation.thread.timeoutInMilliseconds run()方法执行超时时间(Default: 1000)
execution.isolation.semaphore.maxConcurrentRequests 信号量隔离最大并发数(Default:10)
circuitBreaker.errorThresholdPercentage 熔断的错误百分比阀值(Default:50)
circuitBreaker.requestVolumeThreshold 断路器生效必须满足的流量阀值(Default:20)
circuitBreaker.sleepWindowInMilliseconds 熔断后重置断路器的时间间隔(Default:5000)
circuitBreaker.forceOpen 设true表示强制熔断器进入打开状态(Default: false)
circuitBreaker.forceClosed 设true表示强制熔断器进入关闭状态(Default: false)
配置项(前缀hystrix.threadpool.*.) 含义
coreSize 使用线程池时的最大并发请求(Default: 10)
maxQueueSize 最大LinkedBlockingQueue大小,-1表示用SynchronousQueue(Default:-1)
default.queueSizeRejectionThreshold 队列大小阀值,超过则拒绝(Default:5)

Hystrix Dashboard

Hystrix有一个不错的可选功能是能够在仪表板上监视其状态。 为了启用它,我们将 spring-cloud-starter-hystrix-dashboardspring-boot-starter-actuator 放入项目的pom.xml中。

然后添加 @EnableHystrixDashboard 注解。

启动应用程序后,将浏览器指向 http://localhost:8080/hystrix,输入“ hystrix.stream”的指标URL并开始监视。

原文  http://webfuse.cn/2020/04/27/从0开始用SpringCloud搭建微服务系统【四】/
正文到此结束
Loading...