体验SpringCloud Gateway
spring cloud gateway是spring cloud技术栈中的网关服务,本文实战构建一个springcloud环境,并开发一个springcloud gateway应用,快速体验网关服务;
环境信息
- 操作系统:win10(64位)
- jdk:1.8.0_181
- maven:3.5.0
- 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上呈现的结构如下图所示:
准备完毕,开始编码吧;
创建父工程
- 创建名为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>
- 如果您是用idea创建的工程,那么idea可能会在pom.xml所在目录自动创建src文件夹,请手动将其删除,因为用不上;
eureka工程
- 接下来是创建注册中心,鼠标右键点击gatewaydemo文件夹,选择"new -> module":
- 在弹出窗口选择spring initializr,如下图:
- 接下来的窗口填写group、artifact(这里是eureka)、version等信息,其余的默认,即可完成子工程的创建;
- 新的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>
- 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
- 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); } }
-
以上就是注册中心eureka的内容,运行eurekaapplication即可启动服务,访问8080端口的结果如下:
现在注册中心已经就绪,开始编写服务提供者provider应用的代码吧。provider工程
- 在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>
- 配置文件application.yml如下,指定了注册中心地址,并且自身端口为8081:
eureka: client: serviceurl: defaultzone: http://localhost:8080/eureka/ server: port: 8081 spring: application: name: provider
- 启动类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); } }
- 增加一个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") + "]"; } }
- 启动应用,再次刷新eureka的页面localhost:8080,可见provider应用已经注册上去了,如下图红框所示:
- 访问地址:http://localhost:8081/hello/time ,这是controller提供的web服务接口,得到响应如下图,因为header中没有名为"extendtag"的属性,因此返回了null:
提供服务的provider已经ok,可以开发网关服务了;
gateway工程
- 在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>
- 配置文件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/
- 启动类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(); } }
- 启动应用,再次刷新eureka的页面localhost:8080,可见gateway应用已经注册上去了,如下图红框所示:
-
访问地址:http://localhost:8082/customize/hello/time ,这是符合前面我们配置的路由规则的路径,customize被删除掉之后,将剩余的路径转发到provider服务,于是请求的真正地址就是provider服务的/hello/time,得到响应如下图,因为gateway在转发的时候给header中设置了名为"extendtag"的属性,因此返回了extendtag是有内容的:
至此,极速体验springcloud gateway的实战就完成了,这里我们只简单的体验了gateway的一些基本功能,希望本文能帮助您快速搭建环境和开发应用,其实该框架的功能是非常强大的,如果您有兴趣建议从官网的api文档入手深入学习。欢迎关注我的公众号:程序员欣宸
上一篇: MySQL——python交互