spring cloud consul 中使用zuul

版权声明: https://blog.csdn.net/weixin_39823527/article/details/84580229

pom.xml 文件

<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

配置application.properties

           配置端口、网关

server.port=8505
spring.application.name=api-gateway
################################################
####################普通模式####################
###单实例配置
#zuul.routes.provider-service.path=/provider-service/**
#zuul.routes.provider-service.url=http://localhost:8501/
####多实例配置
#zuul.routes.provider-service.path=/provider-service/**
#zuul.routes.provider-service.listOfServers=http://localhost:8501/,http://localhost:8505/
#################################################
#与服务治理框架结合使用
zuul.routes.provider-service.path=/provider-service/**
zuul.routes.provider-service.service-id=provider-service 

配置consul     在   bootstrap.yml

spring:
  cloud:
    consul:
      discovery:
        enabled: true
        heartbeat:
          enabled: true
      host: localhost
      port: 8500

创建启动类

@EnableZuulProxy
@SpringBootApplication
@EnableDiscoveryClient
public class ApiGatewayApplication {

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


}

这是启动服务访问当请求http://localhost:port/provider-service/path,会被路由转发至 provider-service 服务的 /helloWorld 接口

配置请求过滤

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

/**
 * 自定义过滤器
 */
public class AccessFilter extends ZuulFilter {

    private static Logger log = LoggerFactory.getLogger(AccessFilter.class);
    /**
     * 过滤器的种类,它决定过滤器在请求的哪个生命周期执行
     *      pre:可以在请求被路由之前调用,
     *   route:在路由请求时候被调用,
     *   post:在route和error过滤器之后被调用,
     *   error:处理请求时发生错误时被调用
     * @return
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * 过滤器的执行顺序,当请求在一个阶段中存在多个过滤器时,需要根据
     * 该方法返回的值来一次执行
     * @return
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 判断该过滤器是否需要执行
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 过滤器的具体逻辑
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext ctx  =RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        log.info("send {} request to {}",request.getMethod(),request.getRequestURI().toString());
        Object accessToken = request.getParameter("accessToken");
        if (accessToken == null){
            log.warn("access token is empty");
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            return null;
        }
        log.info("access token ok");
        return null;
    }
}
ctx.setSendZuulResponse(false);令zuul过滤该请求,不对齐进行路由
ctx.setResponseStatusCode(401);设置返回错误状态码

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

@EnableZuulProxy
@SpringBootApplication
@EnableDiscoveryClient
public class ApiGatewayApplication {

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

    /**
     * 注入过滤器
     * @return
     */
    @Bean
    public AccessFilter accessFilter(){
        return new AccessFilter();
    }
}

再次访问http://localhost:port/provider-service/path,就会报错返回401状态码

这是需要访问http://localhost:port/provider-service/path?accessToken=true,就可以访问到你所访问的服务

扫描二维码关注公众号,回复: 4304277 查看本文章

二. 路由详解

  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/** 规则时,会被网关转发到 自己本身 服务的对应接口.

猜你喜欢

转载自blog.csdn.net/weixin_39823527/article/details/84580229
今日推荐