SpringCloud Alibaba——Gateway API网关(学习记录)

  1. SpringCloud的第二代网关,未来会取代Zuul
  2. 基于Netty、Reactor、Webflux构建
优点:
  1. 性能强劲,是Zuul 1.X的1.6倍
  2. 功能强大,内置很多实用功能,如转发、监控、限流等
  3. 设计优雅,易扩展
缺点
  1. 依赖Netty与Webflux,不是Servlet编程模型,有一定适应成本
  2. 不能在Servlet容器下工作,不能构建war包
  3. 不支持springboot1.X

核心概念

Router(路由)

SpringCloud Gateway的基础元素,可以理解成一套转发的规则,包含ID、目标URL、Predicate集合以及Filter集合。

Predicate(谓词)

SpringCloud Gateway 使用Predicate实现路由的匹配条件。

Filter(过滤器)

修改请求以及响应。

结构

官网地址
Gateway结构
GatewayClient: 泛指外部请求。
Gateway Handler Mapping: 根据请求匹配是否符合配置的路径,如果匹配就进入到Web Handler。
Gateway Web Handler: 读取配置上的过滤器,交给这些过滤器去处理。
Proxied Service: 被网关代理的微服务。

构建GateWay

引入依赖
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

配置

spring:
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        namespace: 9b74b8d1-94ba-44ea-955b-2e174d42a14a
    gateway:
      discovery:
        locator:
          # 让gateway通过服务发现组件找到其他微服务
          enabled: true
  application:
    name: getway
server:
  port: 8040
management:
  endpoints:
    web:
      exposure:
        include: '*'
  endpoint:
    health:
      show-details: always

启动,访问
访问:{Gateway_url}/{微服务名称}/{访问路径}
访问结果

路由谓词工厂(Router Predicate Factories)

参考文章

自定义路由谓词工厂

yml文件要UTF-8格式,不然启动的时候会报不发将String转LocalTime

spring:
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        namespace: 9b74b8d1-94ba-44ea-955b-2e174d42a14a
    gateway:
      discovery:
        locator:
          # 让gateway通过服务发现组件找到其他微服务
          enabled: true
      routes:
        - id: after_route
          uri: lb://user-center
          predicates:
            - TimeBetween=上午9:00,下午10:49
  application:
    name: getway
server:
  port: 8040
@Data
public class TimeBeweenConfig {
    private LocalTime start;
    private LocalTime end;
}

类名要以RoutePredicateFactory结尾

@Component
public class TimeBetweenRoutePredicateFactory extends AbstractRoutePredicateFactory<TimeBeweenConfig> {
    public TimeBetweenRoutePredicateFactory() {
        super(TimeBeweenConfig.class);
    }

    @Override
    public Predicate<ServerWebExchange> apply(TimeBeweenConfig config) {
        LocalTime start = config.getStart();
        LocalTime end = config.getEnd();
        return exchange -> {
            LocalTime now = LocalTime.now();
            return now.isAfter(start) && now.isBefore(end);
        };
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("start", "end");
    }

    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
        System.out.println(formatter.format(LocalTime.now()));
    }
}

运行结果

过滤器工厂

参考文章

自定义过滤工厂

过滤器生命周期
pre:Gateway转发请求之前
post:Gateway转发请求之后
自定义过滤工厂-方式1

继承:AbstractGatewayFilterFactory
参考:org.springframework.cloud.gateway.filter.factory.RequestSizeGatewayFilterFactory

spring:
  cloud:
    gateway:
      routes:
        filters:
        - name: RequestSize
          args:
            maxSize: 5000000
自定义过滤工厂-方式2

继承:AbstractNameValueGatewayFilterFactory
参考代码:org.springframework.cloud.gateway.filter.factory.AddRequestHeaderGatewayFilterFactory

spring:
  cloud:
    gateway:
      routes:
        filters:
        - AddRequestHeader=S-Header, Bar

这种方式其实是继承了AbstractGatewayFilterFactory,是它的简化版

核心API
修改request

exchange.getRequest().mutate.xxx

修改exchange

exchange.mutate().xxx

传递给下一个过滤器处理

chain.filter(exchange)

拿到响应

exchange.getResponse()

自定义过滤工厂

类名需要以GatewayFilterFactory结尾

@Slf4j
@Component
public class PreLogGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
    @Override
    public GatewayFilter apply(NameValueConfig config) {
        return ((exchange, chain) -> {
            log.info("请求进来了...,{},{}",config.getName(),config.getValue());
            ServerHttpRequest modifiedRequest = exchange.getRequest()
                    .mutate()
                    .build();

            ServerWebExchange modifiedExchage = exchange.mutate()
                    .request(modifiedRequest).build();
            return chain.filter(modifiedExchage);
        });
    }
}
spring:
  cloud:
    gateway:
      discovery:
        locator:
          # 让gateway通过服务发现组件找到其他微服务
          enabled: true
      routes:
          filters:
            - PreLog=a,b

全局过滤器

参考文章

监控Spring Cloud Gateway

参考文章

排错调优技巧

参考文章

过滤器执行顺序

1.在执行顺序中有一个order的值,order值越小,越靠前执行。
2.局部过滤器的Order会按照配置从1开始递增

routes:
  - id: after_route
  uri: lb://user-center
  predicates:
  - TimeBetween=上午9:00,下午10:49
  filters:
  - PreLog=a,b # 1
  - AddReq=b,c # 2
  - AddRes=c,d # 3

3.如果配置了默认过滤器,也是默认从1开始递增。如果有两个相同的order,那么就会先执行默认过滤器的AddResponseHeader -> 自定义的AddResponseHeader -> PrefixPath -> PreLog -> AddRequestHeader

4.如果需要自己控制order,需要返回OrderedGatewayFilter

@Component
public class PreLogGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
    @Override
    public GatewayFilter apply(NameValueConfig config) {
        GatewayFilter filter =  ((exchange, chain) -> {
            log.info("请求进来了...,{},{}",config.getName(),config.getValue());
            ServerHttpRequest modifiedRequest = exchange.getRequest()
                    .mutate()
                    .build();

            ServerWebExchange modifiedExchage = exchange.mutate()
                    .request(modifiedRequest).build();
            return chain.filter(modifiedExchage);
        });
        // 自己设置的order为1000
        return new OrderedGatewayFilter(filter, 1000);
    }
}

Gateway限流

参考文章

总结

1.注册到Nacos,能在Nacos上找到实例,反向代理
2.集成Ribbon,如果有多个实例,也是可以负载均衡
3.容错(默认Hystrix,也可以用Sentinel)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值