SpringCloud组件之Gateway

SpringCloud组件之Gateway

网关的概述

API网关是一个服务器,是系统对外的唯一入口。
网关的作用:授权、日志、限流

SpringCloud Gateway的使用

implementation 'org.springframework.cloud:spring-cloud-starter-gateway'

application.yml

	spring:
		cloud:
			gateway:
				routes:
					- id: mes_routh
					  predicates:			//断言
					  	- Path=/mes/**
					filters:						//过滤器
						- StripPrefix=1
						- Auto=Authorization
					uri: lb://mes

SpringCloud Gateway的核心概念

Routes(路由)

predicates(断言)

当断言为true的时候才会进行路由,当存在多个断言的时候,断言之间的存在关系为&&关系

@Component
public class AutoRoutePredicateFactory extends AbstractRoutePredicateFactory<AutoRoutePredicateFactory.Config> {
    
    public AutoRoutePredicateFactory() {
        super(Config.class);
    }

    private static final String NAME_KEY = "name";

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(NAME_KEY);
    }
    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return new GatewayPredicate() {
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
               HttpHeaders headers =  serverWebExchange.getRequest().getHeaders();
              List<String> headerList = headers.get(config.getName());

              if (headerList != null && headerList.size() > 0) {
                  if (!"null".equals(headerList.get(0).toLowerCase())){
                      return true;
                  }
              }
              return false;
            }
        };
    }

    public static class Config{

        private String name;

        public String getName() {
            return name;
        }

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

Filter

Filter分为两类:GlobalFilter和RouteFilter

//@Order(0)
@Component
public class ActDefineGatewayFilterFactory extends AbstractGatewayFilterFactory<ActDefineGatewayFilterFactory.Config> {
    
    

    public ActDefineGatewayFilterFactory() {
    
    
        super(Config.class);
    }

    private static final String NAME_KEY = "name";

    @Override
    public List<String> shortcutFieldOrder() {
    
    
        return Arrays.asList(NAME_KEY);
    }

    @Override
    public GatewayFilter apply(Config config) {
    
    

        //pre   post

        return new GatewayFilter() {
    
    
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    
    
                System.out.println("conf:" + config.getName());
                //TODO 处理前
                return chain.filter(exchange).then(Mono.fromRunnable(()->{
    
    
                    //TODO 处理后回调
                    System.out.println("回调完成");
                }));
            }
        };
    }

    public static class Config{
    
    
        private String name;

        public String getName() {
    
    
            return name;
        }

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

SpringCloud Gateway 限流

组件提供了关于redis的限流机制:

compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis-reactive', version: '2.3.4.RELEASE'

application.yml

spring:
	cloud:
		routes:
			-	id:	mes_routh
				predicates:
					- Path=/mes/**
				filters:
				-  name: RequestRateLimiter
					args:
					redis-rate-limiter.replenishRate: 1
              		redis-rate-limiter.burstCapacity: 2
           		   redis-rate-limiter.requestedTokens: 1

其中采用了令牌桶算法。

SpringCloud Gateway 动态路由

组件:

compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version: '2.3.4.RELEASE'

配置:

management:
  endpoints:
    web:
      exposure:
        include: "*"

API

/actuator/gateway/routes

查看路由信息

[
  {
    
    
    "predicate": "(Hosts: [**.addrequestheader.org] && Paths: [/headers], match trailing slash: true)",
    "route_id": "add_request_header_test",
    "filters": [
      "[[AddResponseHeader X-Response-Default-Foo = 'Default-Bar'], order = 1]",
      "[[AddRequestHeader X-Request-Foo = 'Bar'], order = 1]",
      "[[PrefixPath prefix = '/httpbin'], order = 2]"
    ],
    "uri": "lb://testservice",
    "order": 0
  }
]

/actuator/gateway/refresh

刷新路由:POST请求

/gateway/routes/{id_route_to_create}

创建路由:POST请求
删除路由:DELETE请求

动态路由是基于内存进行存储的。如果要对路由进行持久化,需要重写RouteDefinitionRepository

@Component
public class RedisRouteDefinitionRepository implements RouteDefinitionRepository {

    private final static String GATEWAY_ROUTE_KEY = "gateway_dynamic_route";

    @Autowired
    RedisTemplate<String, String> redisTemplate;


    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        List<RouteDefinition> routeDefinitionList = new ArrayList<>();
        redisTemplate.opsForHash().values(GATEWAY_ROUTE_KEY).forEach(route -> {
            routeDefinitionList.add(JSONObject.parseObject(route.toString(), RouteDefinition.class));
        });
        return Flux.fromIterable(routeDefinitionList);
    }

    @Override
    public Mono<Void> save(Mono<RouteDefinition> route) {
        return route.flatMap(routeDefinition -> {
            redisTemplate.opsForHash().put(GATEWAY_ROUTE_KEY,routeDefinition.getId(), JSON.toJSONString(routeDefinition));
            return Mono.empty();
        });
    }

    @Override
    public Mono<Void> delete(Mono<String> routeId) {
        return routeId.flatMap(id ->{
            if (redisTemplate.opsForHash().hasKey(GATEWAY_ROUTE_KEY,id)){
                redisTemplate.opsForHash().delete(GATEWAY_ROUTE_KEY,id);
                return Mono.empty();
            }

            return Mono.defer(()->Mono.error(new Exception("routeDefinition not found " + routeId)));
        });
    }
}

猜你喜欢

转载自blog.csdn.net/baidu_41934937/article/details/109352527