所謂網關是什么意思?
? ? ? ?相當于就是你們小區家的保安,進出小區都得獲得保安的同意,守護你們小區的生命財產健康,網關也是如此,對每個請求都嚴格把關,將合法的或者是獲得權限的請求進入服務器
網關的功能:
- 身份驗證和權限校驗
- 服務路由、負載均衡
- 請求限流
?一般的常見的網關分別是:
Gateway:基于Spring5中提供的WebFlux,屬于響應式編程的實現,具有更好的性能
zuul:基于servlet的實現,屬于阻塞式編程
搭建網關服務
1.創建新的module,引入SpringCloudGateway的依賴和nacos的服務發現依賴:
<!--nacos服務注冊發現依賴--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--網關gateway依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>
2.編寫路由配置即nacos地址:
server:port: 10010
logging:level:cn.itcast: debugpattern:dateformat: MM-dd HH:mm:ss:SSS
spring:application:name: gatewaycloud:nacos:server-addr: nacos:8848 # nacos地址gateway:routes:- id: user-service # 路由標示,必須唯一uri: lb://userservice # 路由的目標地址predicates: # 路由斷言,判斷請求是否符合規則- Path=/user/** # 路徑斷言,判斷路徑是否是以/user開頭,如果是則符合
總結:
網關搭建的步驟:
1.創建項目,引入nacos服務發現和gateway依賴
2.配置application.yml,包括服務基本信息、nacos地址、路由
路由配置包括:
1.理由id:路由的唯一標識
2.路由目標:路由的目標地址,http代表固定地址,lb代表根據服務名負載均衡
3路由斷言:判斷路由的規則
4.路由過濾器:對去請求或響應做處理
路由斷言工廠(Route Predicate Factory)
網關路由可以配置的內容為:
- 路由id:路由唯一標示
- uri:路由目的地,支持lb和http兩種
- predicates:路由斷言,判斷請求是否符合要求,符合則轉發到路由目的地
? ? ? ?配置文件中的規則只是字符串,這些字符串會被Predicate Factory讀取并處理,轉變為路由判斷的條件,例如“Path=/user/**”是按照路徑進行匹配,只讓以/user開頭的就認為是符合的
- filter:路由過濾器,處理請求或響應
11種工廠:
?路由過濾器GatewayFilter
GatewayFilter是網關中提供的一種過濾器,可以對進入網關的請求和微服務返回的響應做處理
?下面列舉幾個Spring提供的不同的路由過濾器工廠:
現在要求給進入A服務的所有請求添加一個請求頭,你會怎么實現?
給某個服務單獨添加請求頭:
spring:cloud:gateway:routes:#網關路由配置- id: order-serviceuri: lb://orderservicepredicates:- Path=/order/**filters: #過濾器- AddRequestHeader=Truth,Itcast is freaking awesome!#添加請求頭
如果要對所有的路由都生效,即可將過濾工廠寫到default下,如:
spring:application:name: gatewaycloud:nacos:server-addr: nacos:8848 # nacos地址gateway:routes:- id: user-service # 路由標示,必須唯一uri: lb://userservice # 路由的目標地址predicates: # 路由斷言,判斷請求是否符合規則- Path=/user/** # 路徑斷言,判斷路徑是否是以/user開頭,如果是則符合- id: order-serviceuri: lb://orderservicepredicates:- Path=/order/**default-filters:#對所有的路由都生效的過濾器- AddRequestHeader=Truth,Itcast is freaking awesome!
全局過濾器
? ? ? ?全局過濾器的作用也是處理一切網關的請求和微服務響應,與GatewayFilter的作用一樣,區別在GatewayFilter通過配置定義,處理邏輯時固定的,而GlobalFilter的邏輯需要自己寫代碼實現,定義是實現GlobalFilter接口
//@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 1.獲取請求參數ServerHttpRequest request = exchange.getRequest();MultiValueMap<String, String> params = request.getQueryParams();// 2.獲取參數中的 authorization 參數String auth = params.getFirst("authorization");// 3.判斷參數值是否等于 adminif ("admin".equals(auth)) {// 4.是,放行return chain.filter(exchange);}// 5.否,攔截// 5.1.設置狀態碼exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);// 5.2.攔截請求return exchange.getResponse().setComplete();}@Overridepublic int getOrder() {return -1;}
步驟:
1.實現GlobalFilter接口
2.添加@Order注解或者實現Ordered接口
3.編寫處理邏輯
過濾器執行順序
- ?每一個過濾器都必須指定一個int類型的order值,order值越小,優先級越高,執行順序越靠前
- GlobalFilter通過實現Ordered接口,或者添加@Order注解來指定order值
- 路由過濾器和defaultFilter的order由Spring指定,默認是按照聲明順序從1遞增
- 當過濾器的order值一樣時,會按照defaultFilter>局部路由過濾器>GlobalFilter的順序執行
跨域問題
? ? ? ?跨域問題:域名不一致就是跨域。瀏覽器禁止請求的發起者與服務器發生跨域ajax請求,請求被瀏覽器攔截的問題
CORS:
spring:application:name: gatewaycloud:nacos:server-addr: nacos:8848 # nacos地址gateway:globalcors: #全年的跨域處理add-to-simple-url-handler-mapping: true #解決options請求被攔截問題corsconfigurations: '[/**]':allowedOrigins: #允許哪些網站的跨域請求-"http://127.0.0.1:8090"allowedMethods: #允許的跨域ajax的請求方式-"GET"-"POST"-"DELETE"-"PUT"-"OPTIONS"allowedHeaders: "*" #允許在請求中攜帶的頭信息allowCredentials: true #是否允許攜帶cookiemaxAge: 360000 #這次跨域檢測的有效期