體驗SpringCloud Gateway

Spring Cloud Gateway是Spring Cloud技術棧中的網關服務,本文實戰構建一個SpringCloud環境,並開發一個SpringCloud Gateway應用,快速體驗網關服務;java

環境信息

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

源碼下載

若是您不打算寫代碼,也能夠從GitHub上下載本次實戰的源碼,地址和連接信息以下表所示:git

名稱 連接 備註
項目主頁 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協議

</br>程序員

這個git項目中有多個文件夾,本章的源碼在gatewaydemo文件夾下,以下圖紅框所示: 在這裏插入圖片描述github

總體設計

本次實戰的源碼涉及到三個應用:註冊中心、服務提供者、網關,它們的關係和業務邏輯以下圖: 在這裏插入圖片描述 整個工程基於maven構建,採用父子結構,父工程名爲gatewaydemo,裏面有三個modular,分別是:eureka()註冊中心)、provider(服務提供者)、網關(gateway),在IDEA上呈現的結構以下圖所示: 在這裏插入圖片描述 準備完畢,開始編碼吧;web

建立父工程

  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所在目錄自動建立<font color="blue">src</font>文件夾,請手動將其刪除,由於用不上;

eureka工程

  1. 接下來是建立註冊中心,鼠標右鍵點擊<font color="blue">gatewaydemo</font>文件夾,選擇"New -> Module": 在這裏插入圖片描述
  2. 在彈出窗口選擇<font color="blue">Spring Initializr</font>,以下圖: 在這裏插入圖片描述
  3. 接下來的窗口填寫Group、Artifact(這裏是eureka)、Version等信息,其他的默認,便可完成子工程的建立;
  4. 新的eureka模塊的pom.xml,請修改爲以下內容,可見除了指定父工程,還依賴了<font color="blue">spring-cloud-starter-netflix-eureka-server</font>:
<?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中取出名爲<font color="blue">extendtag</font>的屬性值,返回給瀏覽器:
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文檔入手深刻學習。

歡迎關注個人公衆號:程序員欣宸

在這裏插入圖片描述

相關文章
相關標籤/搜索