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. LeetCode 解题目录

    0001. 两数之和(Java) 0003. 无重复字符的最长子串(Java) 0172. 阶乘后的零 (Java) 0287. 寻找重复数(Java)

  2. paddlepaddle实现猫狗分类

    目录 1.预备工作 1.1 数据集准备 1.2 数据预处理 2.训练 2.1 模型 2.2 定义训练 2.3 训练 3.预测 4.参考文献 声明:这是我的个人学习笔记,大佬可以点评,指导,不喜勿喷.实 ...

  3. 牛客第十场Rikka with Prefix Sum

    由于其中的2操作非常多,我们就需要将其快速的更改,就会用到组合数的东西 其实自己手写一下就可以发现对于一个点增加的值在经过不断地前缀和累加过程中对于一点的贡献满足杨辉三角 所以我们就需要记录一下其中的 ...

  4. Oracle JDK与OpenJDK到底有什么不同?

    ​不知道各位developer平时是否有过疑问,Oracle JDK是什么,OpenJDK又是什么? Oracle JDK便是平常我们在windows系统上做开发使用的JDK,又称作SUN JDK.O ...

  5. Jibx 只绑定需要的字段

    栗子:     binding.xml   <?xml version="1.0" encoding="UTF-8"?> <binding&g ...

  6. Jmeter脚本录制--HTTP代理服务器

    Jmeter脚本录制功能依赖第三方工具Badboy,所以在安装了Jmeter之后,还需要再安装一个工具. Badboy本身自带浏览器,相关操作只能在Badboy上进行操作,偶尔可能会遇到浏览器兼容的问 ...

  7. MemCached的工具类。获取cached中的所有key

    package com.ibs.auth.controller; import java.io.UnsupportedEncodingException; import java.util.Date; ...

  8. SpringMVC学习笔记之---简单入门

    SpringMVC简单入门 (一)什么是MVC设计模式 (1)model:模型数据,业务逻辑 (3)view:呈现模型,与用户进行交互 (3)controller:负责接收并处理请求,响应客户端 (二 ...

  9. 最小化docker镜像

    kubernetes离线安装包,仅需三步 如何让镜像尽可能小 很容器想到from scratch, 就是没任何基础镜像 FROM scratch COPY p / ENTRYPOINT [" ...

  10. AQS之CountDownLatch、Semaphore、CyclicBarrier

    CountDownLatch A synchronization aid that allows one or more threads to wait until a set of operatio ...