服务的雪崩效应及解决方案【hystrix】

1、什么是服务的雪崩效应?

在微服务架构中,一个请求需要调用多个服务是非常常见的。如客户端访问A服务,而A服务需要调用B服务,B服务需要调用C服务,由于网络原因或者自身的原因,如果B服务或者C服务不能及时响应,A服务将处于阻塞状态,直到B服务C服务响应。此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,造成连锁反应,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。

 

2、雪崩效应解决思路

一般情况对于服务依赖的保护主要有3中解决方案:

(1)熔断模式:这种模式主要是参考电路熔断,如果一条线路电压过高,保险丝会熔断,防止火灾。放到我们的系统中,如果某个目标服务调用慢或者有大量超时,此时,熔断该服务的调用,对于后续调用请求,不在继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。使用超时机制,服务降级,所谓的服务降级就是:服务调用某个接口时,如果发生错误或超时,不让其调用该接口,而是调用本地fallback,fallback方法可以直接返回一个固定值。

 

(2)隔离模式:这种模式就像对系统请求按类型划分成一个个小岛的一样,当某个小岛被火少光了,不会影响到其他的小岛。例如可以对不同类型的请求使用线程池来资源隔离,每种类型的请求互不影响,如果一种类型的请求线程资源耗尽,则对后续的该类型请求直接返回,不再调用后续资源。这种模式使用场景非常多,例如将一个服务拆开,对于重要的服务使用单独服务器来部署,再或者公司最近推广的多中心。

 

(3)限流模式:上述的熔断模式和隔离模式都属于出错后的容错处理机制,而限流模式则可以称为预防模式。限流模式主要是提前对各个类型的请求设置最高的QPS阈值,若高于设置的阈值则对该请求直接返回,不再调用后续资源。这种模式不能解决服务依赖的问题,只能解决系统整体资源分配问题,因为没有被限流的请求依然有可能造成雪崩效应。

 

3、Hystrix作用

1.断路器机制

断路器很好理解, 当Hystrix Command请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open). 这时所有请求会直接失败不会发送到后端服务. 断路器保持在开路状态一段时间后(默认5秒), 自动切换到半开路状态(HALF-OPEN). 这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回闭路状态(CLOSED), 否则重新切换到开路状态(OPEN). Hystrix的断路器就像我们家庭电路中的保险丝, 一旦后端服务不可用, 断路器会直接切断请求链, 避免发送大量无效请求影响系统吞吐量, 并且断路器有自我检测并恢复的能力.

2.Fallback

Fallback相当于是降级操作. 对于查询操作, 我们可以实现一个fallback方法, 当请求后端服务出现异常的时候, 可以使用fallback方法返回的值. fallback方法的返回值一般是设置的默认值或者来自缓存.

3.资源隔离

在Hystrix中, 主要通过线程池来实现资源隔离. 通常在使用的时候我们会根据调用的远程服务划分出多个线程池. 例如调用产品服务的Command放入A线程池, 调用账户服务的Command放入B线程池. 这样做的主要优点是运行环境被隔离开了. 这样就算调用服务的代码存在bug或者由于其他原因导致自己所在线程池被耗尽时, 不会对系统的其他服务造成影响. 但是带来的代价就是维护多个线程池会对系统带来额外的性能开销. 如果是对性能有严格要求而且确信自己调用服务的客户端代码不会出问题的话, 可以使用Hystrix的信号模式(Semaphores)来隔离资源.

 

3、什么是服务降级

所有的RPC技术里面服务降级是一个最为重要的话题,所谓的降级指的是当服务的提供方不可使用的时候,程序不会出现异常,而会出现本地的操作调用fallback

 

4、断路器hystrix使用方法

需要注意的是,配置hystrix端应为调用服务的发起者,如A调用B,为了防止B出现异常或网络延迟响应慢,则A开启断路保护。

针对rest和feign,配置方式有所不同。

Rest使用断路器

1、pom.xml

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

2、Rest方式使用断路器

/*Rest请求方式接口改造,在restTemplate发起http调用方法后声明fallback方法,并配置注解@HystrixCommand*/
@HystrixCommand(fallbackMethod = "orderError")
public List<String> getOrderUserAll() {
return restTemplate.getForObject("http://service-member/getMemberAll", List.class);
}

public List<String> orderError() {
	List<String> listUser = new ArrayList<String>();
	listUser.add("not orderUser list");
	return listUser;
}

在方法启动类上加入@EnableHystrix注解

//启动方式
@EnableEurekaClient
@EnableHystrix
@SpringBootApplication
public class OrderApp {

	public static void main(String[] args) {
		SpringApplication.run(OrderApp.class, args);
	}

	@Bean
	@LoadBalanced
	RestTemplate restTemplate() {
		return new RestTemplate();
	}

}

注解说明:

@HystrixCommand 作用:服务发生错误,回调方法。

@EnableHystrix 启动断路器

 

2、Fegin使用断路器

①在feign接口类中加入注解@FeignClient(fallback=该Feign实现类.class)

@FeignClient(value="service-member",fallback=MemberFeignService.class)
public interface MemberFeign {
	@RequestMapping("/getMemberAll")
	public List<String> getOrderByUserList();
}

②书写Feign实现类,千万别忘了加入@Component注解

@Component
public class MemberFeignService implements MemberFeign {

	public List<String> getOrderByUserList() {
		List<String> listUser = new ArrayList<String>();
		listUser.add("not orderUser list");
		return listUser;
	}
}

③配置文件application.yml中新增,表示feign使用断路器并设置超时时间

feign:
   hystrix:
     enabled: true
###超时时间
hystrix:
   command: 
     default: 
       execution: 
        isolation:
         thread: 
          timeoutInMilliseconds: 4000

同样,在feign启动类App.java中加入@EnableHystrix注解。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值