Zuul网关和基本应用场景
API网关是如何演化出来的?
看下面这幅图:
- 单体应用:浏览器发起请求,请求直接打到单体应用所在的机器上,应用从数据库查询数据原路返回给浏览器,对于单体应用来说,它只有一个,不需要网关。
- 微服务:微服务的应用可能部署在不同机房,不同地区,不同域名下。此时客户端(浏览器/手机/软件工具)想要请求对应的服务,都需要知道机器的具体的IP或者域名URL,当微服务实例众多时,这是难以记忆的。此时就有了网关,客户端相关的请求直接发送到网关,由网关根据请求标识解析判断出具体的微服务ip,再把请求转发到微服务实例。这其中的记忆功能就全部交由网关来操作了。
API网关基本功能
网关到底是干嘛的?有什么用呢?关于网关的功能请看下图:
这里重点介绍Netflix Zuul网关 主要是因为:
- 可动态发布的过滤器机制
- 同时也被集成入Spring Cloud体系
zuul 在 Netflix的使用情况(2017)
同时在国内也有很多优秀的应用案例,比如:
Zuul网关高级应用场景
红绿部署
如图右侧, 有红绿2个颜色的服务集群,从中可以看出绿色是v1版本,红色是v2版本。可以通过网关控制客户端请求具体请求到红色还是绿色的服务实例。
开发者测试分支
同上逻辑类似,通过网关配置将请求转发到test环境是服务实例。
埋点测试
同上逻辑类似,通过网关配置将请求转发到有埋点的环境服务实例。
压力测试
同上逻辑,不影响生产服务实例情况下,网关配置控制部分客户端请求或拟造请求到压力测试环境的服务实例。
调试路由
客户端有多种不同的设备,通过网关配置,可以将制定的设备请求路由转发到指定环境的服务实例。
金丝雀测试
粘性金丝雀
失败注入测试
降级测试
相关测试概念参考金丝雀发布、滚动发布、蓝绿发布到底有什么差别?关键点是什么?
跨区域的高可用
如图所示:当请求打到US-West-2
机器是,该机器内的服务实例挂了,但网关可以正常运行,可以通过配置网关,在请求服务实例返回失败的时候,主动再将请求转发到其它服务所在的机器上的网关继续处理,也就是zuul网关集群实现高可用。
防爬防攻击
健康检查和屏蔽坏节点
Zuul网关架构剖析
Zuul网关架构
- Zuul Servlet:zuul的servlet容器
- Zuul Filter Runner:zuul执行filter的处理器
- Pre routing Filter:zuul请求的前置过滤器
- Routing Filter:zuul请求的路由放行过滤器
- Post routing Filter:zuul请求的后置过滤器
- Request Context:zuul servlet的上下文
- Filter Loader:filter加载器
- Filter File Manager:filter内容管理器
- Filter Directory:filter过滤器存放路径
- Filter Publisher:发布filter的处理类
- Filter Persister:持久化filter的处理类
- Filter Poller:轮询Persister中的filter并将新filter推送至Filter Directory
请求处理生命周期
- http发送请求到zuul网关
- zuul网关首先经过pre filter;
- 验证通过后进入routing filter,接着将请求转发给远程服务,远程服务执行完返回结果,如果出错,则执行error filter;
- 继续往下执行post filter;
- 最后返回响应给http 客户端。
过滤器关键概念
- 类型Type: 定义在路由流程中,过滤器被应用的阶段
- 执行顺序Execution Order: 在同一个Type中,定义过滤器执行的顺序
- 条件Criteria: 过滤器被执行必须满足的条件
- 动作Action: 如果条件满足,过滤器中将被执行的动作
zuul中的过滤器类型
- PRE:在请求被路由到源服务器前要执行的过滤器
- 认证
- 选路由
- 请求日志
- ROUTING:处理将请求发送到源服务器的过滤器
- POST:在响应从源服务器返回时要被执行的过滤器
- 对响应增加HTTP头
- 收集统计和度量
- 将响应以流的方式发送回客户端
- ERROR:上述阶段中出现错误要执行的过滤器
过滤器样例Demo
import javax.servlet.http.HttpServletRequest; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; public class PreFilter extends ZuulFilter { @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); System.out.println("Request Method : " + request.getMethod() + " Request URL : " + request.getRequestURL().toString()); return null; } } 复制代码
统一Filter管理界面
因为zuul有可动态发布的过滤器机制,所有可以有一个页面来管理zuul网关的过滤器,使得网关的可定制性,可变性更强大。