概述:什麼是微服務網關?為了解決使用者用戶端在調用微服務系統中的多個消費者工程接口時,需要維護非常多的消費者應用接口位址等資訊,以及可能存在不同應用見的調用跨域等問題,微服務網關元件随即出現。網關作為使用者用戶端和微服務接口之間的一個統一路由及其他功能的元件,友善了使用者用戶端請求接口時不用去關注不同接口的位址路徑等。隻需要統一調用網關的服務即可。微服務網關為一個伺服器服務,是系統對外的唯一入口。網關可以提供身份驗證、監控、負載均衡、緩存、請求分片與管理、等功能。
一、Gateway 簡介
微服務網關比較流行的有Zuul和Gateway。Gateway作為Spring Cloud生态系統中的網關,目标是替代Netfix Zuul,其基于filter鍊的方式在提供了基本的路由之外,還提供了網關的其他功能,如:安全、監控/埋點,和限流等。他是基于Netty的響應式開發模式。
gateway 與 zuul rps 對比。可以看出 Gateway 的RPS 幾乎為Zuul 的 1.6倍。
元件 | RPS(request per second) |
Spring Cloud Gateway | 32212.38 |
Netfix Zuul1x | 20800.13 |
Gateway 核心概念:
1,路由(routes)路由為網關最基礎功能,Gateway網關路由資訊由一個ID、一個目的URL、一組斷言工廠和一組Filter組成,如果斷言為真,則會對改請求路由到對應的url上。
2,斷言(predicates) Java8中的斷言函數,SpringCloud Gateway中的斷言函數允許開發者去定義比對來自使用者端的請求request中的任何資訊,如請求參數和Header中的資訊。
3,過濾器(Filters) 一個标準的Spring webFilter,SpringCloud Gateway中的過濾器分為兩種,針對服務的Gateway Filter 和全局的Global Filter。過濾器可以對請求和響應進行處理。
二、簡單路由配置
準備步驟:
- 建立maven子工程
- pom檔案引入Gateway依賴
- 建立主啟動類
- 編寫配置檔案
1,父工程pom.xml 檔案如下:
<?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>
<groupId>com.xiaohui.springCloud</groupId>
<artifactId>SpringCloud</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
</parent>
<modules>
<module>product_service</module>
<module>order_service</module>
<module>cloud-api-common</module>
<module>eureka_server</module>
<module>eureka_server2</module>
<module>cloud-import-test</module>
<module>consul_product_service</module>
<module>consul_order_service</module>
<module>openfeign_order_service</module>
<module>hystrix_order_service_ipconn</module>
<module>hystrix_order_service_rest</module>
<module>hystrix-turbine</module>
<module>sentinel_order_service_rest</module>
<module>sentinel_order_service_feign</module>
<module>api_gateway_server</module>
</modules>
<!-- 統一jar包管理 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.16.18</lombok.version>
<mysql.version>5.1.47</mysql.version>
<druid.version>1.1.16</druid.version>
<mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
</properties>
<!-- 子子產品繼承之後,提供作用:鎖定版本+子子產品不用寫groupId和version -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- springcloud alibaba -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<!-- maven 插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
2,建立子子產品maven工程,并引入gateway依賴
<?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>SpringCloud</artifactId>
<groupId>com.xiaohui.springCloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>api_gateway_server</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
</project>
3,建立主啟動類
package com.xiaohui.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GatewayServerApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServerApplication.class,args);
}
}
4,編寫配置檔案
server:
port: 8080
spring:
application:
name: api-gateway-server #服務名稱
cloud:
gateway:
routes:
#配置路由: 路由id,路由到微服務的uri,斷言(判斷條件)
- id: product-service #保持唯一
uri: http://127.0.0.1:8001 #目标為服務位址
predicates:
- Path=/payment/** #路由條件 path 路由比對條件
在配置檔案中,我們斷言位置配置了一個當通路網關時以 /payment/開始的請求時都會轉發到uri 配置的位址127.0.0.1:8001上。
5,啟動測試
我們首先保證我們的8001服務正常啟動,以及再啟動gateway 網關服務。都啟動成功後我們通路 http://127.0.0.1:8080/payment/get/1 則會轉發到 http://127.0.0.1:8001/payment/get/1 服務位址上。
至此最簡單的gateway 服務我們搭建完成,并實作了最簡單的服務路由功能。
三、其他路由配置規則:
在上面第二部分我們使用了比較簡單的-Path 路徑比對規則,進行了服務路由。SpringCloud Gateway 處理路徑比對之外還有很多其他的比對規則,比如請求參數、時間等,如下:
例如如下表示:2028年xxxx 時間之後的可以被路由轉發。
spring:
cloud:
gateway:
routes:
#配置路由: 路由id,路由到微服務的uri,斷言(判斷條件)
- id: product-service #保持唯一
uri: http://127.0.0.1:8001 #目标為服務位址
predicates:
- After=2028-03-18T17:32:58.129+08:00[Asia/Shanghai] #路由條件 After 路由比對條件
參考:https://docs.spring.io/spring-cloud-gateway/docs/2.2.7.RELEASE/reference/html/#gateway-request-predicates-factories