1.服务雪崩效应:是一种因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程。
1.A为服务提供者, B为A的服务调用者, C和D是B的服务调用者. 当A的不可用,引起B的不可用,并将不可用逐渐放大C和D时, 服务雪崩就形成了。
2.雪崩原因:
1) 服务提供者不可用
a.硬件故障
a1.硬件损坏造成的服务器主机宕机
a2.网络硬件故障造成的服务提供者的不可访问
b.程序Bug
c.缓存击穿:缓存应用重启, 所有缓存被清空时,以及短时间内大量缓存失效时. 大量的缓存不命中, 使请求直击后端,造成服务提供者超负荷运行,引起服务不可用
d.用户大量请求:在秒杀和大促开始前,如果准备不充分,用户发起大量请求造成服务提供者的不可用
2) 重试加大流量
a.用户重试:用户由于忍受不了界面上长时间的等待,而不断刷新页面甚至提交表单
b.代码逻辑重试:服务调用端的会存在大量服务异常后的重试逻辑
3) 服务调用者不可用
a.同步等待造成的资源耗尽:使用同步调用时,会产生大量的等待线程占用系统资源. 一旦线程资源被耗尽,服务调用者提供的服务也将处于不可用状态, 造成服务雪崩效应产生
3.雪崩应对策略:
1) 流量控制
a.网关限流
因为Nginx的高性能, 目前一线互联网公司大量采用Nginx+Lua的网关进行流量控制, 由此而来的OpenResty也越来越热门.
b.用户交互限流
具体措施:
a21. 采用加载动画,提高用户的忍耐等待时间.
a22. 提交按钮添加强制等待时间机制.
c.关闭重试
2) 改进缓存模式
a.缓存预加载
b.同步改为异步刷新
3) 服务自动扩容
a.AWS的auto scaling
4) 服务调用者降级服务
a.资源隔离:主要是对调用服务的线程池进行隔离.
b.对依赖服务进行分类
依赖服务分为: 强依赖和若依赖. 强依赖服务不可用会导致当前业务中止,而弱依赖服务的不可用不会导致当前业务的中止.
c.不可用服务的调用快速失败
一般通过 超时机制, 熔断器 和熔断后的 降级方法 来实现
4.解决方案:
1)使用Hystrix预防服务雪崩
2)Netflix的 Hystrix是一个帮助解决分布式系统交互时超时处理和容错的类库,
它同样拥有保护系统的能力
3)Hystrix的设计原则包括:资源隔离、熔断器、命令模式
二.示例
@HystrixCommand(fallbackMethod = "findOrderFallback", commandProperties = { //timeoutInMilliseconds 使用线程隔离时,调用超时时间 @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000") }) public String findOrder(Long userId,String orderNo) throws InterruptedException { Random random = new Random(); sleepRandom = random.nextInt(2000); System.out.println("sleepRandom="+sleepRandom); Thread.sleep(sleepRandom); ConsumerBeehiveUser user = findById(userId); if (user != null) { return user.getUsername() + " 的订单" + orderNo + " 找到啦!sleepRandom="+sleepRandom; } return "用户不存在!sleepRandom="+sleepRandom; } public String findOrderFallback(Long userId, String orderNo) { return "订单查找失败!sleepRandom="+sleepRandom; }
@SpringBootApplication @EnableDiscoveryClient //开启eureka服务 @EnableFeignClients //开启feigin注解 @EnableCircuitBreaker //开启Hystrix @EnableCircuitBreaker或@EnableHystrix @EnableHystrixDashboard //开启dashboard图形监控 public class ConsumerBeehiveApplication { @Bean @LoadBalanced public RestTemplate restTemplate() { //用于调用"提供者"的方法 return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(ConsumerBeehiveApplication.class, args); } }
command有四种获取结果的方式:
1.单一的结果execute
2.异步的结果queue
3.多个结果toObservable/observe(返回observable发射源)
4.相应的fallback也可以设置成异步和同步
Hystrix的主要目标是保护应用线程,而且fallbacks也有可能在调用者线程中,Hystrix需要限制并发的数量,当达到数量时无论多少fallback都不再运行了,就直接返回HystrixRuntimeException。