首先微服務是為了構建復雜系統(tǒng)而生的,如果并發(fā)所有系統(tǒng)都適合使用微服務架構,任何技術都是為了解決具體應用業(yè)務場景而生的,離開了業(yè)務場景談技術都是耍流氓!可能你會說,我們做基礎開發(fā)不做業(yè)務,基礎開發(fā)面向的領域跟業(yè)務領域可能不同而已,即領域模型不同而已,其實都是使用編碼解決不各自領域的問題,就好像是網(wǎng)絡七層模型,大家處于不同層次而已。
使用微服務網(wǎng)關之前可以思考如下幾個問題:
1、為什么要用微服務網(wǎng)關,如果不用行不行?
2、我們不用微服務是否也可以用微服務網(wǎng)關?
相信大家對Nginx并不陌生,微服務網(wǎng)關能做什么,簡單說跟Nginx一樣都能反向代理,也就是說可以做前后端分離。還有嗎?當然。當你的項目還是初期的時候,你可能只需要用到做前后分離即可。當你應用龐大之后你需要對系統(tǒng)進行拆解,你可能會有商品服務、購物車服務、商品詳情、支付服務、物流服務等等,而且你可能會有PC端、APP端、小程序等等,當業(yè)務部門精心準備一場購物盛宴的時候,你可能還會遇到洪水般的流量,你如何保障系統(tǒng)平穩(wěn)運行,如絲般順滑。不是說一個就能解決所有問題,而且以上這些問題網(wǎng)關都能起到至關重要的作用。看到這里上面問題的相信大家心里已有答案。
微服務網(wǎng)關:
zuul1.0 : netflix 公司開源的,基于 Serlvet ,與Spring Cloud 集成。優(yōu)點:開發(fā)容易、編程模型簡單。缺點:連接數(shù)限制、線程上下切換開銷、延遲阻塞耗盡線程連接資源.適用于CPU密集型,例如計算視頻編解碼,圖像處理,加解密,壓縮解壓等等
zuul2.0: 基于Netty實現(xiàn)異步非阻塞編程模型.優(yōu)點:線程開銷少、連接數(shù)易擴展 缺點:編程模型復雜,調(diào)試復雜 適用于IO密集型如,web服務器
kong: nginx+lua
SpringCloud Gateway: 基于Spring Boot 2.x, Spring WebFlux
......
市面的網(wǎng)關還有很多我們就不一一列舉了,根據(jù)我的經(jīng)驗入門難度來排序:
zuul1.0<zuul2.0<SpringCloud Gateway<kong
今天我們先來看一下SpringCloud Gateway
SpringCloud Gateway 通過匹配路由規(guī)則然后執(zhí)行相應動作。
一、引入依賴
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
二、路由轉發(fā)規(guī)則
路由轉發(fā)規(guī)則定義說明:
id: 路由規(guī)則唯一識別
predicates: 謂詞工廠,觸發(fā)轉發(fā)條件:After Before Between Cookie Header Host Method Path Query RemoteAddr Weight
uri:轉發(fā)地址
filter: 路由過濾器允許以某種方式修改傳入HTTP請求或輸出HTTP響應。路由篩選器的作用域是特定路由。SpringCloudGateway包括許多內(nèi)置的GatewayFilter工廠:
AddRequestHeader AddRequestParameter AddResponseHeader DedupeResponseHeader Hystrix PrefixPath PreserveHostHeader RequestRateLimiter Redis RateLimiter RedirectTo
order: 路由規(guī)則優(yōu)先級
application.yaml
spring:
cloud:
gateway:
routes:
SpringCloudGateway 路由配置規(guī)則很豐富,我們針對我們常用的場景進行舉例:
根據(jù)路徑(Path)匹配轉發(fā)實現(xiàn)前后分離
假設我們的前端是NodeJs項目,我們通過ajax分別訪問商品服務、訂單服務。
- 靜態(tài)文件服務器:proxy.static.url
- 商品后臺API服務器:proxy.api.goods.url
- 訂單后臺API服務器:proxy.api.order.url
PS: 假設所有靜態(tài)資源訪問根路徑 /,商品服務訪問/api/goods/** ,訂單服務訪問/api/order/**
針對這種場景我們進行如下配置即可實現(xiàn):
spring:
cloud:
gateway:
routes:
- id: static
predicates:
- Path=/**
uri: ${proxy.static.url} #靜態(tài)資源服務器,如 html,js,css,img等
order: 1000
- id: api_goods
predicates:
- Path=/api/goods
uri: ${proxy.api.goods.url} #商品 API 服務器
order: 1000
- id: api_order
predicates:
- Path=/api/order
uri: ${proxy.api.order.url} #訂單 API 服務器
order: 1000
根據(jù)路徑(Path)識別應用,并重定向到 / 。適用于遺留系統(tǒng)接入網(wǎng)關(遺留系統(tǒng)大多使用根路徑:/)。 RewritePath 支持正則表達式,分組提取
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org #后端應用服務
predicates:
- Path=/foo/**
filters:
- RewritePath=/foo(?<segment>/?.*), $\{segment}
根據(jù)主機(Host)識別應用 適用于遺留系統(tǒng)接入網(wǎng)關但又想保留原始域名等,此種方式接入網(wǎng)關改造量最少也能保留原始域名是目前最優(yōu)方案。
PS: 需要將應用原始域名CNAME到網(wǎng)關域名
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org #后端應用服務
predicates:
- Host=**.somehost.org,**.anotherhost.org
網(wǎng)關跨域配置,支持復雜請求,如POST SSE websocket 等
由網(wǎng)關代為跨域,后端應用可以不做跨域處理
spring:
cloud:
gateway:
routes:
- id: spider_route
uri: ws:${proxy.api.url}
predicates:
- Path=/**
filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin # 如果后端服務器也進行跨域支持,需要加上此項。作用是進行返回頭去重
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "*" #生產(chǎn)環(huán)境為了安全考慮請配置具體域名
allowedMethods:
- POST
- GET
- DELETE
- PUT
allowedHeaders: "*" #不配置此項可支持簡單請求跨域如:GET、DELETE 如要兼容復雜請求如:POST SSE 請求此項必不可少