1. Gateway簡介
????????Gateway網關是微服務架構中不可或缺的組件,是微服務架構中的統一入口,它作為所有客戶端請求的第一道防線,負責請求的路由、過濾和聚合。
Gateway核心功能
路由(Routing)
- 根據請求路徑、Header、參數等將請求路由到不同微服務
過濾(Filtering)
-
前置過濾器:認證、鑒權、請求改寫
-
后置過濾器:響應改寫、添加Header
負載均衡
-
熔斷降級
-
集成Hystrix或Resilience4j實現熔斷機制
限流
- 基于Redis等實現分布式限流
2. 搭建網關服務
2.1 創建網關模塊,導依賴
-
創建模塊
-
啟動類
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class GatewayApplication {public static void main(String[] args) {SpringApplication.run(GatewayApplication.class,args);}
}
-
pom導入依賴
<?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>cloud-demo</artifactId><groupId>com.itgaohe</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>gateway-service</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><dependencies><!--網關--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!--nacos服務發現依賴--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--openfeign依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--負載均衡依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency></dependencies></project>
-
?yml配置文件
server:port: 10010 # 網關端口
spring:application:name: gatewayservice # 服務名稱cloud:nacos:server-addr: localhost:8848 # nacos地址discovery:username: nacospassword: nacosgateway:# 。。。globalcors: # 全局的跨域處理add-to-simple-url-handler-mapping: true # 解決options請求被攔截問題corsConfigurations:'[/**]':allowedOrigins: # 允許哪些網站的跨域請求- "http://127.0.0.1:8849"allowedMethods: # 允許的跨域ajax的請求方式- "GET"- "POST"- "DELETE"- "PUT"- "OPTIONS"allowedHeaders: "*" # 允許在請求中攜帶的頭信息allowCredentials: true # 是否允許攜帶cookiemaxAge: 360000 # 這次跨域檢測的有效期routes: # 網關路由配置- id: user-service # 路由id,自定義,只要唯一即可# uri: http://127.0.0.1:8081 # 路由的目標地址 http就是固定地址uri: lb://userservice # 路由的目標地址 lb就是負載均衡,后面跟服務名稱predicates: # 路由斷言,也就是判斷請求是否符合路由規則的條件- Path=/user/** # 這個是按照路徑匹配,只要以/user/開頭就符合要求- id: order-service # 路由id,自定義,只要唯一即可# uri: http://127.0.0.1:8081 # 路由的目標地址 http就是固定地址uri: lb://orderservice # 路由的目標地址 lb就是負載均衡,后面跟服務名稱predicates: # 路由斷言,也就是判斷請求是否符合路由規則的條件- Path=/order/** # 這個是按照路徑匹配,只要以/user/開頭就符合要求filters: #路由過濾器- AddRequestHeader=tou,itgaohe # 添加請求頭 : 格式 k,vdefault-filters: # 默認過濾項- AddRequestHeader=tou2,itgaohe22 # 添加請求頭
? ? ? ? Gateway網關搭建好之后,需要在服務生產者(order-service)設置攔截器,在網關服務的配置文件中配置全局攔截器,攜帶請求頭,通過網關進行請求的話攜帶請求頭,攔截器放行,如果請求不是從網關過來的,則不會攜帶強求頭,攔截器會進行請求攔截
2.2 攔截器
-
定義網關攔截器
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;/*** 網關攔截器,用于校驗請求是否通過網關訪問。*/
@Component
public class GateInterceptor implements HandlerInterceptor {/*** 在處理請求之前進行攔截操作。* * @param request HTTP請求對象* @param response HTTP響應對象* @param handler 請求處理器* @return 如果校驗通過返回true,否則返回false* @throws Exception 異常信息*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 設置響應內容類型和字符編碼response.setContentType("html/text;charset=utf8");// 從請求頭中獲取"tou"字段的值String tou = request.getHeader("tou");// 校驗"tou"字段是否為"itgaohe"if ("itgaohe".equals(tou)) {// 校驗通過,繼續后續處理return true;} else {// 校驗未通過,設置錯誤狀態碼并返回提示信息response.setStatus(502);response.getWriter().write("沒有通過網關訪問");return false;}}
}
-
在核心配置中進行攔截器配置
import com.itgaohe.order.interceptor.GateInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate GateInterceptor gateInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(gateInterceptor).addPathPatterns("/**");}
}
3.跨域問題
跨域問題的核心表現
當以下任意一項不同時,就會觸發跨域限制:
-
協議不同(http vs https)
-
域名不同(a.com vs b.com)
-
端口不同(8080 vs 8081)
? ? ? ? Gateway解決跨域問題采用的是CORS方案,只需要在yml配置文件中進行配置就行
# 。。。globalcors: # 全局的跨域處理add-to-simple-url-handler-mapping: true # 解決options請求被攔截問題corsConfigurations:'[/**]':allowedOrigins: # 允許哪些網站的跨域請求- "http://127.0.0.1:8849"allowedMethods: # 允許的跨域ajax的請求方式- "GET"- "POST"- "DELETE"- "PUT"- "OPTIONS"allowedHeaders: "*" # 允許在請求中攜帶的頭信息allowCredentials: true # 是否允許攜帶cookiemaxAge: 360000 # 這次跨域檢測的有效期