• 体验SpringCloud Gateway


    Spring Cloud Gateway是Spring Cloud技术栈中的网关服务,本文实战构建一个SpringCloud环境,并开发一个SpringCloud Gateway应用,快速体验网关服务;

    环境信息

    1. 操作系统:win10(64位)
    2. JDK:1.8.0_181
    3. Maven:3.5.0
    4. Spring Cloud:Greenwich.SR

    源码下载

    如果您不打算写代码,也可以从GitHub上下载本次实战的源码,地址和链接信息如下表所示:

    名称 链接 备注
    项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
    git仓库地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的仓库地址,https协议
    git仓库地址(ssh) git@github.com:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议

    这个git项目中有多个文件夹,本章的源码在gatewaydemo文件夹下,如下图红框所示:
    在这里插入图片描述

    整体设计

    本次实战的源码涉及到三个应用:注册中心、服务提供者、网关,它们的关系和业务逻辑如下图:
    在这里插入图片描述
    整个工程基于maven构建,采用父子结构,父工程名为gatewaydemo,里面有三个modular,分别是:eureka()注册中心)、provider(服务提供者)、网关(gateway),在IDEA上呈现的结构如下图所示:
    在这里插入图片描述
    准备完毕,开始编码吧;

    创建父工程

    1. 创建名为gatewaydemo的maven工程,pom.xml内容如下,这是个典型的父子工程pom,dependencyManagement节点接管了版本匹配:
    <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.6.RELEASE</version>
            <relativePath/>
        </parent>
        
        <groupId>com.bolingcavalry</groupId>
        <artifactId>gatewaydemo</artifactId>
        <packaging>pom</packaging>
        <version>1.0-SNAPSHOT</version>
        <modules>
            <module>eureak</module>
            <module>provider</module>
            <module>gateway</module>
        </modules>
    
        <properties>
            <java.version>1.8</java.version>
            <spring-boot.version>2.1.6.RELEASE</spring-boot.version>
            <maven-compiler-plugin.version>3.5</maven-compiler-plugin.version>
            <maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
            <maven-failsafe-plugin.version>2.18.1</maven-failsafe-plugin.version>
            <maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
            <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
        </properties>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    </project>
    
    1. 如果您是用IDEA创建的工程,那么IDEA可能会在pom.xml所在目录自动创建src文件夹,请手动将其删除,因为用不上;

    eureka工程

    1. 接下来是创建注册中心,鼠标右键点击gatewaydemo文件夹,选择"New -> Module":
      在这里插入图片描述
    2. 在弹出窗口选择Spring Initializr,如下图:
      在这里插入图片描述
    3. 接下来的窗口填写Group、Artifact(这里是eureka)、Version等信息,其余的默认,即可完成子工程的创建;
    4. 新的eureka模块的pom.xml,请修改成如下内容,可见除了指定父工程,还依赖了spring-cloud-starter-netflix-eureka-server
    <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>gatewaydemo</artifactId>
            <groupId>com.bolingcavalry</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>eureak</artifactId>
        <packaging>war</packaging>
    
        <name>eureak Maven Webapp</name>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <finalName>${project.artifactId}</finalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    
    1. srcmain esources目录下新增application.yml文件,内容如下,这是普通的注册中心设置:
    spring:
      application:
        name: eureka
    server:
      port: 8080
    
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:${server.port}/eureka/
        fetch-registry: false
        register-with-eureka: false
    
    1. java文件只有一个,就是启动类,还通过注解EnableEurekaServer开启了注册中心服务:
    package com.bolingcavalry.eureka;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    @SpringBootApplication
    @EnableEurekaServer
    public class EurekaApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(EurekaApplication.class, args);
        }
    }
    
    1. 以上就是注册中心eureka的内容,运行EurekaApplication即可启动服务,访问8080端口的结果如下:
      在这里插入图片描述
      现在注册中心已经就绪,开始编写服务提供者provider应用的代码吧。

    provider工程

    1. 在gatewaydemo下创建一个子工程,名为provider,pom.xml内容如下,可见用到了spring-boot-starter-web和spring-cloud-starter-netflix-eureka-client这两个依赖,分别用来支持web服务和注册发现:
    <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>gatewaydemo</artifactId>
            <groupId>com.bolingcavalry</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>provider</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <finalName>${project.artifactId}</finalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    
    1. 配置文件application.yml如下,指定了注册中心地址,并且自身端口为8081:
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8080/eureka/
    server:
      port: 8081
    spring:
      application:
        name: provider
    
    1. 启动类ProviderApplication.java:
    package com.bolingcavalry.provider;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class ProviderApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ProviderApplication.class, args);
        }
    }
    
    1. 增加一个controller,用于响应web请求,注意hello方法会从请求的header中取出名为extendtag的属性值,返回给浏览器:
    package com.bolingcavalry.provider.controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpServletRequest;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    @RestController
    @RequestMapping("/hello")
    public class HelloController {
    
        @RequestMapping(value = "time", method = RequestMethod.GET)
        public String hello(HttpServletRequest request){
    
            return "hello, "
                    + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())
                    + ", extendtag ["
                    + request.getHeader("extendtag")
                    + "]";
        }
    }
    
    1. 启动应用,再次刷新eureka的页面localhost:8080,可见provider应用已经注册上去了,如下图红框所示:
      在这里插入图片描述
    2. 访问地址:http://localhost:8081/hello/time ,这是controller提供的web服务接口,得到响应如下图,因为header中没有名为"extendtag"的属性,因此返回了null:
      在这里插入图片描述
      提供服务的provider已经OK,可以开发网关服务了;

    gateway工程

    1. 在gatewaydemo下创建一个子工程,名为gateway,pom.xml内容如下,可见用到了spring-cloud-starter-gateway和spring-cloud-starter-netflix-eureka-client这两个依赖,分别用来支持网关服务和注册发现:
    <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>gatewaydemo</artifactId>
            <groupId>com.bolingcavalry</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>gateway</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <finalName>${project.artifactId}</finalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    
    1. 配置文件application.yml如下,指定了注册中心地址,并且自身端口为8082,还有开启了网关服务:
    server:
      port: 8082
    
    spring:
      application:
        name: gateway
      cloud:
        gateway:
          discovery:
            locator:
              enabled: true
              lowerCaseServiceId: true
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8080/eureka/
    
    1. 启动类GatewayApplication .java,可见实例化了一个RouteLocator,该实例就是路由规则,具体的功能请参考代码中的注释:
    package com.bolingcavalry.gateway;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.gateway.route.RouteLocator;
    import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
    import org.springframework.context.annotation.Bean;
    
    @SpringBootApplication
    public class GatewayApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(GatewayApplication.class, args);
        }
    
        @Bean
        public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
            return builder.routes()
                    //增加一个path匹配,以"/gateway/hello/"开头的请求都在此路由
                    .route(r -> r.path("/customize/hello/**")
                            //表示将路径中的第一级参数删除,用剩下的路径与provider的路径做拼接,
                            //这里就是"lb://provider/hello/",能匹配到provider的HelloController的路径
                            .filters(f -> f.stripPrefix(1)
                                           //在请求的header中添加一个key&value
                                           .addRequestHeader("extendtag", "geteway-" + System.currentTimeMillis()))
                            //指定匹配服务provider,lb是load balance的意思
                            .uri("lb://provider")
                    ).build();
        }
    }
    
    
    1. 启动应用,再次刷新eureka的页面localhost:8080,可见gateway应用已经注册上去了,如下图红框所示:
      在这里插入图片描述
    2. 访问地址:http://localhost:8082/customize/hello/time ,这是符合前面我们配置的路由规则的路径,customize被删除掉之后,将剩余的路径转发到provider服务,于是请求的真正地址就是provider服务的/hello/time,得到响应如下图,因为gateway在转发的时候给header中设置了名为"extendtag"的属性,因此返回了extendtag是有内容的:
      在这里插入图片描述
      至此,极速体验SpringCloud Gateway的实战就完成了,这里我们只简单的体验了Gateway的一些基本功能,希望本文能帮助您快速搭建环境和开发应用,其实该框架的功能是非常强大的,如果您有兴趣建议从官网的API文档入手深入学习。

    欢迎关注我的公众号:程序员欣宸

    在这里插入图片描述

  • 相关阅读:
    带你正确的使用List的retainAll方法求交集
    Java URL
    如何正确的创建线程
    小贾漫谈——Java反射
    二、定时器的应用
    网络获取json数据并解析
    异步消息处理机制Handler
    手机安全卫士——Splash总结
    click事件触发也有失灵的时候?
    一张图看透微信公众号、企业号、小程序
  • 原文地址:https://www.cnblogs.com/bolingcavalry/p/11462977.html
Copyright © 2020-2023  润新知