Spring cloud Zuul网关异常处理
Spring cloud Zuul网关异常处理
一 异常测试:
1> 创建一个pre类型的过滤器,并在该过滤器的run方法实现中抛出一个异常。比如下面的实现,在run方法中调用的doSomething方法将抛出RuntimeException异常
package com.xbchen.springcloud.filter.post; import com.netflix.zuul.ZuulFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; @Component
public class ThrowExceptionPostFilter extends ZuulFilter { private static Logger log = LoggerFactory.getLogger(ThrowExceptionPostFilter.class); @Override
public String filterType() {
return "post";
} @Override
public int filterOrder() {
return 10;
} @Override
public boolean shouldFilter() {
return true;
} @Override
public Object run() {
log.info("This is a post filter, it will throw a RuntimeException");
doSomething();
return null;
} private void doSomething() {
throw new RuntimeException("Exist some errors...");
} }
2> 在启动类中为过滤器创建Bean
@Bean
public ThrowExceptionFilter throwExceptionFilter() {
return new ThrowExceptionFilter();
}
3> 运行启动类
4> 发现后台并没抛出异常信息
二 问题分析:
查看postRoute阶段的异常处理过滤器SendErrorFilter中的方法shouldFilter

注意: 新版本中已经修复了该问题,取消了error.status_code的判断。
即: 只有上线文中包含error.status_code,才能被SendErrorFilter处理。
以此需要自行处理。
处理方式1: 在抛异常时,自行捕获设置error.status_code
@Override
public Object run() {
log.info("This is a post filter, it will throw a RuntimeException");
//doSomething();
RequestContext context=RequestContext.getCurrentContext();
try{
doSomething();
}catch (Exception e){
context.set("error.status_code", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
context.set("error.exception",3);
}
return null;
}
处理方式2:新增一个error处理的过滤器
@Component
public class ErrorFilter extends ZuulFilter {
Logger log = LoggerFactory.getLogger(ErrorFilter.class);
@Override
public String filterType() {
return "error";
}
@Override
public int filterOrder() {
return 20;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
Throwable throwable = RequestContext.getCurrentContext().getThrowable();
log.error("this is a ErrorFilter : {}", throwable.getCause().getMessage());
ctx.set("error.status_code", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
ctx.set("error.exception", throwable.getCause());
return null;
} }
三:遗留问题:路由包括3阶段, 正常处理过程:preRoute-->route-->postRoute
其中preRoute 和route异常时,会被捕获直接进入postRoute;
会经过postRoute的过滤器(SendErrorFilter extends ZuulFilter)
但是postRoute阶段的异常,是没有处理的过滤器的。以此需要针对postRoute阶段的异常进行单独处理。
处理方式:
新增处理类,扩展过滤器处理类FilterProcessor的processZuulFilter方法
public class DidiFilterProcessor extends FilterProcessor {
@Override
public Object processZuulFilter(ZuulFilter filter) throws ZuulException {
try {
return super.processZuulFilter(filter);
} catch (ZuulException e) {
RequestContext ctx = RequestContext.getCurrentContext();
ctx.set("failed.exception", e);
ctx.set("failed.filter", filter);
throw e;
}
}
}
在启动类中设置处理类
@SpringBootApplication
@EnableZuulProxy
public class GatewayApplication { public static void main(String[] args) {
FilterProcessor.setProcessor(new DidiFilterProcessor());
SpringApplication.run(GatewayApplication.class, args);
}
}
新增post阶段的异常处理过滤器
/**
* 从POST抛出的异常,使用该过滤器返回错误信息
*/
@Component
public class ErrorExtFilter extends SendErrorFilter {
Logger log = LoggerFactory.getLogger(ErrorExtFilter.class);
@Override
public String filterType() {
return "error";
}
@Override
public int filterOrder() {
return 30;
}
@Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
ZuulFilter failedFilter = (ZuulFilter) ctx.get("failed.filter");
if(failedFilter != null && failedFilter.filterType().equals("post")) {
return true;
}
return false;
}
}
四:异常自定义
以上异常已经正常抛出,但是格式并不一定符合项目要求,或者有时并不需要将异常返回给客户端。
由于异常信息格式是在DefaultErrorAttributes定义的,以此可对该类进行扩展。
比如:异常异常信息,避免返回到客户端。
public class DidiErrorAttributes extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes (
RequestAttributes requestAttributes, boolean includeStackTrace){
Map<String, Object> result = super.getErrorAttributes(requestAttributes, includeStackTrace);
result.remove("exception");
return result;
}
}
在启动类中新增异常属性扩展类的Bean创建。
@Bean
public DefaultErrorAttributes errorAttributes() {
return new DidiErrorAttributes();
}
Spring cloud Zuul网关异常处理的更多相关文章
- 创建swagger的springboot-stater,并在spring cloud zuul网关中引入
Swagger 是一款RESTFUL接口的.基于YAML.JSON语言的文档在线自动生成.代码自动生成的工具. 通过在controller中添加注解,即可轻易实现代码文档化. Swagger提供ui界 ...
- Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式。
时间过的很快,写springcloud(十):服务网关zuul初级篇还在半年前,现在已经是2018年了,我们继续探讨Zuul更高级的使用方式. 上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制 ...
- Spring Cloud Zuul 网关使用与 OAuth2.0 认证授权服务
API 网关的出现的原因是微服务架构的出现,不同的微服务一般会有不同的服务地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题: 客户端会 ...
- Spring Cloud Zuul 网关服务的fallback
当我们的zuul进行路由分发时,如果后端服务没有启动,或者调用超时,这时候我们希望Zuul提供一种降级功能,而不是将异常暴露出来. Spring cloud zuul提供这种降级功能,操作步骤如下: ...
- Spring Cloud Zuul 网关的分布式系统中整合Swagger(转)和 zuul跨域访问问题
首先恭喜自己终于找对了努力的方向,很荣幸能在公司接触到微服务架构,也很高兴公司一个大佬哥们愿意带我,他技术确实很牛逼,我也很佩服他,前后端通吃,干了六年能有这样的水平.最近跟着在搞微服务架构,给我分配 ...
- Spring Cloud(十一):Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式
上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制,但其实Zuul还有更多的应用场景,比如:鉴权.流量转发.请求统计等等,这些功能都可以使用Zuul来实现. Zuul的核心 Filter是Zuu ...
- Spring Cloud zuul网关服务 一
上一篇进行Netflix Zuul 1.0 与 gateway的对比.今天来介绍一下 zuul的搭建及应用 Zuul 工程创建 工程创建 cloud-gateway-zuul.还是基于之前的工程 po ...
- Spring Cloud Zuul网关(快速搭建)
zuul 是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用. 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架.相当于是设备和 Netflix ...
- spring cloud深入学习(十二)-----Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式
Zuul的核心 Filter是Zuul的核心,用来实现对外服务的控制.Filter的生命周期有4个,分别是“PRE”.“ROUTING”.“POST”.“ERROR”,整个生命周期可以用下图来表示. ...
随机推荐
- dbus-launch(转)
*NAME* dbus-launch - Utility to start a message bus from a shell script dbus-launch - 从shell脚本启动一个消息 ...
- css中代码格式以及@import的语法结构
CSS中代码格式 CSS是Cascading Style Sheets(层叠样式表)的缩写.是一种对web文档添加样式的简单机制,属于表现层的布局语言. 1.基本语法规范分析一个典型CSS的语句: p ...
- 队列的理解和实现(一) ----- 循环队列(java实现)
什么是队列 我们都知道栈是先进后出的一种线性表,与之相反的是,队列是一种先进先出的线性表.它只允许在表的一端进行插入,而在另一端进行删除.举个例子来说,在生活中我们买东西需要进行排队,最先排队的可以最 ...
- 【APUE】第3章 文件I/O (1)
1.文件描述符 对于内核来说,所有打开的文件都通过文件描述符来引用.文件描述符是一个非负整数.当打开一个现有的文件或者创建一个新文件时,内核向进程返回一个文件描述符.当读.写一个文件时,使用open或 ...
- Android NDK开发及OpenCV初步学习笔记
https://www.jianshu.com/p/c29bb20908da Android NDK开发及OpenCV初步学习笔记 Super_圣代 关注 2017.08.19 00:55* 字数 6 ...
- Java NIO学习与记录(一):初识NIO
初识 工作中有些地方用到了netty,netty是一个NIO框架,对于NIO却不是那么熟悉,这个系列的文章是我在学习NIO时的一个记录,也期待自己可以更好的掌握NIO. 一.NIO是什么? 非阻塞式I ...
- 关于Nginx启动成功,浏览器不能访问的解决办法
本人初学Nginx,第一天配置成功并能通过浏览器进行访问. 第二天重新打开,将Nginx启动,但是浏览器却访问不了. 执行 ps aux|grep nginx ,执行结果如下,的确Nginx服务已经启 ...
- [性能测试]:记录一次性能测试,nmon文件收集工具的小问题
问题:今天发现nmon文件分析成excel后,用<NMON抽取结果.excel>无法抓取到数据 解决过程:1,认为是nmon分析文件<nmon analyser v33g.xls&g ...
- C# 文件操作系列一
在.Net环境中,所有关于文件操作的类都在System.IO命名空间下,注:在修改文件时,安全性显得格外重要,但是本随笔不过多讲述安全性,这里假设我们有足够的权限. 1.管理文件系统 先通过一幅图来了 ...
- git 学习之基本概念
在学习 Git 的时候我们经常会听到工作区,版本库,暂存区.那么这些东西指的是什么呢?本次我们就一起学习一下. 工作区 顾名思义:工作的区域,那么你一般在哪工作呢?当然是你本地可以看到的目录啦! 版本 ...