摘要
API可謂扮演了“技術(shù)膠水”的角色,能幫助企業(yè)內(nèi)外進(jìn)行不同業(yè)務(wù)邏輯和不同數(shù)據(jù)的連接和整合,API市場(chǎng)正逐步形成一個(gè)新的生態(tài)系統(tǒng),對(duì)于調(diào)用者來(lái)說(shuō),能快速整合不同服務(wù)到自己的產(chǎn)品中,快速豐富產(chǎn)品功能;對(duì)提供者而言,能通過(guò)API將自己的服務(wù),專業(yè)能力和專業(yè)數(shù)據(jù)變現(xiàn)。
解決方案
隨著微服務(wù)架構(gòu)體系的建立,API網(wǎng)關(guān)扮演著獨(dú)木橋的角色,其出現(xiàn)在企業(yè)系統(tǒng)的邊界,承擔(dān)著企業(yè)內(nèi)部與企業(yè)外部交互通信的作用,它除了需要保證數(shù)據(jù)交換之外,還需要對(duì)接入客戶端身份認(rèn)證,防止數(shù)據(jù)篡改等業(yè)務(wù)鑒權(quán)的功能之外,還承擔(dān)了流控、協(xié)議轉(zhuǎn)換等作用,其架構(gòu)大概如下:
在業(yè)界比較流行的api網(wǎng)關(guān)有Kong、Gravitee、Zuul等,其主要是針對(duì)rest api等來(lái)做的,協(xié)議轉(zhuǎn)換功能是沒(méi)有的
基于zuul與oauth2來(lái)構(gòu)建api網(wǎng)關(guān)
Oauth2
oauth2是一個(gè)搞授權(quán)的,對(duì)于Api網(wǎng)關(guān)來(lái)說(shuō),用oauth2來(lái)做業(yè)務(wù)鑒權(quán)是比較合適的選擇,其大概有幾種角色的定義:
- 資源擁有者(resource owner):能授權(quán)訪問(wèn)受保護(hù)資源的一個(gè)實(shí)體,可以是一個(gè)人,那我們稱之為最終用戶;
- 資源服務(wù)器(resource server):存儲(chǔ)受保護(hù)資源,客戶端通過(guò)access token請(qǐng)求資源,資源服務(wù)器響應(yīng)受保護(hù)資源給客戶端;
- 授權(quán)服務(wù)器(authorization server):成功驗(yàn)證資源擁有者并獲取授權(quán)之后,授權(quán)服務(wù)器頒發(fā)授權(quán)令牌(Access Token)給客戶端。
- 客戶端(client):第三方應(yīng)用,也可以是它自己的官方應(yīng)用;其本身不存儲(chǔ)資源,而是資源擁有者授權(quán)通過(guò)后,使用它的授權(quán)(授權(quán)令牌)訪問(wèn)受保護(hù)資源,然后客戶端把相應(yīng)的數(shù)據(jù)展示出來(lái)/提交到服務(wù)器。
而對(duì)于Api網(wǎng)關(guān)來(lái)說(shuō),網(wǎng)關(guān)扮演了資源服務(wù)器及授權(quán)服務(wù)器的角色
集成oauth2比較簡(jiǎn)單
- Pom依賴
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.0.12.RELEASE</version>
</dependency>
```
- 開(kāi)啟授權(quán)服務(wù)器
@Configuration
@EnableAuthorizationServer
public class OAuth2ServerConfiguration extends AuthorizationServerConfigurerAdapter {
}
- 開(kāi)啟資源服務(wù)器
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
}
基本上這三部就能把oauth2進(jìn)行完美的集成,還有其他方面的工作,比如說(shuō)token的存儲(chǔ),UserDetailsService、ClientDetailsService、ClientRegistrationService具體實(shí)現(xiàn),及WebSecurity的定義等
詳細(xì)可以查看<a >oauth2</a>
zuul
zuul是netfix的api 網(wǎng)關(guān),主要特色有:filter的PRPE(pre,route,post,error)模型、groovy的fitler機(jī)制,其中spring cloud對(duì)其有比較好的擴(kuò)展,但是spring cloud對(duì)其的擴(kuò)展感覺(jué)不是很完美,存在路由規(guī)則無(wú)法只能是通過(guò)配置文件來(lái)存儲(chǔ),而無(wú)法動(dòng)態(tài)配置的目的,其中有一個(gè)人寫(xiě)了一個(gè)starter插件來(lái)解決路由規(guī)則配置到Cassandra的問(wèn)題,詳細(xì)請(qǐng)看:<a >cassandra</a>,此插件針對(duì)的spring cloud zuul版本比較老,故我對(duì)他進(jìn)行改進(jìn),將路由配置可以配置到mysql這樣的關(guān)系型數(shù)據(jù)庫(kù)中,詳細(xì)請(qǐng)看:<a >zuul</a>
改動(dòng)點(diǎn)有:
1:對(duì)DiscoveryClientRouteLocator的重新覆蓋,該類的作用就是從yml中讀取路由規(guī)則;
2:定義自己的Filter機(jī)制,這里主要是做了流控及協(xié)議轉(zhuǎn)化的工作,這里主要是http->grpc的轉(zhuǎn)換;
LimitAccessFilter:利用redis令牌桶算法進(jìn)行流控
GrpcRemoteRouteFilter:http轉(zhuǎn)化為grpc的協(xié)議轉(zhuǎn)換
3:還有是添加路由到數(shù)據(jù)后,通知zuul重新刷新路由規(guī)則,通過(guò)spring的event來(lái)實(shí)現(xiàn)的;
以上就是用zuul和oauth2來(lái)構(gòu)建網(wǎng)關(guān)的一些實(shí)際經(jīng)驗(yàn),僅拋磚引玉,其中api網(wǎng)關(guān)還有一些其他工作,比如服務(wù)編排,服務(wù)隔離等并沒(méi)有體現(xiàn),僅實(shí)現(xiàn)了限流、鑒權(quán)、協(xié)議轉(zhuǎn)換三個(gè)基本功能點(diǎn),而且與kong這樣的Nginx網(wǎng)關(guān)相比,并發(fā)量支持比Kong要差好多,這點(diǎn)可以部署多節(jié)點(diǎn)來(lái)解決
詳細(xì)代碼 gateway
https://github.com/linking12/saluki/tree/develop/saluki-gateway