zoukankan      html  css  js  c++  java
  • SpringCloud Zuul基于Consul配置及详解

    一.构建工程

      1.引入依赖

            <!--SpringBoot2.0以上版本需引入该依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-consul-discovery</artifactId>
            </dependency>

      2.创建主类

    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableZuulProxy
    @RestController
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
    }

      3.配置application.properties

    zuul.routes.api-a.path=/api-a/**
    zuul.routes.api-a.service-id=api-a
    
    zuul.routes.api-b.path=/api-b/**
    zuul.routes.api-b.service-id=api-b

      这里存在 api-a 和 api-b 两个微服务应用, 当请求http://localhost:port/api-a/helloWorld, 会被路由转发至 api-a 服务的 /helloWorld 接口, 当请求http://localhost:port/api-b/helloWorld, 会被路由转发至 api-b 服务的 /helloWorld 接口. 当请求 URL 符合配置规则时, 就会被转发至 service-id 对应的微服务应用接口.

      4.配置请求过滤

      SpringCloud Zuul 还有另一个和核心功能: 请求过滤. Zuul 允许开发者在 API 网关上通过定义过滤器来实现对请求的拦截与过滤, 实现方法非常简单, 只需继承 ZuulFilter 抽象类并实现它定义的4个抽象函数就可以完成对请求的拦截和过滤.

    public class MyGatewayFilter extends ZuulFilter {

      /*
    4种过滤器类型,
      pre:可以在请求被路由之前调用,
      route:在路由请求时候被调用,
      post:在route和error过滤器之后被调用, 
      error:处理请求时发生错误时被调用
    */
      @Override 
      public String filterType() {
        
    return "pre";
      }
        @Override
        public int filterOrder() {
            return 0;  //优先级为0,数字越大,优先级越低
        }
    
        @Override
        public boolean shouldFilter() {
            return true;  // 是否执行该过滤器,此处为true,说明需要过滤
        }
    
        @Override
        public Object run() {
            RequestContext ctx = RequestContext.getCurrentContext();
            HttpServletRequest request = ctx.getRequest();
    
            log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
    
            Object accessToken = request.getParameter("token");  //获取token参数
            if (accessToken == null) {
                log.warn("token is empty");
                ctx.setSendZuulResponse(false);  //过滤该请求, 不对其进行路由
                ctx.setResponseStatusCode(401);  //返回错误码
                ctx.setResponseBody("token is null!");  //返回错误内容
                return null;   //Zuul还未对返回数据做处理
            }
        return null; } }

      

      创建过滤器后,它并不会直接生效, 我们还需为其创建具体的 Bean 才能启动该过滤器.

    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableZuulProxy
    @RestController
    public class LixjApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(LixjApplication.class, args);
        }
    
        @Bean
        public MyGatewayFilter myGatewayFilter(){
            return new MyGatewayFilter();
        }
    }

    二. 路由详解

      1.路径匹配规则  

        /api-a/?    可以匹配 /api-a/ 之后拼接一个任务字符的路径 , 比如 /api-a/a , /api-a/b , /api-a/c

        /api-a/*    可以匹配 /api-a/ 之后拼接任意字符的路径, 比如 /api-a/a, /api-a/aaa, /api-a/bbb . 但它无法匹配 /api-a/a/b 这种多级目录路径

        /api-a/**   可以匹配 /api-a/* 包含的内容之外, 还可以匹配形如 /api-a/a/b 的多级目录路径

     

      2.路由匹配顺序

        随着版本的迭代, 我们需要对一个服务做一些功能拆分, 将原属于 api-a 服务的某些功能拆分到另一个全新的服务 api-a-part 中, 而这些拆分的外部调用 URL 路径希望能够符合规则 /api-a/part/** .

        zuul.routes.api-a.path=/api-a/**
        zuul.routes.api-a.service-id=api-a
    
        zuul.routes.api-a-part.path=/api-a/part/**
        zuul.routes.api-a-part.service-id=api-a-part

        在源码中, 路由规则是通过 LinkedHashMap 保存的, 也就是说, 路由规则的保存时有序的, 而内容的加载是通过遍历配置文件中路由规则依次加入的, 所以导致问题的根本原因是对配置文件中内容的读取, 但上述properties配置无法保证路由规则加载顺序, 我们需要使用 YML 文件来配置, 以实现有序的路由规则. 

    zuul:
        routes:
            api-a-part:
                path=/api-a/part/**
                service-id=api-a-part 
            api-a:
                path=/api-a/**
                service-id=api-a        

      3.本地跳转 

    zuul.routes.api-c.path=/api-c/**
    zuul.routes.api-c.url=forward:/api-c

        以上配置使用了本地跳转,当 url 符合 /api-c/** 规则时,会被网关转发到 自己本身 服务的对应接口.

      

  • 相关阅读:
    希尔排序的理解和实现(Java)
    直接插入排序实现(Java)
    冒泡排序算法与选择排序算法
    Java中IO流中所涉及到的各类方法介绍
    Java常见编码方式简介
    Java中的BufferedReader 的readLine方法
    Java使用基本字节流OutputStream的四种方式对于数据复制(文本,音视频,图像等数据)
    java中IO流操作的标准异常类
    Java中常见数据结构:list与map
    互联网的网络地址分类
  • 原文地址:https://www.cnblogs.com/xiaoshouxing/p/9502469.html
Copyright © 2011-2022 走看看