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. src\main\resources目录下新增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文档入手深入学习。

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

体验SpringCloud Gateway的更多相关文章

  1. spring-cloud-kubernetes与SpringCloud Gateway

    本文是<spring-cloud-kubernetes实战系列>的第五篇,主要内容是在kubernetes上部署一个SpringCloud Gateway应用,该应用使用了spring-c ...

  2. 万字长文:SpringCloud gateway入门学习&实践

    官方文档:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/# ...

  3. 1、springcloud gateway

    参考: https://www.cnblogs.com/babycomeon/p/11161073.html 1.springcloud gateway1.1.依赖-初体验https://www.cn ...

  4. SpringCloud Gateway 测试问题解决

    本文针对于测试环境SpringCloud Gateway问题解决. 1.背景介绍 本文遇到的问题都是在测试环境真正遇到的问题,不一定试用于所有人,仅做一次记录,便于遇到同样问题的干掉这些问题. 使用版 ...

  5. SpringCloud Gateway入门

    本文是介绍一下SpringCloud Gateway简单路由转发使用. SpringCloud Gateway简介 SpringCloud是基于Spring Framework 5,Project R ...

  6. 使用springcloud gateway搭建网关(分流,限流,熔断)

    Spring Cloud Gateway Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 ...

  7. SpringCloud Gateway(八)

    搭建SpringCloud Gateway 创建microservicecloud-springcloud-gateway-9528工程 pom文件 依赖: <dependencies> ...

  8. SpringCloud gateway (史上最全)

    疯狂创客圈 Java 分布式聊天室[ 亿级流量]实战系列之 -25[ 博客园 总入口 ] 前言 ### 前言 疯狂创客圈(笔者尼恩创建的高并发研习社群)Springcloud 高并发系列文章,将为大家 ...

  9. springcloud gateway nullpointerexception (NettyRoutingFilter)

    最近在做一个下载功能时,发现直接调用服务是可以下载的,但是通过gateway路由下载会报NPE异常,具体如下 java.lang.NullPointerException: null at java. ...

随机推荐

  1. jango简介

    Django简介   Django框架简介 MVC框架和MTV框架 MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Mode ...

  2. sort+结构体+简单数学+暴力-例题

    A-前m大的数 还记得Gardon给小希布置的那个作业么?(上次比赛的1005)其实小希已经找回了原来的那张数表,现在她想确认一下她的答案是否正确,但是整个的答案是很庞大的表,小希只想让你把答案中最大 ...

  3. SpringBoot Kafka 整合使用

    前提 假设你了解过 SpringBoot 和 Kafka. 1.SpringBoot 如果对 SpringBoot 不了解的话,建议去看看 DD 大佬 和 纯洁的微笑 的系列博客. 2.Kafka K ...

  4. 【iOS】Interface Builder 预览

    Interface Builder 为最顶层视图提供了 Simulated Metrics,预览用户界面的各种外观设置效果,例如顶部有导航栏或底部有标签栏的效果,如图所示:

  5. windows下hexo+github搭建个人博客

    网上利用hexo搭建博客的教程非常多,大部分内容都大同小异,选择一篇合适的参考,跟着一步一步来即可. 但是,很多博客由于发布时间较为久远等问题,其中某些操作在现在已不再适用,从而导致类似于我这样的小白 ...

  6. umask 默认权限控制和特殊权限

    权限简单介绍: 在Linux中,创建目录或者文件之后总会有默认的权限.共9个,分为三组.分别代表u.g.o(属主.属组.其他用户).r.w.x 也代表各自的权限. r:读   在文件中的权限代表次文件 ...

  7. c#将字符串转化为合理的文件名

    string name = System.Text.RegularExpressions.Regex.Replace(url, "[<>/\\|:\"?*]" ...

  8. MariaDB 修改存储路径后启动失败问题解决

    修改 MariaDB 路径到 home 路径下, 执行 systemctl start mariadb 启动MariaDB 时,报错提示: Job for mariadb.service failed ...

  9. 【JDK】JDK源码分析-CyclicBarrier

    概述 CyclicBarrier 是并发包中的一个工具类,它的典型应用场景为:几个线程执行完任务后,执行另一个线程(回调函数,可选),然后继续下一轮,如此往复. 打个通俗的比方,可以把 CyclicB ...

  10. Leetcode的SQL题解:185. 部门工资前三高的员工

    题目 查询部门工资前三高的员工. 我用的数据库是oracle. 下面是数据表的信息. Employee表数据: | ID | NAME | Salary | DepartmentId | | -- | ...