SpringCloud Gateway用法详解

SpringCloud Gateway用法详解,第1张

SpringCloud Gateway用法详解 零、人在月球

目录

零、人在月球

一、功能简介

1、网关是一个服务:

二、Gateway 断言

1、path断言

2、Query断言

3、Method断言

4、Host断言

5、cookie断言

6、Header断言

7、Weight 权重路由

8、After 时间路由

9、Before 时间路由

10、Between时间区间路由

11、灰度发布

三、Gateway 过滤器

1、增加header 请求头

2、新增动态header请求头

3、设置请求头 过滤器配置,修改移除请求头

4、PreserverHostHeader

5、重写response加密密码

6、response去重

7、路径带前缀 请求/get/app 其实是/prefix/get

8、配置30几 跳转到指定地址

9、修改状态码

10、转发地址

11、去掉增加 请求路径中部分层级

12、重试过滤器

13、过滤器设置请求大小

14、spring-session

15、默认filter

四、熔断机制 

1、老熔断

2、熔断机制-新的

五、限流配置

1、增加依赖

2、配置redis:spring.redis.database:XX

3、配置keyResolver,参考类RateLimiteConfig

4、ym配置spring.cloud.gateway.routes

5、当发生限流,会向redis存储两个数据 .限流返回状态码是429

6、配置文件RateLimiteConfig.java

六、自定义谓词配置类

1、配置类UserNameCheckRoutePredicateFactory.java

2、配置项

七、自定义过滤器

1、配置类

pre配置类

post过滤器

3、配置文件

八、全局过滤器

九、网关超时配置

十、元数据 metadata

十一、gateway内置API与跨域

1、API说明:

2、打开端点配置

3、跨域请求:


一、功能简介 1、网关是一个服务:

路由:使用webflux、缓存、权重和灰度发布、随机算法

过滤器:有序

限流:内置令牌桶+Redis 整合GoogleGuava

权限

hystrix 熔断

声明周期

二、Gateway 断言

断言:predicates 多断言可以配合使用

1、path断言

predicates:

        -Path=/mg

2、Query断言

参数值可以写正则,也可以只写参数名

predicates:

        -Query=foo,ba.

3、Method断言

predicates:

        -Method=get

4、Host断言

predicates:

        -Host=mashibing.com

5、cookie断言

predicates:

        -cookie=name,yiming

6、Header断言

predicates:

        -Header=reqId,9090d+ #正则表达式d+ 数字

7、Weight 权重路由
- id: weight2
  uri: http://localhost:6601
  predicates:
    - Path=/api
@Configuration
public class RateLimiteConfig{

    //ip限流  1s 100次
    //userId限流 1s 100次
    //路径限流
    @Bean
    @Primary  #如果不使用 @Primary 注解,项目启动会报错
    public KeyResolver pathKeyResolver(){
        //写法1
//        return exchange-> Mono.just(
//                exchange.getRequest()
//                .getPath()
//                .toString()
//        );
        //写法2
        return new KeyResolver(){
            @Override
            public Mono resolve(ServerWebExchange exchange){
                return Mono.just(exchange.getRequest()
                .getPath()
                .toString());
            }
        };
    }
    //根据请求IP限流
    @Bean
    public KeyResolver ipKeyResolver(){
        return exchange -> Mono.just(
                exchange.getRequest()
                .getRemoteAddress()
                .getHostName()
        );
    }
    //根据userid限流
    @Bean
    public KeyResolver userKeyResolver(){
        return exchange -> Mono.just(
                exchange.getRequest()
                .getQueryParams()
                .getFirst("userId")
        );
    }
}
六、自定义谓词配置类

可以保存数据库,存储。

1、配置类UserNameCheckRoutePredicateFactory.java
package com.pig4cloud.pig.demo.util;

import com.mysql.cj.util.StringUtils;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;

import javax.validation.constraints.NotEmpty;
import java.util.function.Predicate;


@Component
public class UserNameCheckRoutePredicateFactory extends AbstractRoutePredicateFactory {

    public UserNameCheckRoutePredicateFactory(){
        super(Config.class);
    }
    @Override
    public Predicate apply(UserNameCheckRoutePredicateFactory.Config config) {
        //写法1
        return new Predicate() {
            @Override
            public boolean test(ServerWebExchange exchange) {
                String userName = exchange.getRequest().getQueryParams().getFirst("userName");
                if(StringUtils.isNullOrEmpty(userName)){
                    return false;
                }
                //检查请求参数中userName是否与配置的数据相同,如果相同则允许访问,否则不允许访问
                if(userName.equals(config.getName())){
                    return true;
                }
                return false;
            }
        };
    }

    @Validated
    public static class Config{
        @NotEmpty
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}
2、配置项
spring.cloud.gateway
routes:
    -id: Auth_route
     uri: lb://mima-cloud-producer
     order:1
     predicates:
        -Path= 
@Component
public class MyAddRequestHeaderGatewayFilterFactory extends AbstractGatewayFilterFactory {
    public MyAddRequestHeaderGatewayFilterFactory(){super(Config.class);}

