Zuul是Netflix旗下的又一重要成员,是一个基于 JVM 路由和服务端的网关和负载均衡器,是一个提供路由、监控、弹性、安全等方面的服务框架。其核心是过滤器,通过这些过滤器我们可以扩展出很多功能,例如:
Zuul的网关功能非常强大,这里通过一个简单的例子,通过zuul网关路由到之前的微服务中。
springboot版本:2.2.6.RELEASE 。工程名:zuul。启动类为:ZuulApplication
需要添加2个依赖,分别为eureka,zuul.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
启动类上添加@EnableZuulProxy注解
@SpringBootApplication
//开启
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
需要在配置文件中添加基础配置,eureka,路由规则等。
配置端口号与服务名
server:
port: 9008 #端口
spring:
favicon:
enabled: false
application:
name: service-zuul #服务名称
由于serice-zuul也是一个微服务因此也需要注册到Eureka中
#配置eureka server
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
#注册到两个eureka上
defaultZone: http://localhost:9005/eureka/,http://localhost:9006/eureka/
#配置路由规则
zuul:
routes:
api-monkey:
path: /api-monkey/**
serviceId: service-openfeign
以上配置,路由规则就是匹配所有符合/api-monkey/**的请求,只要路径中带有/api-monkey/都将被转发到service-openfeign服务上,至于service-openfeign服务的地址到底是什么则由eureka-server注册中心去分析,我们只需要写上服务名即可。
以当前搭建的项目为例,请求 http://localhost:9008/api-monkey/buy/1 接口则相当于请求 http://localhost:9007/buy/1 (service-openfeign服务的地址为 http://localhost:9007/buy/1), 路由规则中配置的api-monkey是路由的名字,可以任意定义,但是一组path和serviceId映射关系的路由名要相同。返回结果为:
{
"id": 1,
"name": "apple1",
"price": 8000.00
}
说明API网关服务已经构建成功。
Zuul 就像一个安检站 ,所有请求都会经过这个安检站,安检站中需要对所有的请求按照一定的规则进行过滤。例如:请求验证,当验证通过了才可以进行转发。这里模拟一个带token的过滤,如果请求中没有token,则返回无效请求,反之进行跳转
@Component
//必须要继承ZuulFilter
public class OAuth2Filter extends ZuulFilter {
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String token = request.getParameter("token");
if (token == null) {
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
ctx.addZuulResponseHeader("content-type", "text/html;charset=utf-8");
ctx.setResponseBody("无效请求");
}
return null;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public int filterOrder() {
return 0;
}
@Override
public String filterType() {
return "pre";
}
}
ctx.setSendZuulResponse(false)表示不对该请求进行路由,然后设置响应码和响应值。这里只是个模拟,所以run方法的返回值目前暂时没有任何意义。{
"id": 1,
"name": "apple1",
"price": 8000.00
}
无效请求在上面的例子中,路由规则配的是:
#配置路由规则
zuul:
routes:
api-monkey:
path: /api-monkey/**
serviceId: service-openfeign
当访问地址符合/api-monkey/**规则的时候,会被自动定位到service-openfeign服务上。如果路由规则什么都不写,则zuul默认会路由到注册中心中的所有服务。格式为:域名/服务名/api地址
例如,本服务系统中可以向外提供服务的有service-openfeign,service-product,则对应的请求分别为:
zuul:
ignored-services: service-product
zuul:
ignored-patterns: /**/hello/**
zuul:
prefix:/v1
此时访问路径就变成:http://localhost:9008/v1/api-monkey/buy/1?token=123
| 通配符 | 含义 | 举例 | 备注 |
|---|---|---|---|
| ? | 匹配任意单个字符 | /api-monkey/? | 可以匹配: /api-monkey/1 |
| * | 匹配单路径任意数量字符 | /api-monkey/* | 可以匹配:/api-monkey/1,/api-monkey/22,/api-monkey/333 不可以匹配:/api-monkey/1/2/3 |
| ** | 匹配多路径任意单个字符 | /api-monkey/** | 可以匹配: /api-monkey/1,/api-monkey/1/22 |
关于Zuul的基本知识点就介绍完了。最后,希望本文能帮助大家,祝大家在IT之路上少走弯路,一路绿灯不堵车,测试一性通过,bug秒解!
源码下载