随着业务的扩展,微服务会不对增加,相应的其对外开放的 API 接口也势必增多,这不利于前端的调用以及不同场景下数据的返回,因此,我们通常都需要设计一个 API 网关作为一个统一的 API 入口,来组合一个或多个内部 API。
业界常用的 API 网关有很多方式,如:Spring Cloud Zuul、 Nginx、Tyk、Kong。本篇介绍的对象正是 Spring Cloud Zuul 。
Zuul 是 Netflix 公司开源的一个 API 网关组件,提供了认证、鉴权、限流、动态路由、监控、弹性、安全、负载均衡、协助单点压测等边缘服务的框架。
Spring Cloud Zuul 是基于 Netflix Zuul 的微服务路由和过滤器的解决方案,也用于实现 API 网关。其中,路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入门的基础。而过滤功能是负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础。
Spring Cloud Zuul 和 Eureka 进行整合时,Zuul 将自身注册到 Eureka 服务中,同时从 Eureka 中获取其他微服务信息,以便请求可以准确的通过 Zuul 转发到具体微服务上。
当前的项目列表如下:
服务实例 | 端口 | 描述 |
---|---|---|
common-api | - | 公用的 api,如:实体类 |
eureka-server | 9000 | 注册中心(Eureka 服务端) |
goods-server | 8081 | 商品服务(Eureka 客户端) |
goods-server-02 | 8082 | 商品服务(Eureka 客户端) |
goods-server-03 | 8083 | 商品服务(Eureka 客户端) |
order-server | 8100 | 订单服务(Eureka 客户端) |
创建一个为名 gateway-server 的 Spring Boot 项目。
在启动类上添加 @EnableZuulProxy 注解:
启动上边的所有项目,打开 Postman 请求订单下单接口,如下图:
图中,我们首先不经过网关直接访问 order-server 项目请求地址: http://localhost:8100/order/place
之后再修改成访问 gateway-server 项目的请求地址: http://localhost:9600/order/order/place
最终,响应结果都一样。
将订单服务的路由名称改成 extlight。
使用 Postman 请求下单接口,运行结果:
请求成功。
http://localhost:9600/order/order/place 无法被正常路由到订单服务,响应返回 404。
所有请求中的 path 需要添加 api 前缀。如: http://localhost:9600/extlight/order/place 需要改成 http://localhost:9600/api/extlight/order/place 。
或
Zuul 的核心技术就是过滤器,该框架提供了 ZuulFilter 接口让开发者可以自定义过滤规则。
我们以身份检验为例,自定义 ZuulFilter 过滤器实现该功能。
新建名为 user-server 的项目。
添加依赖:
application.yml:
登录接口:
user-server 启动类:
在 gateway-server 项目中,新建一个过滤器,需要继承 ZuulFilter 类 :
其中,filterType 有 4 种类型:
其过滤顺序如下图:
运行所有项目,测试操作步骤如下:
测试效果图如下:
Zuul demo 源码
Announcing Zuul: Edge Service in the Cloud