目前看起来我们的项目越来越像模像样了,只要服务器足够多,部分的故障完全不会影响到我们的正常业务,是这样的吗?不是!
我们假设这种情况,现在由于
商品服务器
的网络不稳定或濒临崩溃,或者短暂故障(Eureka的自我保护)。当访问订单信息的时候,订单服务器
会向商品服务器
请求数据,但是商品服务器
迟迟不能返回数据,随着访问订单信息的请求增多,订单服务器
就会产生大量的挂起线程,进而崩溃,如果再有其他服务需要向订单服务器
请求数据,它就也会濒临崩溃,直至蔓延到整个系统,也就是所说的雪崩效应
。
那么这种情况怎么办呢?我相信你心里已经有了答案:第一时间切断有问题的那台商品服务器
。对!!!
但是,谁去切断?人工肯定不能第一时间发现,所以,这个时候我们的断路器Hystrix
就该上场了。先来看下它的作用:
Hystrix是国外知名的视频网站Netflix所开源的非常流行的高可用架构框架。Hystrix能够完美的解决分布式系统架构中打造高可用服务面临的一系列技术难题。
资源隔离:包括线程池隔离和信号量隔离,限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其他服务调用。
降级机制:超时降级、资源不足时(线程或信号量)降级,降级后可以配合降级接口返回托底数据。
*融断:当失败率达到阀值自动触发降级(如因网络故障/超时造成的失败率高),熔断器触发的快速失败会进行快速恢复。
*缓存:提供了请求缓存、请求合并实现。
断路器开启或者关闭的条件:
1、当满足一定的阀值的时候(默认10秒内超过20个请求次数)
2、当失败率达到一定的时候(默认10秒内超过50%的请求失败)
3、到达以上阀值,断路器将会开启
4、当开启的时候,所有请求都不会进行转发
5、一段时间之后(默认是5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。重复4
废话不多说,下面,我们在订单服务器
上加以改造,首先在order
模块下的pom.xml
添加如下依赖,引入hystrix:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
</dependency>
进入OrderApplication
启用断路器
package com.felix;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@EnableHystrix
@EnableDiscoveryClient
@SpringBootApplication
public class OrderApplication {
@Bean
@LoadBalanced //启用负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
接下来,设置断路器
开启后,请求失败的方法:
package com.felix.service;
import com.felix.model.Goods;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class GoodsService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
//启用负载均衡后,有restTemplate自己去选择访问那个服务
@HystrixCommand(fallbackMethod = "findGoodsByIdServiceOffline")
public Goods findGoodsById(Long id){
String service = "goods-service";
String url = "http://" + service + "/goods/" + id;
return restTemplate.getForObject(url,Goods.class);
}
public Goods findGoodsByIdServiceOffline(Long id){
return new Goods(id,"查询商品信息出错","","",0.0F);
}
这里,请求失败后,调用findGoodsByIdServiceOffline
方法,返回一个错误的产品信息。现在,启动/重启订单服务器
,先去查看一下服务中心
已有的服务

现在
服务中心
一共有5个注册进来的服务。然后访问订单信息http://127.0.0.1:8100/order/2
,此时,数据正常
然后,关闭一台
商品服务器
,模拟服务器故障,再次访问http://127.0.0.1:8100/order/2

可以发现,故障已经体现出来了,我们再多次访问
http://127.0.0.1:8100/order/2
这个地址后,会有几条有问题的数据,但是紧接着,数据就又开始正常了,因为此时,断路器
已经满足了开启条件,断开了故障商品服务器
,阻断了故障向整个系统的蔓延。
分布式系统开发---摈弃接口拼接SpringCloud(九)
以上内容转载请注明出处,同时也请大家不吝你的关注和下面的赞赏
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
网友评论