写点什么

极速体验 SpringCloud Gateway

作者:程序员欣宸
  • 2022 年 9 月 30 日
    广东
  • 本文字数:6034 字

    阅读完需:约 20 分钟

极速体验SpringCloud Gateway

欢迎访问我的 GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos


  • 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 上下载本次实战的源码,地址和链接信息如下表所示:


  • 这个 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: eurekaserver:  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@EnableEurekaServerpublic 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: 8081spring:  application:    name: provider
复制代码


  • 启动类 ProviderApplication.java:


package com.bolingcavalry.provider;
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplicationpublic 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: trueeureka: 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;
@SpringBootApplicationpublic 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 文档入手深入学习。

欢迎关注 InfoQ:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...


发布于: 刚刚阅读数: 3
用户头像

搜索"程序员欣宸",一起畅游Java宇宙 2018.04.19 加入

前腾讯、前阿里员工,从事Java后台工作,对Docker和Kubernetes充满热爱,所有文章均为作者原创,个人Github:https://github.com/zq2599/blog_demos

评论

发布
暂无评论
极速体验SpringCloud Gateway_Java_程序员欣宸_InfoQ写作社区