springCloud Alibaba教程-网关gateway入门实践(上)

1 简易网关工程

pom文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>

    <parent>
        <groupId>com.tdt.platform.cloud</groupId>
        <artifactId>platform-cloud-b-parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <artifactId>cloud-gateway</artifactId>

    <dependencies>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <!-- mac -->
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-resolver-dns-native-macos</artifactId>
            <version>4.1.79.Final</version>
            <classifier>osx-aarch_64</classifier>
        </dependency>
    </dependencies>
</project>

配置文件:

server:
  port: 8000
spring:
  application:
    name: cloud-gateway


  cloud:
    gateway:
      routes:
        - id: product_route
          uri: http://localhost:9002
          order: 1
          predicates:
            - Path=/cloud-product-service/**
          filters:
            - StripPrefix=1

启动类:

@SpringBootApplication
public class GatewayApplication {

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

然后启动网关工程,请求接口如图:
在这里插入图片描述
这样一个简易的网关就搭建好了。

2 整合nacos注册中心

引入依赖:

<!--  nacos discovery  -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<!-- loadbalancer: 新版本cloud已经移除了ribbon -->
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-loadbalancer</artifactId>
 </dependency>

启动类增加注解@EnableDiscoveryClient

配置文件中增加nacos相关配置:

server:
  port: 8000
spring:
  application:
    name: cloud-gateway


  cloud:
    gateway:
      discovery:
        locator:
          # 让gateway可以发现nacos中的微服务
          enabled: false
      routes:
      	  # 路由标识
        - id: product_route
          # 路由指向的目的地,也就是说被转发到那个服务上
          # uri: http://localhost:9002
          uri: lb://cloud-product-service
          # 断言条件判断,所有断言都验证通过,才会执行真正的路由
          predicates:
            # 以/cloud-product-service开头的请求
            - Path=/cloud-product-service/**
          # 过滤器
          filters:
            - StripPrefix=1
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: dev

3 gateway原理

gateway中请求的执行流程,如图:
在这里插入图片描述
执行流程大体如下:

  1. Gateway Client向Gateway Server发送请求
  2. 请求首先会被HttpWebHandlerAdapter进行提取组装成网关上下文
  3. 然后网关的上下文会传递到DispatcherHandler,它负责将请求分发给 RoutePredicateHandlerMapping
  4. RoutePredicateHandlerMapping负责路由查找,并根据路由断言判断路由是否可用
  5. 如果断言成功,由FilteringWebHandler创建过滤器链并调用
  6. 请求会依次次经过PreFilter–微服务–PostFilter的方法,最终返回响应

4 断言

Predicate(断言, 谓词) 用于进行条件判断,只有断言都返回真,才会真正的执行路由。 断言就是说: 满足什么条件才能进行路由转发。

该配置有坑: spring.cloud.gateway.discovery.locator.enabled

4.1 内置路由断言工厂

4.1.1 基于Datetime类型的断言工厂

AfterRoutePredicateFactory: 接收一个日期参数,判断请求日期是否晚于指定日期

– After=2013-01-20T17:42:47.789-07:00[America/Denver]

BeforeRoutePredicateFactory: 接收一个日期参数,判断请求日期是否早于指定日期

– Before=2013-01-20T17:42:47.789-07:00[America/Denver]

BetweenRoutePredicateFactory: 接收两个日期参数,判断请求日期是否在指定时间段内

– Between=Before=2013-01-20T17:42:47.789-07:00[America/Denver],Before=2013-01-20T17:42:47.789-07:00[America/Denver]

4.1.2 基于远程地址的断言工厂

RemoteAddrRoutePredicateFactory接收一个IP地址段,判断请求主 机地址是否在地址段中

– RemoteAddr=192.168.1.1/24

4.1.3 基于Cookie的断言工厂

CookieRoutePredicateFactory:接收两个参数,cookie 名字和一个正则表达式。 判断请求中cookie是否具有给定名称且值与正则表达式匹配

– Cookie=chocolate, ch.

4.1.4 基于Header的断言工厂

HeaderRoutePredicateFactory:接收两个参数,标题名称和正则表达式。 判断请求Header是否具有给定名称且值与正则表达式匹配

– Header=X-Request-Id, \d+

4.1.5 基于Host的断言工厂

HostRoutePredicateFactory:接收一个参数,主机名模式。判断请求的Host是否满足匹配规则。

– Host=**.spring.org

4.1.6 基于Method请求方法的断言工厂

MethodRoutePredicateFactory:接收一个参数,判断请求类型是否跟指定的类型匹配。

– Method=GET

4.1.7 基于Path请求路径的断言工厂

PathRoutePredicateFactory:接收一个参数,判断请求的URI部分是否满足路径规则。

– Path=/order-service/**

4.1.8 基于Query请求参数的断言工厂

QueryRoutePredicateFactory :接收两个参数,请求param和正则表达式, 判断请求参数是否具有给定名称且值与正则表达式匹配。

– Query=baz, ba.

4.1.9 基于路由权重的断言工厂

WeightRoutePredicateFactory:接收一个[组名,权重], 然后对于同一个组内的路由按照权重转发

routes:
- id: weight_route1
uri: host1
predicates:
- Path=/product/**
- Weight=group3, 1
- id: weight_route2
uri: host2
predicates:
- Path=/product/**
- Weight= group3, 9

4.2 自定义路由断言工厂

需求: 仅仅让年龄age在【minAge, maxAge】范围之间的请求通过。

首先在配置中添加Age断言:

– Age 18,65

自定义断言工厂:

@Component
public class AgeRoutePredicateFactory extends AbstractRoutePredicateFactory<AgeRoutePredicateFactory.AgeRoutePredicateConfig> {

    public AgeRoutePredicateFactory() {
        super(AgeRoutePredicateConfig.class);
    }

    // 用于从配置文件中获取参数值赋值到配置类中的属性上
    @Override
    public List<String> shortcutFieldOrder() {
        // 这里的顺序要跟配置文件中的参数顺序一致
        return Arrays.asList("minAge", "maxAge");
    }

    @Override
    public Predicate<ServerWebExchange> apply(AgeRoutePredicateConfig config) {
        return new Predicate<ServerWebExchange>() {
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                String age = serverWebExchange.getRequest().getQueryParams().getFirst("age");
                if (StringUtils.hasText(age)) {
                    int targetAge = Integer.parseInt(age);
                    return targetAge >= config.getMinAge() && targetAge <= config.getMaxAge();
                }

                return false;
            }
        };
    }

    /**
     * 用于接收配置文件中的参数
     */
    public static class AgeRoutePredicateConfig {
        private int minAge;
        private int maxAge;

        public int getMinAge() {
            return minAge;
        }

        public void setMinAge(int minAge) {
            this.minAge = minAge;
        }

        public int getMaxAge() {
            return maxAge;
        }

        public void setMaxAge(int maxAge) {
            this.maxAge = maxAge;
        }
    }
}

测试:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值