Spring Cloud之微服务网关Zuul

生活中,最使人疲惫的往往不是道路的遥远,而是心中的郁闷;最使人痛苦的往往不是生活的不幸,而是希望的破灭;最使人颓废的往往不是前途的坎坷,而是自信的丧失;最使人绝望的往往不是挫折的打击,而是心灵的死亡。所以我们要有自己的梦想,让梦想的星光指引着我们走出落漠,走出惆怅,带着我们走进自己的理想。

导读:本篇文章讲解 Spring Cloud之微服务网关Zuul,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

服务网关概述

Spring Cloud的网关组件可以使用Zuul与Gateway,早期使用Zuul,后来spring出了自己的网关组件Gateway。

微服务网关Zuul、Gateway是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过网关这一层。API的实现方面更多的考虑业务逻辑,而安全、性能、监控交由网关来做。所以,微服务网关就是一个系统,通过暴露该微服务网关系统,提供相关功能。

微服务网关Zuul

Spring Cloud Zuul是整合Netflix公司的Zuul开源项目实现的微服务网关,它实现了请求路由、负载均衡、校验过虑等功能。

使用场景

请求鉴权:一般在pre类型,如果发现没有权限,直接拦截
	
异常处理:一般会在error类型和post类型过滤器中结合来处理

服务调用时长统计:pre和post结合使用

Zuul的基本使用

引入依赖

    <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>

标识Zuul网关

在启动类上使用@EnableZuulProxy注解标识此工程为Zuul网关

@SpringBootApplication
@EnableZuulProxy
public class GatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

路由配置

server:
  port: 8888

zuul:
  routes:
    zull-service: #路由名称,名称任意,保持所有路由名称唯一
      path: /zull/** #匹配访问路径
      #serviceId: zull-service #指定服务id,网关会从Eureka中找到服务的ip和端口,服务有多个实例时,进行动态路由
      url: http://localhost:9999 #指定url,映射路径对应的实际url地址
      strip-prefix: false #true:代理转发时去掉前缀,false:代理转发时不去掉前缀 如:请求zull/test true则代理转发到:/test false:则代理转发到:zull/test
      sensitiveHeaders:  #敏感头设置,默认会过虑掉cookie,设置为空表示不过虑 默认zuul会屏蔽cookie,cookie不会传到下游服务,设置为空则取消默认的黑名单,如果设置了具体的头信息则不会传到下游服务
         ignoredHeaders: #可以设置过虑的头信息,默认为空表示不过虑任何头

路由配置简化

大多数情况下, 路由名称和服务名会写成一样的。因此Zuul提供了一种简化的配置语法: zuul.routes.<serviceId>=<path>

zuul:
  routes:
    zull-service: #路由名称,名称任意,保持所有路由名称唯一
      path: /zull/** #匹配访问路径
      url: http://localhost:9999 #指定url,映射路径对应的实际url地址

# 简化      
zuul: 
  routes: 
    zull-service: /zull/**

Zuul的默认路由规则:

默认情况下,所有服务的映射路径就是服务名本身。如服务:zull-service,则默认映射路径就是: /zull-service/**

网关路由转发测试

新建一个工程项目,用于测试。

server:
  port: 9999
  servlet:
    context-path: /
@RestController
@RequestMapping("/zull")
public class TestController {

    @RequestMapping("/test")
    public String zullTest(){
        return "Hello Zull";
    }
}

直接访问服务
在这里插入图片描述
通过网关路由转发访问
在这里插入图片描述

过虑器

Zuul的核心就是过虑器,通过过虑器实现请求过虑,身份校验等。自定义过虑器需要继承 ZuulFilter,ZuulFilter是一个抽象类,需要覆盖它的四个方法

1、 shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true表示要执行此过虑器,否则不执行。

2、 run:过滤器的业务逻辑。
 
3、 filterType:返回字符串代表过滤器的类型,如下 pre:请求在被路由之前执行 routing:在路由请求时调用 post:在routing和errror过滤器之后调用 error:处理请求时发生错误调用

4、 filterOrder:此方法返回整型数值,通过此数值来定义过滤器的执行顺序,数字越小优先级越高。

自定义过滤器

测试过虑所有请求,判断是否有某头信息

@Component
public class ZullFilterTest extends ZuulFilter {

    /**
     * 指定过虑器的类型
     * 
     * 四种类型:
     * pre:请求在被路由之前执行
     * routing:在路由请求时调用
     * post:在routing和errror过滤器之后调用
     * error:处理请求时发生错误调用
     *
     * @return
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * 过虑器序号,越小越被优先执行
     * int值定义过滤器的执行顺序,数值越小优先级越高
     *
     * @return
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 返回true表示要执行此过虑器
     *
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 过虑器的内容
     * <p>
     * 过虑所有请求,判断头部信息是否有SSO-COOKIE,如果没有则拒绝访问,否则转发
     *
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
    	// RequestContext用于在过滤器之间传递消息, 数据保存在每个请求的ThreadLocal中,是线程安全的
        RequestContext requestContext = RequestContext.getCurrentContext();
        //得到request
        HttpServletRequest request = requestContext.getRequest();
        //得到response
        HttpServletResponse response = requestContext.getResponse();
        //得到SSO-COOKIE头
        String authorization = request.getHeader("SSO-COOKIE");
        if (StringUtils.isEmpty(authorization)) {
            //拒绝访问
            requestContext.setSendZuulResponse(false);
            //设置响应代码
            requestContext.setResponseStatusCode(200);

            //构建响应的信息
            JSONObject responseResult = new JSONObject();
            responseResult.put("code", 0);
            responseResult.put("msg", "拒绝访问");

            //转成json
            String jsonString = JSON.toJSONString(responseResult);
            requestContext.setResponseBody(jsonString);

            //转成json,设置contentType
            response.setContentType("application/json;charset=utf-8");
            return null;
        }
        return null;
    }
}

过滤器执行生命周期

在这里插入图片描述
正常流程

请求先经过pre类型过滤器,然后到达routing类型进行路由,请求就到达真正的服务提供者,执行请求返回结果后,会到达post过滤器,最后返回响应。

异常流程

如果error过滤器出现异常,最终也会进入POST过滤器,而后返回响应。

如果POST过滤器出现异常,会跳转到error过滤器,但是与pre和routing不同的是,请求不会再到POST过滤器了

执行测试

未加入头:SSO-COOKIE
在这里插入图片描述
加入头:SSO-COOKIE
在这里插入图片描述
Zuul进行请求转发的时候,会把header清空,为了传递原始的header信息到最终的微服务,需要另外配置

zuul.routes.xxx.sentiviteHeaders: #将指定路由的敏感头设置为空

zuul.routes.xxx.customSensitiveHeaders: true #对指定路由开启自定义敏感头

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/137042.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!