Zuul Filter的小坑
Zuul是Spring Cloud技术栈里对外网关的实现。
所有的服务从这里对外暴露,鉴权、加密、压缩、缓存等等等等,各类需求可以在这里一次编码、彻底解决,方便极了。
但是这里又是所有服务的入口,一夫当关、万夫莫开,丁点错误会被无限放大,需要慎之又慎。
昨天小踩了一下,发现了几个小坑,先记下来,待时机成熟时在一块儿总结。
1. 不要对response直接操作!!
response的输出流不是你想写就能写,想读就能读。
可以看下HttpServletResponse的各种实现,也是通过各种wrapper,通过包装器模式来感知获取流数据的,断然不是想读就读想写就写。
作为Zuul中的filter,想操作response的多了,有一个乱来的,其他人就啥都不要干了。
所以,第一军规:不要直接操作 response。
写出这样的代码,你已经在犯错的边缘了:
HttpServletResponse response = RequestContext.getCurrentContext().getResponse();
正确的姿势是这样的,通过RequestContext操作:
RequestContext ctx = RequestContext.getCurrentContext();
ctx.setResponseStatusCode(RESPONSE_STATUS_CODE_304);
ctx.setResponseGZipped(true);
ctx.setResponseBody(sb.toString());
2. ZuulFilter的顺序
Zuul的设计可视化太差了,通过每个Filter的fitlerOrder返回,如下:
public int filterOrder() {
return 0;
}
没有一个统一的地方,可以看到所有的filter的顺序,只有调试时才能知道,不人性。
正确的姿势,放在同一个Class里:
@Bean
public XxxFilter xxxFilter(){ return new XxxFilter().setPreOrder(1); }
@Bean
public XxxFilter xxxFilter(){ return new XxxFilter().setPreOrder(2); }
@Bean
public XxxFilter xxxFilter(){ return new XxxFilter().setPostOrder(1); }
@Bean
public XxxFilter xxxFilter(){ return new XxxFilter().setPostOrder(2); }
@Bean
public XxxFilter xxxFilter(){ return new XxxFilter().setPostOrder(3); }
暂时这些。