美文网首页
spring cloud gateway实践

spring cloud gateway实践

作者: pilisiyang | 来源:发表于2019-11-18 14:33 被阅读0次

    Spring Cloud Gateway简介

    Spring Cloud Gateway是spring官方替代zuul作为网关的解决方案.
    

    Spring Cloud Gateway requires the Netty runtime provided by Spring Boot and Spring Webflux.

    基于Spring Boot 2.X 和 Spring Webflux,不能在Servlet容器中运行,采用非阻塞API,相比zuul,优化了很多配置。

    相关词汇

    • Route: 路由网关构建过滤规则,由id,目标url,Predicate规则,Filter定义,如果Predicate的结果为true,则匹配到路由。
    • Predicate: Java 8 Function Predicate,它可以接受输入参数,返回一个布尔值结果,靠它匹配请求的path,headers ,参数。
    • Filter: 路由过程中的filter,分为 GlobalFilter(全局过滤器) ,GatewayFilter。

    工作流程

    这是官方文档中的流程,client 向 gateway 发送请求,首先在 Gateway Handler Mapping 中匹配路由,如果匹配到就将请求传递到对应的 Handler ,Handler再执行设置的过滤器链,最后将请求发送到代理的服务。

    内置Predicate

    • 时间: 包括 After,Before ,Between 匹配请求时间
    • Cookie: 提供了匹配请求Cookie名和正则表达式的功能
    • Header:提供了匹配请求Header名和正则表达式的功能
    • Host:匹配主机名,支持 URI 模板,例如 {sub}.myhost.org
    • Method:匹配请求方法
    • Path:匹配请求路径
    • Query:匹配请求参数
    • RemoteAddr:匹配ip地址和子网掩码

    过滤器

    • AddRequestHeader:转发请求前增加Header
    • AddRequestParameter:转发请求前增加参数
    • AddResponseHeader:回调请求增加Header
    • Hystrix:断路器
    • FallbackHeaders:服务降级
    • PrefixPath:为请求增加前缀
    • PreserveHostHeader:发送原始Header
    • RequestRateLimiter:限流,也可以通过Redis
    • RedirectTo:重定向
    • RemoveNonProxyHeaders:从转发的请求中删除Header
    • RemoveRequestHeader:删除设置的Header
    • RemoveResponseHeader:在响应返回到客户端之前删除Header
    • RewritePath:通过正则表达式重写请求路径
    • RewriteResponseHeader:通过正则表达式重写响应头值
    • SaveSession:转发调用之前已保存会话状态
    • SecureHeaders:增加安全Header
    • SetPath:通过模板化路径段来操作请求路径
    • SetResponseHeader:替换响应Header
    • SetStatus:设置http status
    • StripPrefix:转发请求前删除部分路径
    • Retry: 重试
    • RequestSize:限制请求大小

    以上都是可以在application.yml中配置的内置过滤器,如果无法满足开发要求,可以自己在java DSL中配置。

        @Bean
        public RouteLocator routes(RouteLocatorBuilder builder) {
            return builder.routes()
                    .route("cos3", predicateSpec -> predicateSpec.path("/cos3/**")
                            .filters(gatewayFilterSpec -> {
                                gatewayFilterSpec.rewritePath("/cos3/(?<segment>.*)", "/$\\{segment}");
                                gatewayFilterSpec.filters(jwtFilter);
                                gatewayFilterSpec.preserveHostHeader();
                                gatewayFilterSpec.removeRequestHeader(HttpHeaders.AUTHORIZATION);
                                return gatewayFilterSpec;
                            })
                            .uri(cos3URI)
                    )
                    .build();
        }
    

    自定义过滤器

    GlobalFilters

    这种过滤器针对的是全局路由,还区分了 pre 和 post 两种阶段,确定代码是指在路由前执行还是路由后执行。
    
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public GlobalFilter a() {
        return (exchange, chain) -> {
            log.info("pre");
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                log.info("post");
            }));
        };
    }
    

    GatewayFilter

    这种过滤器针对的单独的路由,需要自己配置。
    
        @Bean
        public GatewayFilter sessionAuthenticationFilter() {
            return (exchange, chain) -> {
                String userMobile = exchange.getAttribute("User");
    
                if (userMobile == null) {
                    log.info("session中不存在用户信息!");
                    ServerHttpResponse response = exchange.getResponse();
                    response.setStatusCode(HttpStatus.FORBIDDEN);
                    return Mono.empty();
                }
    
                return chain.filter(exchange);
            };
        }
    
    

    转发日志

    在VM Options设置启动参数 -Dreactor.netty.http.server.accessLogEnabled=true
    

    在logback.xml文件配置

     <appender name="accessLog" class="ch.qos.logback.core.FileAppender">
            <file>access_log.log</file>
            <encoder>
                <pattern>%msg%n</pattern>
            </encoder>
        </appender>
        <appender name="async" class="ch.qos.logback.classic.AsyncAppender">
            <appender-ref ref="accessLog" />
        </appender>
    
        <logger name="reactor.netty.http.server.AccessLog" level="INFO" additivity="false">
            <appender-ref ref="async"/>
        </logger>
    

    相关文章

      网友评论

          本文标题:spring cloud gateway实践

          本文链接:https://www.haomeiwen.com/subject/ybxbictx.html