1. 概念
微服务访问入口,可以做请求路由,监控,安全检查等
2.zuul的搭建
1.搭建zuul工程springcloud-netflix-service-zuul
2. 完成基本搭建
导入eureak-client + web包
启动类编写
yml中 端口,服务名 注册地址 id
3. Zuul搭建
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
启动类加注解开启zuul功能
// 开启Zuul功能
@EnableZuulProxy
@SpringBootApplication
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class);
}
}
zuul配置访问路径,前缀,禁用服务名访问
zuul:
prefix: "/servers" #统一访问前缀
ignoredServices: "*" #禁用掉使用浏览器通过服务名的方式访问服务
routes:
pay-server: "/pay/**" #指定pay-server这个服务使用 /pay路径来访问 - 别名
order-server: "/order/**" #指定order-server这个服务使用 /order路径来访问
3. 访问
http://localhost:10050/servers/pay/pay/1
4. 自定义zuul的Filter, 过滤- 登录拦截
zuul的Filter工作流程
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过滤器了。
-
自定义Filter
自定义Filter类继承 ZuulFilter抽象类 重写四个方法
public String filterType(); 定义Filter的类型(pre 前置,post 后置, route 路由, error 错误)
public int filterOrder();定义filter执行顺序 数字越小越先执行
public boolean shouldFilter(); 是否执行run方法
public Object run() ; // 做过滤逻辑方法
@Component
public class LoginCheckFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre"; // pre前置filter
}
@Override
public int filterOrder() {
return 0; // filter序号 0 越小越先执行
}
@Override
public boolean shouldFilter() { // 是否执行run方法
RequestContext currentContext = RequestContext.getCurrentContext();
HttpServletRequest request = currentContext.getRequest();
String requestURI = request.getRequestURI();
if (requestURI.contains("/login")){ // 是否是登录
return false; // false 表示不走run方法
}
return true; // true 表示走run方法
}
@Override
public Object run() throws ZuulException {
// 获取currentContext
RequestContext currentContext = RequestContext.getCurrentContext();
// 获取请求对象
HttpServletRequest request = currentContext.getRequest();
// 获取响应对象
HttpServletResponse response = currentContext.getResponse();
// 设置响应格式与字符集
response.setContentType("application/json;charset=utf-8");
response.setCharacterEncoding("utf-8");
// 从请求头获取token
String token = request.getHeader("token");
if (token == null) {
try {
// 阻止filter继续往后执行
currentContext.setSendZuulResponse(false);
response.getWriter().println("请登录");
} catch (IOException e) {
e.printStackTrace();
}
}
return null; // 不用管
}
}
5. 备注
zuul底层还是使用rebbin负载均衡做请求的分发