1.Zuul概念
概念:微服务访问入口,可以做请求路由,监控,安全检查等
zuul本身是一个独立的服务,默认集成了Ribbon,zuul通过Ribbon将客户端的请求分发到下游的微服务,所以zuul需要通过Eureka做服务发行,同时zuul也集成了Hystrix。
2.整合Zuul
1.导入依赖
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.启动类编写
/**
* Zuul网关的启动类
*/
@SpringBootApplication
@EnableZuulProxy //开启网关
public class ZuulApplication1050 {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication1050.class);
}
}
3.yml配置
#注册到EurekaServer
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1010/eureka/
instance:
instance-id: zuul-server-1050
spring:
application:
name: zuul-server
server:
port: 1050
zuul:
prefix: "/servers" #统一访问前缀
ignoredServices: "*" #禁用掉使用浏览器通过服务名的方式访问服务
routes:
pay-server: "/pay/**" #指定pay-server这个服务使用 /pay路径来访问 - 别名
order-server: "/order/**" #指定order-server这个服务使用 /order路径来访问
user-server: "/user/**" #指定order-server这个服务使用 /user路径来访问
4.测试zuul
http://localhost:1050/servers/pay/pay/1
3.自定义zuul的Filter
1.zuul的工作原理
zuul的底层是通过各种Filter来实现的,zuul中的filter按照执行顺序分为了“pre”前置(”custom”自定义一般是前置),“routing”路由,“post”后置,以及“error”异常Filter组成,当各种Filter出现了异常,请求会跳转到“error filter”,然后再经过“post filter” 最后返回结果。
-
正常流程:
-
请求到达首先会经过pre类型过滤器,而后到达routing类型,进行路由,请求就到达真正的服务提供者,执行请求,返回结果后,会到达post过滤器。而后返回响应。
-
-
异常流程:
-
整个过程中,pre或者routing过滤器出现异常,都会直接进入error过滤器,再error处理完毕后,会将请求交给POST过滤器,最后返回给用户。
-
如果是error过滤器自己出现异常,最终也会进入POST过滤器,而后返回。
-
如果是POST过滤器出现异常,会跳转到error过滤器,但是与pre和routing不同的时,请求不会再到达POST过滤器了。
-
2.ZuulFilter
该filter下有四个核心方法
public abstract class ZuulFilter implements IZuulFilter{
// filter类型
abstract public String filterType();
// filter的执行顺序,越小越先执行
abstract public int filterOrder();
// 下面两个方法是 IZuulFilter 提供的
// 决定run方法是否要被执行
boolean shouldFilter();
// Filter的核心业务方法
Object run() throws ZuulException;
}
3.自定义filter
@Component
public class LoginCheckZuulFilter extends ZuulFilter {
@Override
public String filterType() {
//filter类型
return "pre";
}
@Override
public int filterOrder() {
//filter的执行顺序,越小越先执行
return 0;
}
@Override
public boolean shouldFilter() {
//是否执行该过滤器,此处为true,则会执行run方法
HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
String url = request.getRequestURI();
if (url.contains("/login")) {
return false;
}
return true;
}
@Override
public Object run() throws ZuulException {
//获取请求头
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
HttpServletResponse response = context.getResponse();
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
String token = request.getHeader("token");
//如果没有token,登录检查失败
if (StrUtil.isBlank(token)) {
try {
response.getWriter().print("请登录");
} catch (IOException e) {
e.printStackTrace();
}
// 不继续执行,过滤器执行
context.setSendZuulResponse(false);
}
return null;
}
}
4.测试 - postman
没有token时,如下
勾选token后