降级的概念
降级的作用就是当某个服务的访问量急剧增高,服务器资源不够用时,将访问量较低的服务停下来,把服务器资源让给资源需求较高的服务,以避免整个系统宕掉
降级的实现两种实现方式
- 利用 Docker 来实现,当需要对某个服务进行降级时,直接将这个服务所有的容器停掉,需要恢复的时候重新启动就可以了
- 在网关中实现降级,某个服务被降级后,前台在请求被降级服务的接口时直接拒绝掉
1.在zuul网关中实现降级
1、在zuul网关的application.yml中,配置要降级的服务
将要降级的服务配置到down.service节点,多个服务之间用逗号分隔
down: # 配置需要降级的服务,多个服务之间用逗号分隔
service: jwxt-student,jwxt-xxxx
2、在zuul服务中创建新的filter过滤器,配置降级
过滤器拦截到接口后,找到接口所属的服务,若此接口的服务在down的service节点中存在,那么对该服务进行降级处理
概括:
- 从application.yml配置文件中获取down.service节点的值(要降级的服务)
- 将过滤器的拦截规则设置为路由拦截
- 在run()方法中创建当前上下文对象;从上下文中获取当前接口的服务的实例;若此服务在down.service节点中存在,则对此服务进行降级(拒绝服务)并停止该服务的zuul拦截器;在上下文中设置名为isSuccess的参数,动态控制过滤器的启动与停止;最后向前台返回服务降级提示(注意:向前台返回提示时,必须设置编码格式)
- 在shouldFilter()方法中通过上下文中的isSuccess判断是否开启过滤器
@Component
public class DownFilter extends ZuulFilter {
@Value("${down.service}")//从配置文件中获取down.service节点的值
private String BASIC_CONF;
public DownFilter(){
super();
}
@Override
public String filterType() {
return FilterConstants.ROUTE_TYPE;//过滤器的拦截规则
}
@Override
public int filterOrder() {
return 0; //过滤的优先级
}
@Override
public boolean shouldFilter() {//是否开启过滤器
//从RequestContext中获取isSuccess,判断如果isSuccess存在,那么说明服务需要被降级,返回false,
// 如果isSuccess不存在,那么该服务不需要被降级,返回true
Object success = RequestContext.getCurrentContext().get("isSuccess");
return success == null ? true : Boolean.parseBoolean(success.toString());
}
@Override
public Object run() throws ZuulException {
RequestContext context = RequestContext.getCurrentContext();
context.getResponse().setContentType("application/json;charset=utf-8");
Object serviceId = context.get("serviceId");//从上下文中获取当前访问的接口的服务的实例
if(serviceId != null && BASIC_CONF != null){
List<String> serviceIds = Arrays.asList(BASIC_CONF.split(","));//将BASIC_CONF的值通过 , 分隔存入list集合
if(serviceIds.contains(serviceId.toString())){//然后判断若服务的id在serviceIds中包含,那么就降级这个服务
context.setSendZuulResponse(false);//拒绝服务
context.set("isSuccess",false);//动态的控制过滤器的启动停止
Result result = new Result(ResultCode.FAIL);//向前台返回降级提示(这里没有写降级提示)
context.setResponseBody(JSON.toJSONString(result));//setResponseBody设置返回的内容
return null;
}
}
return null;
}
}