    @Override
    public GatewayFilter apply(Config config){
        //写法一
//        return new GatewayFilter() {
//            @Override
//            public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//                System.out.println("MyAddRequestHeaderGatewayFilterFactory.apply is run...");
//                //exchange.getRequest().mutate() //目的是转化为装饰类,否则request为只读的,不能 *** 作
//                //header方法用来设置header的值
//                ServerHttpRequest request = exchange.getRequest().mutate().header(config.getName(),config.getValue()).build();
//                //将request包裹继续向下传递
//                return chain.filter(exchange.mutate().request(request).build());
//            }
//        }
        return (exchange, chain) -> {
            System.out.println("MyAddRequestHeaderGatewayFilterFactory.apply is run...");
            //exchange.getRequest().mutate() //目的是转化为装饰类,否则request为只读的,不能 *** 作
            //header方法用来设置header的值
            ServerHttpRequest request=exchange.getRequest().mutate().header(config.getName(),config.getValue()).build();
            return chain.filter(exchange.mutate().request(request).build());
             //response可以直接写
//            exchange.getResponse().getHeaders().set(config.getName(),config.getValue());
//            return chain.filter(exchange);
        };
    }

    @Validated
    public static class Config{
        @NotEmpty
        private String name;
        @NotEmpty
        private String value;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }
}
post过滤器
@Component
public class PostLogGatewayFilterFactory extends AbstractGatewayFilterFactory {
    @Override
    public GatewayFilter apply(Object config){
        return (exchange, chain) -> {
            return chain.filter(exchange).then(Mono.fromRunnable(()-> {
                System.out.println("PostLogGatewayFilterFactory is run...");
            }));
        };
    }
}
3、配置文件
spring.cloud.gateway.routes
-id: MyFilter
uri: lb://mima-cloud
order: 1
predicates:
    -Path=
@Configuration
public class GlobalFilterConfig {
    //order 越小,越先执行
    @Bean
    @Order(-1)
    public GlobalFilter globalFilter1(){
        return (exchange, chain) -> {
            System.out.println("pro filter globalFilter1...");
            return chain.filter(exchange).then(Mono.fromRunnable(()->{
                System.out.println("post filter globalFilter1...");
            }));
        };
    }
    @Bean
    @Order(1)
    public GlobalFilter globalFilter2(){
        return (exchange, chain) -> {
            System.out.println("pro filter globalFilter2...");
            return chain.filter(exchange).then(Mono.fromRunnable(()->{
                System.out.println("post filter globalFilter2...");
            }));
        };
    }
}

应答顺序为:pro filter globalFilter1...

pro filter globalFilter2...

post filter globalFilter2...

post filter globalFilter1...

九、网关超时配置

spring.cloud.gateway.httpclient.connect-timeout=1000 #连接超时 毫秒

spring.cloud.gateway.httpclient.response-timeout=5s #应答超时 java.time.Duration http状态码504

十、元数据 metadata 十一、gateway内置API与跨域 1、API说明:

/actuator/gateway/routes/{id} ,method=[DELETE] 删除单个路由

/actuator/gateway/routes/{id},method=[POST] 新增单个路由

/actuator/gateway/routes/{id},method=[GET] 查看单个路由

/actuator/gateway/routes ,method=[GET] 查看路由列表

/actuator/gateway/refresh,method=[POST] 路由刷新

/actuator/gateway/globalfilters,method=[GET]获取全局过滤器列表

/actuator/gateway/routefilters,method=[GET] 路由过滤器工厂列表

2、打开端点配置
management.endpoint.gateway.enabled=true
3、跨域请求:

配置文件-直接引用即可

package com.pig4cloud.pig.demo.util;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.cors.reactive.CorsUtils;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

@Configuration
public class CorsConfig {
    private static final String MAX_AGE="18000L";
 
    @Bean
    public WebFilter corsFilter(){
        return (ServerWebExchange ctx, WebFilterChain chain)->{
            System.out.println("corsFilter...  run");
            ServerHttpRequest request = ctx.getRequest();
            if(!CorsUtils.isCorsRequest(request)){
                return chain.filter(ctx);
            }
            HttpHeaders requestHeaders=request.getHeaders();
            ServerHttpResponse response = ctx.getResponse();
            HttpMethod requestMethod= requestHeaders.getAccessControlRequestMethod();
            HttpHeaders headers=response.getHeaders();
            headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestHeaders.getOrigin());
            headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders.getAccessControlAllowHeaders());
            if(requestMethod!=null){
                headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS,requestMethod.name());
            }
            //携带cookie
            headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
            headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,"*");
            headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE);
            if(request.getMethod() == HttpMethod.OPTIONS){
                response.setStatusCode(HttpStatus.OK);
                return Mono.empty();
            }
            return chain.filter(ctx);
        };
    }
}

荆轲刺秦王!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5694593.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存