前言
Zuul 是在 Spring Cloud Netflix 平台上提供动态路由, 监控, 弹性, 安全等边缘服务的框架, 是 Netflix 基于 jvm 的路由器和服务器端负载均衡器, 相当于是设备和 Netflix 流应用的 web 网站后端所有请求的前门. 本文基于上篇 (SpringCloud 系列 --Ribbon 负载均衡) 实现 Zuul 动态路由
GitHub 地址: https://github.com/Netflix/zuul
官方文档:
代码编写
首先我们在 springCloud 下面新建一个 springboot 项目: zuul-server,pom 继承 parent, 并且在 Eureka 上面注册(还不会服务注册与发现的, 请戳: SpringCloud 系列 --Eureka 服务注册与发现)
maven 引入 Zuul
- <!-- Zuul -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
- </dependency>
配置文件
- server.port=10010
- spring.application.name=zuul-server
- eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
- # 健康检查(需要 spring-boot-starter-actuator 依赖)
- eureka.client.healthcheck.enabled=true
- # 续约更新时间间隔(默认 30 秒)
- eureka.instance.lease-renewal-interval-in-seconds=10
- # 续约到期时间(默认 90 秒)
- eureka.instance.lease-expiration-duration-in-seconds=10
- #zuul 代理配置 zuul.routes. 服务名. path, 服务名要与注册的一致
- # 应用名映射
- zuul.routes.myspringboot.path=/myspringboot/**
- zuul.routes.myspringboot.service-id=myspringboot
- #URL 映射
- #zuul.routes.myspringboot.path=/myspringboot/**
- #zuul.routes.myspringboot-url.url=http://localhost:10087/
- 自定义 Zuul 过滤器
- 更多的检查规则后续慢慢健全
- /**
- * Zuul 过滤器, 实现了路由检查
- */
- public class AccessFilter extends ZuulFilter {
- /**
- * 通过 int 值来定义过滤器的执行顺序
- */
- @Override
- public int filterOrder() {
- // PreDecoration 之前运行
- return PRE_DECORATION_FILTER_ORDER - 1;
- }
- /**
- * 过滤器的类型, 在 zuul 中定义了四种不同生命周期的过滤器类型:
- * public static final String ERROR_TYPE = "error";
- * public static final String POST_TYPE = "post";
- * public static final String PRE_TYPE = "pre";
- * public static final String ROUTE_TYPE = "route";
- */
- @Override
- public String filterType() {
- return PRE_TYPE;
- }
- /**
- * 过滤器的具体逻辑
- */
- @Override
- public Object run() {
- RequestContext ctx = RequestContext.getCurrentContext();
- HttpServletRequest request = ctx.getRequest();
- System.out.println(String.format("%s AccessFilter request to %s", request.getMethod(),request.getRequestURL().toString()));
- String accessToken = request.getParameter("accessToken");
- // 有权限令牌
- if (!StringUtils.isEmpty(accessToken)) {
- ctx.setSendZuulResponse(true);
- ctx.setResponseStatusCode(200);
- // 可以设置一些值
- ctx.set("isSuccess", true);
- return null;
- } else {
- ctx.setSendZuulResponse(false);
- ctx.setResponseStatusCode(401);
- ctx.setResponseBody("{\"result\":\"accessToken is not correct!\"}");
- // 可以设置一些值
- ctx.set("isSuccess", false);
- return null;
- }
- }
- /**
- * 返回一个 boolean 类型来判断该过滤器是否要执行
- */
- @Override
- public boolean shouldFilter() {
- return true;
- }
- }
启动类
添加 @EnableZuulProxy 注解并使用自定义过滤器
- @EnableZuulProxy
- @SpringBootApplication
- public class ZuulServerApplication {
- public static void main(String[] args) {
- SpringApplication.run(ZuulServerApplication.class, args);
- }
- @Bean
- public AccessFilter accessFilter() {
- return new AccessFilter();
- }
- }
效果演示
启动所有项目, 我们在 Eureka 上注册了四个服务, 相比上篇 (SpringCloud 系列 --Ribbon 负载均衡) 多了一个 Zuul
浏览器访问 http://localhost:10010/myspringboot/feign/ribbon,http://localhost:10010/myspringboot/feign/ribbon?accessToken=123456
http://localhost:10010/ 这个端口对外暴露, 相对于总入口, 后面接不同的路径由, Zuul 路由到对应的服务上
1, 没有 accessToken 是, 无法通过检查
2, 携带 accessToken 时, 可正常路由, 并且 Feign 调用, Ribbon 负载均衡
后记
我们为什么要使用 Zuul 呢?
1, 请求校验, 路由转发, 接口校验与业务逻辑分离
2, 隐藏诸多服务路径, 只暴露统一入口, 安全
更多 Zuul 配置, 请看官方文档
来源: https://www.cnblogs.com/huanzi-qch/p/10142395.html