一、什么是zuul网关
Zuul相当于是第三方调用(app应用端和PC端)和服务提供方之间的防护门。作为前端服务(Edge Service也称边缘服务,前端服务的作用是对后端服务做必要的聚合和裁剪后暴露给外部不同的设备,如PC,Pad或者Phone),Zuul旨在实现动态路由,监控,弹性和安全性。
二、zuul网关能做什么
(1)- 权限控制和安全性--为每个请求提供身份认证,并拒绝不满足条件的请求。
(2)- 预警和监控--跟踪前端有意义的请求和统计数据,以便我们准确了解生产环境运行状况。
(3)- 动态路由--根据需求将请求动态地路由到不同的后端集群。
(4)- 压力测试--逐渐增大到集群的流量,以便进行性能评估。
(5)- 负载均衡--为每种类型的请求分配容量并丢弃超过限额的请求。
三、SpringCloud配置Zuul网关
1、向Pom文件添加依赖
<!--客户端eureka--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!--网关zuul--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> <!--熔断与降级hystrix--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-hystrix</artifactId> </dependency> <!--监视和管理应用程序Springboot,查看路由--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
2、application.yml
spring:
application:
name: zuul-proxy
server:
port: 20000
#注册中心相关配置
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
instance-id: ${spring.cloud.client.ip-address}:${server.port}
#网关配置
zuul:
# LogFilter: #自定义过滤器的名称
# pre: #自定义过滤器类型
# disable: true # 是否禁用
prefix: /api/ #前缀
routes: #路由规则
user:
path: /u/**
url: http://localhost:9000 #远程服务必须有url
word:
path: /w/**
url: http://localhost:9001
# 关闭那些服务的默认路由
ignored-services: user,word
add-host-header: true
#不对敏感资源做拦截
sensitive-headers:
ignored-headers:
host:
socket-timeout-millis: 4000 # 请求的处理时间
connect-timeout-millis: 4000 # 请求的链接时间
#开启路由端点
management:
endpoints:
web:
exposure:
include: 'routes'
3、启动类
在启动类上添加@EnableZuulProxy注解
@SpringBootApplication @EnableDiscoveryClient @EnableZuulProxy public class ZuulApp { public static void main(String[] args){ SpringApplication.run(ZuulApp.class,args); } }
4、查看路由访问接口
通过链接地址http://localhost:端口/actuator/routes 查看简单路由信息
通过链接地址http://localhost:端口/actuator/routes/details 查看详细路由信息
5、自定义网关过滤器
继承ZuulFilter
package com.donleo.zuul.filter; import com.alibaba.fastjson.JSONObject; import com.donleo.zuul.common.CommonResult; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import org.apache.http.HttpStatus; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; /** * 自定义网关过滤器 * * @author liangd * @since 2021-01-12 18:52 */ @Component public class LogFilter extends ZuulFilter { /** * 过滤器的类型。可选值有: * pre - 前置过滤 * route - 路由后过滤 * error - 异常过滤 * post - 远程服务调用后过滤 */ @Override public String filterType() { return "pre"; } /** * 同种类的过滤器的执行顺序。 * 按照返回值的自然升序执行。 * 值越小,级别越高 */ @Override public int filterOrder() { return 0; } /** * 哪些请求会被过滤 * */ @Override public boolean shouldFilter() { RequestContext currentContext = RequestContext.getCurrentContext(); HttpServletRequest request = currentContext.getRequest(); String requestURI = request.getRequestURI(); //只有/api/w 开头的会被过滤 return requestURI.startsWith("/api/w"); //true 默认所有请求都会过滤 //return true; } @Override public Object run() { RequestContext currentContext = RequestContext.getCurrentContext(); HttpServletRequest request = currentContext.getRequest(); String remoteAddr = request.getRemoteAddr(); String remoteHost = request.getRemoteHost(); String requestURI = request.getRequestURI(); //可以在此处进行日志、鉴权等 if (requestURI.startsWith("/api/w")) { currentContext.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED); String method = request.getMethod();//方法额类型 System.out.println(remoteAddr + "," + remoteHost + "访问了:" + requestURI + "方法:" + method); //设置为false,表示不进行路由,如果这个请求被拦截,这个方法后面的逻辑不需要执行了 currentContext.setSendZuulResponse(false); //表示没有权限访问 currentContext.setResponseBody(JSONObject.toJSONString(CommonResult.forbidden(""))); } return null; } }
6、其它过滤器
过滤器名称 |
过滤类型 |
优先级 |
过滤器的作用 |
ServletDetectionFilter |
pre |
-3 |
检测当前请求是通过DispatcherServlet处理运行的还是ZuulServlet运行处理的。 |
Servlet30WrapperFilter |
pre |
-2 |
对原始的HttpServletRequest进行包装。 |
FormBodyWrapperFilter |
pre |
-1 |
将Content-Type为application/x-www-form-urlencoded或multipart/form-data的请求包装成FormBodyRequestWrapper对象。 |
DebugFilter |
route |
1 |
根据zuul.debug.request的配置来决定是否打印debug日志。 |
PreDecorationFilter |
route |
5 |
对当前请求进行预处理以便执行后续操作。 |
RibbonRoutingFilter |
route |
10 |
通过Ribbon和Hystrix来向服务实例发起请求,并将请求结果进行返回。 |
SimpleHostRoutingFilter |
route |
100 |
只对请求上下文中有routeHost参数的进行处理,直接使用HttpClient向routeHost对应的物理地址进行转发。 |
SendForwardFilter |
route |
500 |
只对请求上下文中有forward.to参数的进行处理,进行本地跳转。 |
SendErrorFilter |
post |
0 |
当其他过滤器内部发生异常时的会由它来进行处理,产生错误响应。 |
SendResponseFilter |
post |
1000 |
利用请求上下文的响应信息来组织请求成功的响应内容。 |
7、过滤器的生命周期
8、过滤器的种类
- pre:在请求被路由到目标服务前执行,比如权限校验、打印日志等功能;
- routing:在请求被路由到目标服务时执行,这是使用Apache HttpClient或Netflix Ribbon构建和发送原始HTTP请求的地方;
- post:在请求被路由到目标服务后执行,比如给目标服务的响应添加头信息,收集统计数据等功能;
- error:请求在其他阶段发生错误时执行。