SpringCloud中Gateway的使用教程详解

2022-11-13 14:11:55 教程 详解 SpringCloud

1.基础教程

pom.xml

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.6</version>
    </parent>
    <dependencies>
        <!--gateway不是通过servlet启动的,不需要spring-boot-starter-WEB-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>
   
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2020.0.6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement> 

application.yml

server:
  port: 8081

SpringBoot启动类

@SpringBootApplication
public class GateWayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GateWayApplication.class,args);
    }
    @Bean
    public RouteLocator myRoutes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(p -> p
                        .path("/**")
                        .filters(f -> f.addRequestParameter("aa","bb"))
                        .uri("Http://localhost:18080"))

                .build();
    }
}

以上代码,是做了个路由:如果url的path符合正则“/**”则给请求添加一个aa=bb的参数然后转发到http://localhost:18080,。

如果访问http://localhost:8081/get,则最终会请求http://localhost:18080/get?aa=bb

我们再添加一个route。

@SpringBootApplication
public class GateWayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GateWayApplication.class,args);
    }
    @Bean
    public RouteLocator myRoutes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(p ->p
                        .method("POST")
                        .uri("http://localhost:18081")
                )
                .route(p -> p
                        .path("/**")
                        .filters(f -> f.addRequestParameter("aa","bb"))
                        .uri("http://localhost:18080"))

                .build();
    }
}

以上代码添加了一个如果是POST访问,则转发到http://localhost:18081。

那么如果我们使用POST的http://localhost:8081/aaa,则会转发到http://localhost:18081/aaa.

值得注意的是,如果这两个route换下位置,path=/** 的route放在method=post的上面,则会产生另外的情况,就是会转发到18080上去,因为POST的http://localhost:8081/aaa也会匹配上/** .这些route是有先后顺序的。

可以看出route有一个重要的概念,就是条件predicate,命中了什么条件就会被转发到哪里。

Predicate来自于java8的接口。Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将Predicate组合成其他复杂的逻辑(比如:与,或,非)。可以用于接口请求参数校验、判断新老数据是否有变化需要进行更新操作。add–与、or–或、negate–非。

spring cloud Gateway内置了许多Predict,这些Predict的源码在org.springframework.cloud.gateway.handler.predicate包中,如果读者有兴趣可以阅读一下。现在列举各种Predicate如下图:

可以看到这有几种类型的Predict,而我们刚刚使用的就是METHOD和Path这两种,当然你可以选择其他的。

2.将配置放在配置文件里

总是写些Bean实际上还是不爽,不如我们放在配置文件里面。放配置文件里面可以减少代码量,最重要的是,如果配合sprinGCloudconfig,可以做到在线更新,这就很爽了。

我们将上面的那个bean注释掉,然后把上面的写到配置文件里。

server:
  port: 8081
spring:
  cloud:
    gateway:
      routes:
      - id: my_method_route
        uri: http://localhost:18081
        predicates:
        - Method=POST
      - id: my_path_route
        uri: http://localhost:18080
        predicates:
        - Path=/**

注意一些关键的地方,要约定大于配置比如:Method=POST Path=/**

3.放在springcloud里面

目前我们都是一个单机springboot,跟springcloud没有关系。我们尝试将这段配置放在Nacos的config里面。

nacos新建gateway-test.yaml,类型yaml,内容如下:

spring:
  cloud:
    gateway:
      routes:
      - id: my_path_route
        uri: http://localhost:18080
        predicates:
        - Path=/**
      - id: my_method_route
        uri: http://localhost:18081
        predicates:
        - Method=POST

java项目的pom修改下,添加了nacos的服务发现和配置文件。

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.6</version>
    </parent>
    <dependencies>
        <!--<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        
        <!--springboot2.4版本之后需要添加下面依赖才能加载bootstrap.yml-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>



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

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2020.0.6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- SpringCloud Alibaba 微服务 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2021.1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

添加bootstrap.yml,添加了nacos的一些配置

spring:
  application:
    name: gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml

修改application.yml

server:
  port: 8081
spring:
  profiles:
    active: test

此时

{{spring.application.name}}-{{spring.profiles.active}}.{{spring.cloud.nacos.config.file-extension}}

正好等于我们刚才在nacos上建的gateway-test.yaml

最后是java启动执行,发现gateway就从nacos拉取配置文件生效了。

4.使用服务名而不是IP

我们的uri转发的都是具体的ip地址,那么真正在微服务的时候,肯定转发的是服务名而不是ip地址。

修改gateway-test.yaml里面的uri,boot-cloud和boot-cloud1是我们创建的另两个服务。

spring:
  cloud:
    gateway:
      routes:
      - id: my_path_route
        uri: lb://boot-cloud
        predicates:
        - Path=/**
      - id: my_method_route
        uri: lb://boot-cloud1
        predicates:
        - Method=POST

lb是对服务进行负载均衡的意思,需要添加依赖

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

启动后,就可以对服务进行转发了。

到此这篇关于SpringCloud中Gateway的使用教程详解的文章就介绍到这了,更多相关SpringCloud Gateway内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

相关文章