① 開源API網關系統(Kong教程)入門到精通
1、Kong的簡介和安裝
2、使用Docker安裝Kong
3、開源API網關:KONG入門培訓
1、配置詳解
2、代理詳解
3、身份驗證詳解
4、負載均衡詳解
5、健康檢查和斷路器詳解
6、集群詳解
7、網路與防火牆詳解
8、共有Lua API詳解
9、管理API安全保護詳解
一、身份驗證鄭腔扒插件
1、Basic驗證
2、Key驗證
3、OAuth2.0驗證
二、許可權安全插件
1、ACL鑒權
2、動態SSL
3、IP限制(黑白名單)
4、爬蟲控制
三、流量控制插件
1、請求大小限制
2、請求速率限制
3、請求終止
四、Serverless插件
1、Serverless功能
五、分析與監控插件
1、Zipkin
六、數據轉換插件
就是請求,和返回的時候加喊昌減點數據。
七、日誌插件
日誌插件發送目標包括圓搜:TCP、UDP、HTTP、FILE、STATSD、SYSLOG 等,比較簡單,自己找資料看看
1、玩轉SERVICE服務
2、玩轉ROUTE路由
3、玩轉API對象 (不推薦)
4、玩轉CONSUMER消費者
1、Kong整合Consul 附: Consul快速入門
2、Kong整合Spring Security實現OAuth2.0驗證
3、實現Kong的Java管理API
② API網關從入門到放棄
假設你正在開發一個電商網站,那麼這里會涉及到很多後端的微服務,比如會員、商品、推薦服務等等。
那麼這里就會遇到一個問題,APP/Browser怎麼去訪問這些後端的服務? 如果業務比較簡單的話,可以給每個業務都分配一個獨立的域名(https://service.api.company.com),但這種方式會有幾個問題:
更好的方式是採用API網關,實現一個API網關接管所有的入口流量,類似Nginx的作用,將所有用戶的請求轉發給後端的伺服器,但網關做的不僅僅只是簡單的轉發,也會針對流量做一些擴展,比如鑒權、限流、許可權、熔斷、協議轉換、錯誤碼統一、緩存、日誌、監控、告警等,這樣將通用的邏輯抽出來,由網關統一去做,業務方也能夠更專注於業務邏輯,提升迭代的效率。
通過引入API網關,客戶端只需要與API網關交互,而不用與各個業務方的介面分別通訊,但多引入一個組件就多引入了一個潛在的故障點,因此要實現一個高性能、穩定的網關,也會涉及到很多點。
API 注冊
業務方如何接入網關?一般來說有幾種方式。
協議轉換
內部的API可能是由很多種不同的協議實現的,比如HTTP、Dubbo、GRPC等,但對於用戶來說其中很多都不是很友好,或者根本沒法對外暴露,比如Dubbo服務,因此需要在網關層做一次協議轉換,將用戶的HTTP協議請求,在網關層轉換成底層對應的協議,比如HTTP -> Dubbo, 但這里需要注意很多問題,比如參數類型,如果類型搞錯了,導致轉換出問題,而日誌又不夠詳細的話,問題會很難定位。
服務發現
網關作為流量的入口,負責請求的轉發,但首先需要知道轉發給誰,如何定址,這里有幾種方式:
服務調用
網關由於對接很多種不同的協議,因此可能需要實現很多種調用方式,比如HTTP、Dubbo等,基於性能原因,最好都採用非同步的方式,而Http、Dubbo都是支持非同步的,比如apache就提供了基於NIO實現的非同步HTTP客戶端。
因為網關會涉及到很多非同步調用,比如攔截器、HTTP客戶端、bbo、redis等,因此需要考慮下非同步調用的方式,如果基於回調或者future的話,代碼嵌套會很深,可讀性很差,可以參考zuul和spring cloud gateway的方案,基於響應式進行改造。
優雅下線
性能
網關作為所有流量的入口,性能是重中之重,早期大部分網關都是基於同步阻塞模型構建的,比如Zuul 1.x。但這種同步的模型我們都知道,每個請求/連接都會佔用一個線程,而線程在JVM中是一個很重的資源,比如Tomcat默認就是200個線程,如果網關隔離沒有做好的話,當發生網路延遲、FullGC、第三方服務慢等情況造成上游服務延遲時,線程池很容易會被打滿,造成新的請求被拒絕,但這個時候其實線程都阻塞在IO上,系統的資源被沒有得到充分的利用。另外一點,容易受網路、磁碟IO等延遲影響。需要謹慎設置超時時間,如果設置不當,且服務隔離做的不是很完善的話,網關很容易被一個慢介面拖垮。
而非同步化的方式則完全不同,通常情況下一個CPU核啟動一個線程即可處理所有的請求、響應。一個請求的生命周期不再固定於一個線程,而是會分成不同的階段交由不同的線程池處理,系統的資源能夠得到更充分的利用。而且因為線程不再被某一個連接獨占,一個連接所佔用的系統資源也會低得多,只是一個文件描述符加上幾個監聽器等,而在阻塞模型中,每條連接都會獨佔一個線程,而線程是一個非常重的資源。對於上游服務的延遲情況,也能夠得到很大的緩解,因為在阻塞模型中,慢請求會獨佔一個線程資源,而非同步化之後,因為單條連接所佔用的資源變的非常低,系統可以同時處理大量的請求。
如果是JVM平台,Zuul 2、Spring Cloud gateway等都是不錯的非同步網關選型,另外也可以基於Netty、Spring Boot2.x的webflux、vert.x或者servlet3.1的非同步支持進行自研。
緩存
對於一些冪等的get請求,可以在網關層面根據業務方指定的緩存頭做一層緩存,存儲到Redis等二級緩存中,這樣一些重復的請求,可以在網關層直接處理,而不用打到業務線,降低業務方的壓力,另外如果業務方節點掛掉,網關也能夠返回自身的緩存。
限流
限流對於每個業務組件來說,可以說都是一個必須的組件,如果限流做不好的話,當請求量突增時,很容易導致業務方的服務掛掉,比如雙11、雙12等大促時,介面的請求量是平時的數倍,如果沒有評估好容量,又沒有做限流的話,很容易服務整個不可用,因此需要根據業務方介面的處理能力,做好限流策略,相信大家都見過淘寶、網路搶紅包時的降級頁面。
因此一定要在接入層做好限流策略,對於非核心介面可以直接將降級掉,保障核心服務的可用性,對於核心介面,需要根據壓測時得到的介面容量,制定對應的限流策略。限流又分為幾種:
穩定性
穩定性是網關非常重要的一環,監控、告警需要做的很完善才可以,比如介面調用量、響應時間、異常、錯誤碼、成功率等相關的監控告警,還有線程池相關的一些,比如活躍線程數、隊列積壓等,還有些系統層面的,比如CPU、內存、FullGC這些基本的。
網關是所有服務的入口,對於網關的穩定性的要求相對於其他服務會更高,最好能夠一直穩定的運行,盡量少重啟,但當新增功能、或者加日誌排查問題時,不可避免的需要重新發布,因此可以參考zuul的方式,將所有的核心功能都基於不同的攔截器實現,攔截器的代碼採用Groovy編寫,存儲到資料庫中,支持動態載入、編譯、運行,這樣在出了問題的時候能夠第一時間定位並解決,並且如果網關需要開發新功能,只需要增加新的攔截器,並動態添加到網關即可,不需要重新發布。
熔斷降級
熔斷機制也是非常重要的一項。若某一個服務掛掉、介面響應嚴重超時等發生,則可能整個網關都被一個介面拖垮,因此需要增加熔斷降級,當發生特定異常的時候,對介面降級由網關直接返回,可以基於Hystrix或者Resilience4j實現。
日誌
由於所有的請求都是由網關處理的,因此日誌也需要相對比較完善,比如介面的耗時、請求方式、請求IP、請求參數、響應參數(注意脫敏)等,另外由於可能涉及到很多微服務,因此需要提供一個統一的traceId方便關聯所有的日誌,可以將這個traceId置於響應頭中,方便排查問題。
隔離
比如線程池、http連接池、redis等應用層面的隔離,另外也可以根據業務場景,將核心業務部署帶單獨的網關集群,與其他非核心業務隔離開。
網關管控平台
這塊也是非常重要的一環,需要考慮好整個流程的用戶體驗,比如接入到網關的這個流程,能不能盡量簡化、智能,比如如果是bbo介面,我們可以通過到git倉庫中獲取源碼、解析對應的類、方法,從而實現自動填充,盡量幫用戶減少操作;另外介面一般是從測試->預發->線上,如果每次都要填寫一遍表單會非常麻煩,我們能不能自動把這個事情做掉,另外如果網關部署到了多個可用區、甚至不同的國家,那這個時候,我們還需要介面數據同步功能,不然用戶需要到每個後台都操作一遍,非常麻煩。
這塊個人的建議是直接參考阿里雲、aws等提供的網關服務即可,功能非常全面。
其他
其他還有些需要考慮到的點,比如介面mock,文檔生成、sdk代碼生成、錯誤碼統一、服務治理相關的等,這里就不累述了。
目前的網關還是中心化的架構,所有的請求都需要走一次網關,因此當大促或者流量突增時,網關可能會成為性能的瓶頸,而且當網關接入的大量介面的時候,做好流量評估也不是一項容易的工作,每次大促前都需要跟業務方一起針對介面做壓測,評估出大致的容量,並對網關進行擴容,而且網關是所有流量的入口,所有的請求都是由網關處理,要想准確的評估出容量很復雜。可以參考目前比較流行的ServiceMesh,採用去中心化的方案,將網關的邏輯下沉到sidecar中,
sidecar和應用部署到同一個節點,並接管應用流入、流出的流量,這樣大促時,只需要對相關的業務壓測,並針對性擴容即可,另外升級也會更平滑,中心化的網關,即使灰度發布,但是理論上所有業務方的流量都會流入到新版本的網關,如果出了問題,會影響到所有的業務,但這種去中心化的方式,可以先針對非核心業務升級,觀察一段時間沒問題後,再全量推上線。另外ServiceMesh的方案,對於多語言支持也更友好。
③ 使用netty構建API網關實踐之路
隨著互聯網的快速發展,當前以步入移動互聯、物聯網時代。用戶訪問系統入口也變得多種方式,由原來單一的PC客戶端,變化到PC客戶端、各種廳派瀏覽器、手機移動端及智能終端等。同時系統之間大部分都不是單獨運行,經常會涉及與其他系統對接、共享數據的需求。所以系統需要升級框架滿足日新月異需求變化,支持業務發展,並將框架升級為微服務架構。「API網關」核心組件是架構用於滿足此些需求
很多互聯網平台已基於網關的設計思路,構建自身平台的API網關,國內主要有京東、攜程、唯品會等,國外主要有Netflix、Amazon等。
業界為了滿足這些需求,已有相關的網關框架。
1、基於nginx平台實現的網關有:kong、umbrella等
2、自研發的網關有:zuul1、zuul2等
但是以上網關框架只能是滿足部分需求,不能滿足企業的所有要求,就我而言,我認為最大的問題是沒有協議轉換及OPS管理控制平台
另外:對於微服務架構下,如果基於HTTP REST傳輸協議,API網關還承擔了一個內外API甄別的功能,只有在API網關上注冊了的API還能是真正的堆外API
整個網關系統由扮兆三個子系統組成:
說明:
1) 整個網關基於Netty NIO來實現同步非阻塞是HTTP服務,網關是外部API請求的HTTP服務端,同時是內部服務的客戶端,所以有Netty Server Handler和Netty Client Handler的出現;
2)對於Netty Server Handler來說,當一個HTTP請求進來時,他會把當前連接轉化為ClientToProxyConnection,它是線程安全的,伴隨當前此HTTP請求的生命周期結束,它也負責ClientToProxyConnection的生命周期的維護;
3)對於Netty Client Handler來說,當ClientToProxyConnection需要傳遞請求到內部服務時,會新建(或者獲取扮缺賀原來已建)的ProxyToServerConnection來進行內部的請求,它也是線程安全的;
4)對於Filter來說,他運行在ClientToProxyConnection上,插入請求進來及收到後端請求之間;
從以上分析,網關選擇同步非阻塞方式是一個合適的選擇
其中轉化的過程如下:
2:根據FileDescriptorSet獲取gRPC的入參和出參描述符,然後再創建gRPC所需要的MethodDescriptor方法描述對象
2) HTTP ----> bbo
在bbo的框架設計中,其中已經包含了泛化調用的設計,所以在這塊,基本上就延用了bbo的泛化調用來實現http轉bbo的協議,而關於bbo的參數部分,可以指定參數映射規范,利用參數裁剪的技術對http請求參數進行抽取,如果bbo的介面是java類型,則直接抽取,如果是pojo,按照bbo的用戶文檔,把他組成一個Map的數據結構即可,而操作這一步需要映射規則
整個網關目前基本完成並且也開源到GitHub上,歡迎拍磚及使用
tesla
④ 關於API網關(四)——限流
通俗的說,流量控制就是控制用戶請求的策略,主要包括:許可權、限流、流量調度。
許可權上一篇已經講過了,這一篇講限流,下一篇講流量調度。
限流是指限制用戶調用的頻率(QPS/QPM)或者次數。
流量限制,站在用戶或者運營的角度看,最直觀能感受到的作用是——收費
各大主流開放平台的對外API,一般都有一些免費的額度,可以供個人測試用,一旦想大規模調用,就需要付費購買更大的額度(頻率、次數),根據調用次數或者頻率進行收費。一旦超過擁有的額度,就會被限制調用。
其實這才是限流最大的用處,只是用戶或者運營同學無感,所以不太被大多數人了解。
網關後面是各個服務,各個服務的介面通過網關透出去給用戶調用。理論上說,用戶的流量是不可預知的,隨時可能來一波,一旦流量的峰值超過了服務的承載能力,服務就掛了,比如有大新聞發生時的某浪微博,比如前些年的12306.
所以, 網關必須保證,放過去到達後端服務的流量一定不可以超過服務可以承載的上限 。這個上限,是網關和各個服務協商出來的。
由簡到難,限流可以 分為單機限流、單集群限流、全集群限流 。
這里不討論具體的如漏桶、令牌桶等限流演算法,只說概念和思想。
單機限流的思想很簡單,就是每個機器的限流值 x 機器數量 = 總的限流值。
舉個例子,A用戶的QPS限制是100,網關部署了10台機器,那麼,每台機器限制10QPS就可以了。
先說好處,這種方法實現起來非常簡單,每台機器在本地內存計算qps就可以了,超過閾值就拒流。
不過單機限流的缺陷也十分明顯,主要體現在兩點:
當網關部署的機器數量發生變化時,每台機器的限流值需要根據機器數調整。現實中,因為擴容、縮容、機器宕機等原因,機器數的變化是常有的事。
單機限流的前提是,每台網關承載的用戶的流量是平均的,但是事實上,在某些時間,用戶的流量並不是完全平均分布在每台機器上的。
舉個例子:
10台機器,每台限qps10,其中3台每台實際qps是15,因為超限導致用戶流量被拒。其餘7台每台qps是7。這樣用戶總的qps = 15 * 3 + 7 * 7 = 94. 用戶qps並沒有超限,但是卻有一部分流量被拒了,這樣就很有問題。
實際上,單台限流的閾值也會設置的稍微大一些,以抵消流量不均的問題。
因為上面的問題, 單機限流通常作為一種兜底的備用手段,大多數時候用的還是集群限流 。
先來看一個示意圖:
相比單機限流,集群限流的計數工作上移到redis集群內進行,解決了單機限流的缺陷。
但是集群限流也不是完美的,因為引入了redis,那麼,當網關和redis之間的網路抖動、redis本身故障時,集群限流就失效了,這時候,還是得依靠單機限流進行兜底。
也就是說, 集群限流 + 單機限流配合,才是一個比穩妥的方案 。
接下來我們來思考這樣一個問題:大型網關一般都是多機房、多地域部署的,當然,後端的服務也是多機房、多地域部署的,在保護服務這一點來說,集群限流是夠用了。但是對用戶來說,還是有一些問題:
比如,用戶購買的QPS上限是30,我們的網關部署在中國北、中、南三個地域,那麼這30QPS怎麼分配呢?
平均肯定不行,用戶的流量可能是明顯不均衡的,比如用戶的業務主要集中在中國北方,那麼用戶的流量大部分都會進入北方的網關,網關如果限制QPS為10的話,用戶肯定來投訴。
那每個地域都限制為30行不行?也不行,如果用戶的流量比較均勻的分布在各個地域,那麼用戶購買了30QPS,實際上可能使用了90QPS,這太虧了。
按照解決單機限流流量不均的思路,搞一個公共的redis集群來計數行不行?
也不行,受限於信號傳播速度和天朝的廣闊疆域,每個流量都計數,肯定不現實,rt太高會導致限流失去意義,帶寬成本也會變得極其昂貴,對redis的規格要求也會很高。總之,很貴還解決不了問題。
有一種巧妙的解決辦法是:本地集群階梯計數 + 全集群檢查。
還是剛才的例子:
限流閾值時90,那麼三個地域各自計數,當本地域的數值達到30時,去其他兩個地域取一次對方當前的計數值,三個地域的計數值加起來,如果超了,告訴另外兩個地域超了,開始拒流。如果沒超,本地QPS每上漲10,重復一次上述的動作。
這樣就能有效的減少與redis的交互次數,同時實現了全地域真·集群限流。
當然,這種全地域集群限流,因為rt和階梯計數間隔的存在,一定是不準的,但是,比單集群限流還是好很多。
當某個用戶流量特別大的時候,redis計數就會遇到典型的熱點key問題,導致redis集群單節點壓力過大, 有兩種辦法可以解決這個問題:打散和抽樣。
打散是指,把熱點key加一些後綴,使其變成多個key,從而hash到不通的redis節點上,均攤壓力。
比如熱點key是abcd,那麼打散後,key變成了abcd1、abcd2、abcd3、abcd4。技術時,輪流加1、2、3、4的後綴就可以了。
抽樣是指,針對熱點key,不是每個每個請求到來時都進行計數,而是進行一個抽樣,比如每10個請求記一次數,這樣redis的壓力就會降低到十分之一。
說著把流量調度的也說完了哈哈,那下一篇再說說監控好了,順便推一下我現在在用的國產網關:GOKU,來自Eolinker。我覺得比KONG好用,感興趣的同學可以自行去了解一下。
www.eolinker.com
⑤ 阿里API網關使用總結
API網關 API Gateway)提供高性能、高可用的 API 託管服務,幫助用戶對外開放其部署在 ECS、容器服務等阿里雲產品上的應用,提供完整的 API 發布、攔埋管理、維護生命周期管理。用戶只需進行簡單的操作,即可快速、低成本、低風險地開放數據或服務。
利用API網關你可以提高自己公司API安全性,也可以上架到API雲市場,供用戶購買和使用。
這個沒什麼可說的,主要是你要想辦法盡可能安全地存儲你的AppKey和AppSecrect。
所屬分組是API的基本屬性,所以需要先創建分組,再在分組下創建API。每個賬號默認最多可創建100個分組,如需更多分組需要提交工單。分組有所屬區域(Region)的概念,比如華東上海區,選擇之後就不能修改了。創建完分組之後,系統會給該分組分配一個二級域名,供測試使用,不過,每個二級域名每天最多可訪問1000次。
如果你的API支持HTTPS協議,還需要為該獨立域名上傳 SSL 證書。我們需要把我們的域名解析到該分組上,之後才能綁定到該分組上。綁定的域名需要現在阿里雲系統備案。綁定域名之後,該分組下的API就可以通過該域名來訪問了,不再需要調用系統分配的二級域名了。
在API分組的環境管理中,你可以自定義環境變數,同一個變數可以再在線上、預發和測試三個環境下對應不同的值,這樣在API的定義中就可以使用這里定義好的環境變數了。可以在Path、入參默認值和後端服務服務地址中加入環境變數,在API的定義中使用環境變數需要以 #變數名# 的方式使用。 如果要修改已發布的API用到的環境變數,先把老的環境變數給刪掉,再重新定義一個新的同名環境變數賦上新值之後再把全部對簡簡螞應的API重新發布一遍,這個是非同步生效的,一般發布後1分鍾內生效。
這里的內容還是蠻多的,包括基本配置,前端和後端地址,請求參數配置等,詳細文檔可以看阿里API的官方文檔,這里說幾點重要的:
創建好API之後,就可以對應用進行授權了,點擊API的「授權」就可以在指定環境下授權某個APP可以訪問該API了,如果你在調用API的過程中控制台列印了x-ca-message中包含了Unauthorized錯誤,你應該想到你的API還未對該APP進行授權訪問。
API編輯完成之後就可以發布到指定環境上去了,發布之後就立馬生效了。可以多次編輯然後發布到不同的環境下,如果你編輯完了忘記發布到指定環境下了,是不會生效的。在分組API列表下,直接點擊API名字進入的是當前API最後一次編輯保存的狀態,不一定跟發布的狀態一直哦。點擊API右邊的線上、預發或測試後面的"運行中"可以看到在該環境下最後一次編輯發布後的狀態哦。
網關會在請求的時候加上日期、時間戳、nonce、userAgent、Host、AppKey、version等參數值,如果是POST請求的話,需要對參數值進行urlEncode。如果有body值的話,需要對body值,將body中的內容MD5演算法加密後再採用BASE64方法Encode成字元串,放入HTTP頭中。最後再通過將httpMethod、headers、path、queryParam、formParam經過一系列的運算,合成一個字元串用hmacSha256演算法雙向加密進行簽名。
在我們分組上綁定好了域名之後,我們不管是預發還是線上環境都可以通過這同一個域名進行訪問,那網關是怎麼幫我們區分環境的呢?這個時候就用到上面的環境變數管理了,我們通過在環境變數中定義一個變數在不同環境下不同的值達到區分環境的效果。在網路請求的時候,我們可以在頭部指定 X-Ca-Stage 參咐棗數值來讓網關幫我們轉發到對應環境的後端服務上,對應的值分別是:線上(RELEASE)默認、預發(PRE)和測試(TEST)。
這里重點說一下參數位置下可選的Body選項,這個地方坑了我們蠻久。我們知道在我們客戶端發起POST請求時,我們會在頭部指定「Content-Type」為「application/x-www-form-urlencoded」,然後把請求的參數組裝成"key1=value1&key2=value2"的字元串,然後在編碼成二進制,放在請求的Body里,以Form表單的形式提交的。所以呢,我們在定義API的參數時,應該把參數位置選擇為Body選項。但是我們在很長一段時間里,創建API時或編輯API時,參數位置處下拉一直沒有Body選項,我們就把參數定義成了Query類型的了。在使用時也沒有啥問題,但是一旦當我們的參數值非常長時,比如一個json字元串,這個是就報錯了「414 Request-URI Too Large」,這個時候呢,網關就不會再幫我們把請求轉發到服務端了。排查了很久終於找到了罪魁禍首在這里等著呢,通過把參數位置改成Body就可以了。這個可能是阿里API網關前端頁面上的一個bug,有時候根本選不到Body選項,這個時候你可以先把「請求Body(非Form表單數據,比如JSON字元串、文件二進制數據等)」選項給勾選上,然後再取消勾選,再下拉展開「參數位置」就可以看到Body選項了。(該文發布時是如此,我已經將該問題反饋給阿里API網關,可能後面會修復該bug。)
另外一個問題是如果你的參數值中包含了emoji表情,需要對參數值進行urlEncode,服務端在收到請求時需要對參數值進行urlDecode。否則用的過程中會出現各種奇怪的問題。問了阿里網關的服務人員,他們的解釋是,如果不進行urlEncode,參數在傳到網關時可能會丟失。可以對所有Post請求的參數值統一urlEncode,服務端對收到的參數值統一進行urlDecode。
在使用網關時,timestamp和nonce這兩個header參數值是可選的,如果加上這兩個值,網關層會對請求進行校驗,防止重放攻擊。不過有個問題:在當前時間的前後15分鍾的時間戳都是可以的,一旦超過15分鍾就會請求失敗,所以,如果用戶修改了客戶端的系統時間的話,API就會調不通了。這個校驗有點嚴格,如果不知道這一點的話,用戶反饋客戶端不能用,而你這里測試又沒有任何問題,那就淚奔了,哈哈。當然這個是可選的校驗,如果不傳這兩個值的話,就不會校驗,這個時候防重放攻擊的工作就需要我們自己的服務端做了。
目前網關不支持multipart形式的上傳,所以一般我們的上傳API不太適合錄入網關,阿里的說法是現在大家的做法普遍是先將文件上傳到文件伺服器,然後通過調用介面把文件地址等信息報錯到伺服器的方式,所以,目測以後也不大可能支持定義multipart形式的上傳API。
每個 API 分組的默認流控上限是500QPS,如果你要調大QPS,需要提交工單並支付相應費用。另外網關有個「流量控制策略」的功能,它是針對API的,也就是說定好策略之後,選中對哪些API生效,這些API就會單獨的受這個流量控制策略的控制。但是,需要注意的是,如果你要調大流量控制策略,也必須先調大API所在分組的QPS才會生效,否則流量控制策略可以創建但不會實際生效。
雖然我們可以在分組的環境管理中添加不同的環境變數來實現同一個API分組下可以定義不同服務域名的API,這樣我們客戶端在發起請求的時候,域名只需要配一個就可以了,非常方便。但是,一旦網關這一層癱瘓(盡管是小概率事件,但不排除),這個時候我們就心有餘而力不足了,只能等網關盡快恢復了。如果我們一個分組對應一個我們真正的服務域名的話,一旦網關出問題,我們可以快速把該分組綁定的域名指向我們真正的該分組的服務上。
⑥ 如何使用API 網關做服務編排
服務編排/數據聚合 指的是可以通過一個請求來依次調用多個微服務,並對每個服務的返回結果做數據處理,最終整合成一個大的結果返回給前端。
例如一個服務是「查詢用戶預定的酒店」,前端僅需要傳一個訂單ID,後端會返回整個訂單的信息,包括用戶信息、酒店信息和房間信息等。
這個服務背後可能對應著以下幾個操作:
微服務架構上對功能做了解耦,使用服務編排可以快速從各類服務上獲取需要的數據,對業務實現快速響扒畢應。總的來說,編排有以下幾點優勢:
Goku API Gateway (中文名:悟空 API 網關)是一個基於 Golang 開發的微服務網關,能夠實現高性能 HTTP API 轉發、服務編排、多租戶管理、API 訪問許可權控制等目的,擁有強大的自定義插件系統可以自行擴展,並且提供友好的圖形化配置界面,能夠叢念快速幫助企業進行 API 服務治理、提高 API 服務的穩定性和安全性。
Goku API Gateway支持一個編排API對應多個後端服務,每個後端服務的請求參數可以使用前端傳入的參數,也可以在編排里自定義(寫靜態參數或從返回數據里獲得)。每個後端服務的返回數據支持過濾、刪除、移動、重命名、拆包和封包等操作;編排API能夠設定編排失敗時的異常返回。
Goku API Gateway 的社區版本(CE)同時擁有完善的使用指南和二次開發指南,內置的插件系統也能夠讓企業針對自身業務進行定製開發。
項目地址: https://github.com/eolinker/goku-api-gateway
官網地址: https://www.eolinker.com
我們將編排的整個操作滲此困放到網關進行,由網關對數據做處理與轉換,這樣無需對後端服務做改動。一個請求到達網關,網關調用多個後端服務,並且在網關上對各個服務的返回數據做處理(操作有過濾、移動、重命名、封包、拆包,後面會對各操作做詳細解釋),最後由網關將數據整合好返回給前端。
網關將編排過程中對 API的轉發處理過程 (轉發->獲取返回數據->數據處理)稱為一個 Step 。
添加一個轉發服務,該服務為 查詢訂單詳情API,配置相應的轉發地址、傳入的參數、對返回數據做何種處理等。
由於篇幅原因,後續的Step(查詢用戶詳情、查詢酒店詳情、查詢房間詳情)就不一一展示了。
網關將編排過程中對 API的轉發處理過程 (轉發->獲取返回數據->數據處理)稱為一個 Step。
我們將處理查詢訂單詳情API稱為 Step1 ,其中Step1的返回數據有:用戶ID、酒店ID、房間ID。同理,將查詢用戶信息這步稱為 Step2 ,將查詢酒店信息稱為 Step3 ,將查詢房間信息稱為 Step4 。
傳參規則:
以下為轉發路徑的傳參寫法:
Step2中需要接收Step1里返回的userID作為參數,同時需要接收前端傳入的Authorization參數
在網關里Step2的請求參數配置如下所示,請求參數存在多個的話用換行表示:
1.查詢訂單詳情的API,返回數據稱為json1,內容如下:
2.查詢用戶詳情的API,返回數據稱為json2,內容如下:
3.查詢酒店詳情的返回數據,稱為json3,內容如下:
4.查詢房間詳情的返回數據,稱為json4,內容如下:
5.可以在每一個Step里對返回Json做處理,網關會將處理過的數據最後整合起來,再返回前端,例如這是通過網關返回的最終數據:
這里以查詢酒店詳情API的返回數據json3為例,講解網關如何在編排過程中對返回數據做處理。
查詢酒店詳情API返回的原始數據如下:
從網關返回給前端的數據中截取酒店信息的數據如下:
從原始數據到處理後的數據需要經過以下操作:
欄位黑名單的作用是排除某些欄位,支持數組形式。
在網關的Step3里配置如下:
經過網關處理後,實際的返回數據如下,可以看到data對象里的id欄位已經被過濾掉:
拆包是指將指定對象的內容提取出來作為該步驟(step)的返回結果。其中匹配目標只能為object,匹配目標為空時,結果為 {},可用於清除數據。
在網關的Step里配置如下:
經過網關處理後,實際的返回數據如下,可以看到data對象被拆開,最終數據僅保留了data對象裡面的欄位:
欄位封包會將當前的數據整體打包為最終返回數據中的一個對象,不支持*,不支持數組。
在網關的Step里配置如下:
經過網關處理後,實際的返回數據如下,數據被整體打包為hotelinfo對象:
經過三個步驟,就可以將原始數據變成最終的數據。
本文僅列舉了編排過程中部分數據處理的操作,如需了解更多編排細則,可通過文末給出的教程鏈接。
相關鏈接
⑦ API網關設置基礎知識
如果大家了解網路構成的話,對於網關應該就不會陌生了,今天我們就一起來了解一下,API網關的一些基礎知識,希望對大家以後的伺服器開發工作有所幫助,下面就開始今天的主要內容吧。
一、API網關產生背景
在微服務的架構中,一個大的應用會被拆分成多個小的單一的服務提供出來,這些小的服務有自己的處理,有自己的資料庫(也可以共用),也許語言也是不一樣的,他們可以部署在一個或多個伺服器上,其實也就是對復雜的應用進行了解耦,那為什麼微服務需要API網關呢?
我們看看微服務後產生的問題:
客戶枯罩鋒端需要知道多個沒晌服務地址
通用的功能怎麼處理?例如鑒權、流量控制、日誌等
以前一個功能可能是一次請求就可以完成,現在可能要多個服務一起進行才可以,那如何減少客戶端請求的時間呢?
由於悶汪以上幾點的問題,所以在所有的服務前面還需要定義一個代理,即API網關,所有的客戶端請求都必須經過API網關代理到真實的服務地址,這也可以有效的避免真實地址的暴露,同時API網關也可以集成鑒權、流量控制、日誌、API聚合、黑白名單等。
二、kong的介紹
Kong是由Mashape開發的並且於2023年開源的一款API網關框架,基於nginx以及OpenResty研發,主要特點是高性能以及其強大的擴展性,由於本身是基於nginx進行開發,因此網上很多關於nginx的調優等資料都可以用到kong的上面,包括負載均衡、或者充當web伺服器等
kong的擴展是通過插件機制進行的,並且也提供了插件的定製示例方法,插件定義了一個請求從進入到反饋到客戶端的整個生命周期,所以電腦培訓認為可以滿足大部分的定製需求,本身kong也已經集成了相當多的插件,包括CORS跨域、logging、限流、轉發、健康檢查、熔斷等,API聚合功能從github上看也已經進入開發階段。
⑧ 「微服務架構」部署NGINX Plus作為API網關,第1部分 - NGINX
了解著名的Nginx伺服器(微服務必不可少的東西)如何用作API網關。
現代應用程序體系結構的核心是HTTP API。 HTTP使應用程序能夠快速構建並輕松維護。無論應用程序的規模如何,HTTP API都提供了一個通用介面,從單用途微服務到無所不包的整體。通過使用HTTP,支持超大規模Internet屬性的Web應用程序交付的進步也可用於提供可靠和高性能的API交付。
有關API網關對微服務應用程序重要性的精彩介紹,請參閱我們博客上的構建微服務:使用API網關。
作為領先的高性能,輕量級反向代理和負載均衡器,NGINX Plus具有處理API流量所需的高級HTTP處理功能。這使得NGINX Plus成為構建API網關的理想平台。在這篇博文中,我們描述了許多常見的API網關用例,並展示了如何配置NGINX Plus以便以高效,可擴展且易於維護的方式處理它們。我們描述了一個完整的配置,它可以構成生產部署的基礎。
注意:除非另有說明,否則本文中的所有信息均適用於NGINX Plus和NGINX開源。
API網關的主要功能是為多個API提供單一,一致的入口點,無論它們在後端如何實現或部署。並非所有API都是微服務應用程序。我們的API網關需要管理現有的API,單塊和正在部分過渡到微服務的應用程序。
在這篇博文中,我們引用了一個假設的庫存管理API,即「倉庫API」。我們使用示例配置代碼來說明不同的用例。 Warehouse API是一個RESTful API,它使用JSON請求並生成JSON響應。但是,當部署為API網關時,使用JSON不是NGINX Plus的限制或要求; NGINX Plus與API本身使用的架構風格和數據格式無關。
Warehouse API實現為離散微服務的集合,並作為單個API發布。庫存和定價資源作為單獨的服務實施,並部署到不同的後端。所以API的路徑結構是:
例如,要查詢當前倉庫庫存,客戶端應用程序會向/ api / warehouse / inventory發出HTTP GET請求。
使用NGINX Plus作為API網關的一個優點是,它可以執行該角色,同時充當現有HTTP流量的反向代理,負載平衡器和Web伺服器。如果NGINX Plus已經是應用程序交付堆棧的一部分,那麼通常不需要部署單獨的API網關。但是,API網關所期望的某些默認行為與基於瀏覽器的流量的預期不同。出於這個原因,我們將API網關配置與基於瀏覽器的流量的任何現有(或未來)配置分開。
為實現這種分離,我們創建了一個支持多用途NGINX Plus實例的配置布局,並為通過CI / CD管道自動配置部署提供了便利的結構。 / etc / nginx下的結果目錄結構如下所示。
所有API網關配置的目錄和文件名都以api_為前綴。這些文件和目錄中的每一個都啟用API網關的不同特性和功能,並在下面詳細說明。
所有NGINX配置都以主配置文件nginx.conf開頭。要讀入API網關配置,我們在nginx.conf的http塊中添加一個指令,該指令引用包含網關配置的文件api_gateway.conf(下面的第28行)。請注意,默認的nginx.conf文件使用include偽指令從conf.d子目錄中引入基於瀏覽器的HTTP配置(第29行)。本博文廣泛使用include指令來提高可讀性並實現配置某些部分的自動化。
api_gateway.conf文件定義了將NGINX Plus公開為客戶端的API網關的虛擬伺服器。此配置公開API網關在單個入口點https://api.example.com/(第13行)發布的所有API,受第16到21行配置的TLS保護。請注意,此配置純粹是HTTPS - 沒有明文HTTP偵聽器。我們希望API客戶端知道正確的入口點並默認進行HTTPS連接。
此配置是靜態的 - 各個API及其後端服務的詳細信息在第24行的include偽指令引用的文件中指定。第27到30行處理日誌記錄默認值和錯誤處理,並在響應中討論錯誤部分如下。
一些API可以在單個後端實現,但是出於彈性或負載平衡的原因,我們通常期望存在多個API。使用微服務API,我們為每個服務定義單獨的後端;它們一起作為完整的API。在這里,我們的Warehouse API被部署為兩個獨立的服務,每個服務都有多個後端。
API網關發布的所有API的所有後端API服務都在api_backends.conf中定義。這里我們在每個塊中使用多個IP地址 - 埠對來指示API代碼的部署位置,但也可以使用主機名。 NGINX Plus訂戶還可以利用動態DNS負載平衡,自動將新後端添加到運行時配置中。
配置的這一部分首先定義Warehouse API的有效URI,然後定義用於處理對Warehouse API的請求的公共策略。
Warehouse API定義了許多塊。 NGINX Plus具有高效靈活的系統,可將請求URI與配置的一部分進行匹配。通常,請求由最具體的路徑前綴匹配,並且位置指令的順序並不重要。這里,在第3行和第8行,我們定義了兩個路徑前綴。在每種情況下,$ upstream變數都設置為上游塊的名稱,該上游塊分別代表庫存和定價服務的後端API服務。
此配置的目標是將API定義與管理API交付方式的策略分開。為此,我們最小化了API定義部分中顯示的配置。在為每個位置確定適當的上游組之後,我們停止處理並使用指令來查找API的策略(第10行)。
使用重寫指令將處理移至API策略部分
重寫指令的結果是NGINX Plus搜索匹配以/ _warehouse開頭的URI的位置塊。第15行的位置塊使用=修飾符執行完全匹配,從而加快處理速度。
在這個階段,我們的政策部分非常簡單。位置塊本身標記為第16行,這意味著客戶端無法直接向它發出請求。重新定義$ api_name變數以匹配API的名稱,以便它在日誌文件中正確顯示。最後,請求被代理到API定義部分中指定的上游組,使用$ request_uri變數 - 其中包含原始請求URI,未經修改。
API定義有兩種方法 - 廣泛而精確。每種API最合適的方法取決於API的安全要求以及後端服務是否需要處理無效的URI。
在warehouse_api_simple.conf中,我們通過在第3行和第8行定義URI前綴來使用Warehouse API的廣泛方法。這意味著以任一前綴開頭的任何URI都代理到相應的後端服務。使用基於前綴的位置匹配,對以下URI的API請求都是有效的:
如果唯一的考慮是將每個請求代理到正確的後端服務,則廣泛的方法提供最快的處理和最緊湊的配置。另一方面,精確的方法使API網關能夠通過顯式定義每個可用API資源的URI路徑來理解API的完整URI空間。採用精確的方法,Warehouse API的以下配置使用精確匹配(=)和正則表達式(〜)的組合來定義每個URI。
此配置更詳細,但更准確地描述了後端服務實現的資源。這具有保護後端服務免於格式錯誤的客戶端請求的優點,代價是正常表達式匹配的一些小額外開銷。有了這個配置,NGINX Plus接受一些URI並拒絕其他URI無效:
使用精確的API定義,現有的API文檔格式可以驅動API網關的配置。可以從OpenAPI規范(以前稱為Swagger)自動化NGINX Plus API定義。此博客文章的Gists中提供了用於此目的的示例腳本。
隨著API的發展,有時會發生需要更新客戶端的重大更改。一個這樣的示例是重命名或移動API資源。與Web瀏覽器不同,API網關無法向其客戶端發送命名新位置的重定向(代碼301)。幸運的是,當修改API客戶端不切實際時,我們可以動態地重寫客戶端請求。
在下面的示例中,我們可以在第3行看到定價服務以前是作為庫存服務的一部分實現的:rewrite指令將對舊定價資源的請求轉換為新的定價服務。
動態重寫URI意味著當我們最終在第26行代理請求時,我們不能再使用$ request_uri變數(正如我們在warehouse_api_simple.conf的第21行所做的那樣)。這意味著我們需要在API定義部分的第9行和第14行使用稍微不同的重寫指令,以便在處理切換到策略部分時保留URI。
HTTP API和基於瀏覽器的流量之間的主要區別之一是如何將錯誤傳達給客戶端。當NGINX Plus作為API網關部署時,我們將其配置為以最適合API客戶端的方式返回錯誤。
頂級API網關配置包括一個定義如何處理錯誤響應的部分。
第27行的指令指定當請求與任何API定義都不匹配時,NGINX Plus會返回錯誤而不是默認錯誤。此(可選)行為要求API客戶端僅向API文檔中包含的有效URI發出請求,並防止未經授權的客戶端發現通過API網關發布的API的URI結構。
第28行指的是後端服務本身產生的錯誤。未處理的異常可能包含我們不希望發送到客戶端的堆棧跟蹤或其他敏感數據。此配置通過向客戶端發送標准化錯誤來進一步提供保護。
完整的錯誤響應列表在第29行的include偽指令引用的單獨配置文件中定義,其前幾行如下所示。如果首選不同的錯誤格式,並且通過更改第30行上的default_type值以匹配,則可以修改此文件。您還可以在每個API的策略部分中使用單獨的include指令來定義一組覆蓋默認值的錯誤響應。
有了這種配置,客戶端對無效URI的請求就會收到以下響應。
在沒有某種形式的身份驗證的情況下發布API以保護它們是不常見的。 NGINX Plus提供了幾種保護API和驗證API客戶端的方法。有關基於IP地址的訪問控制列表(ACL),數字證書身份驗證和HTTP基本身份驗證的信息,請參閱文檔。在這里,我們專注於API特定的身份驗證方法。
API密鑰身份驗證
API密鑰是客戶端和API網關已知的共享密鑰。它們本質上是作為長期憑證發布給API客戶端的長而復雜的密碼。創建API密鑰很簡單 - 只需編碼一個隨機數,如本例所示。
在頂級API網關配置文件api_gateway.conf的第6行,我們包含一個名為api_keys.conf的文件,其中包含每個API客戶端的API密鑰,由客戶端名稱或其他描述標識。
API密鑰在塊中定義。 map指令有兩個參數。第一個定義了API密鑰的位置,在本例中是在$ http_apikey變數中捕獲的客戶端請求的apikey HTTP頭。第二個參數創建一個新變數($ api_client_name)並將其設置為第一個參數與鍵匹配的行上的第二個參數的值。
例如,當客戶端提供API密鑰7B5zIqmRGXmrJTFmKa99vcit時,$ api_client_name變數設置為client_one。此變數可用於檢查經過身份驗證的客戶端,並包含在日誌條目中以進行更詳細的審核。
地圖塊的格式很簡單,易於集成到自動化工作流程中,從現有的憑證存儲生成api_keys.conf文件。 API密鑰身份驗證由每個API的策略部分強制執行。
客戶端應在apikey HTTP頭中顯示其API密鑰。如果此標頭丟失或為空(第20行),我們發送401響應以告知客戶端需要進行身份驗證。第23行處理API鍵與地圖塊中的任何鍵都不匹配的情況 - 在這種情況下,api_keys.conf第2行的默認參數將$ api_client_name設置為空字元串 - 我們發送403響應告訴身份驗證失敗的客戶端。
有了這個配置,Warehouse API現在可以實現API密鑰身份驗證。
JWT身份驗證
JSON Web令牌(JWT)越來越多地用於API身份驗證。原生JWT支持是NGINX Plus獨有的,可以在我們的博客上驗證JWT,如使用JWT和NGINX Plus驗證API客戶端中所述。
本系列的第一篇博客詳細介紹了將NGINX Plus部署為API網關的完整解決方案。可以從我們的GitHub Gist倉庫查看和下載此博客中討論的完整文件集。本系列的下一篇博客將探討更高級的用例,以保護後端服務免受惡意或行為不端的客戶端的攻擊。
原文:https://dzone.com/articles/deploying-nginx-plus-as-an-api-gateway-part-1-ngin
本文:http://pub.intelligentx.net/deploying-nginx-plus-api-gateway-part-1-nginx
討論:請加入知識星球或者小紅圈【首席架構師圈】
⑨ 阿里雲API網關
API 網關(API Gateway)提供高性能、高可用的 API 託管服務,幫助用戶對外開放其做並部署在 ECS、容器服務等阿里雲產品上的應用,提供完整的 API 發布、管理、維護生命周期管理。用戶只需進行簡單的操作,即可快速、低成本、低風險地開放數據或服務。輔助用戶簡單、快速、低成本、低風險的實現微服務聚合、前後端分離、系統集成,向合作夥伴、開發者開放功能和數據
提供防攻擊、防重放、請求加密、身份認證、許可權管理、流量控制等多重手段保證 API 安全,降低 API 開放風險。
提供 API 定義、測試、發布、下線等全生命周期管理,並生成 SDK、API 說明文檔,提升 API 管理、迭代的效率。
提供便捷的監控、報警、分析、API 市場等運維、運營工具,降低 API 運營、維護成本。
API 網關將能力的復用率最大化,企業間能夠互相借力,企業發展能夠專注自身業務,實現共贏。
API 便捷管理 (便捷的 API 管理功能,便捷的 API 管理工具)
API 生命周期管理:覆蓋 API 的定義、測試、發布的整個生命周期管理,便捷的日常管理、版本管理,支持熱升級和快速回滾。
便捷工具&文檔:提供頁面調試工具,自動生成 API 文檔和 SDK,大大降低人力成本。
安全穩定 (嚴格的許可權管理、精準的流量控制、全面的監控報警)
安全防護:API 請求到達網關需要經過嚴格的身份認證、許可權認證,才能到達後端服務。支持 HMAC(SHA-1,SHA-256)演算法簽名,支持 SSL 加密
流量控制:可控制單位時間內 API 允許被調用次數。用來保護企業純腔跡的後端服務,實現業務分級和用戶分級。
支持對 API 流控,您可以根據 API 的重要程度來配置不同流控,從而保障重要業務的穩定運行。
支持用戶、應用和例外流控,您可以根據用戶的重要性來配置不同流控,從而可以保證大用戶的權益。
流控粒度:分鍾、小時、天。
請求管理 (通過參數校驗過濾無效請求,通過參數轉換實現 API 高度復用,一套 API 多種服務)
參數校驗:請求經過 API 網關,可根據您的配置進行參數類型、參數值(范圍、枚舉、正則、Json Schema)的校驗,減少後端對非法請求、無效請求的資源消耗和處理成本。
參數轉換:您可以在 API 網關定義參數映射規則,網關通過映射規則將後端服務通過映射翻譯成任何形式,以滿足不同用戶的不同需求,從而避免功能重復開發。
監控告警 (結合阿里雲監控服務,提供靈活全面的監控告警能力,該部分持續升級中)
監控告警:提供實時、可視化的 API 監控,包括:調用量、調用方式、響應時間、錯誤率,讓您能夠清楚的了解 API 的運行狀況和用戶的圓悉行為習慣。
支持自定義報警規則,來針對異常情況進行報警,降低故障處理時間。
API 市場 (一站式解決 API 管理和 API 變現)
API 市場:API 接入 API 網關後,還能以 API 服務的方式上架到阿里雲 API 市場。API 網關和API 市場將為您解決計量計費、Quota 控制、運營售賣等需求。
⑩ API網關express-gateway初體驗
昨天朋友發來一個消息,問我express源碼中的一個問題,我去看了一番源碼以後,發現自己並不是很懂,只能看懂一些字面意思...
不過在聊天過程中,了解到他們公司在用express做api網關,什麼是api網關呢?
我將以express-gateway為例,學習 get started教程 ,對api網關進行探索。
安裝
①npm i -g express-gateway
②創建一個express網關:eg gateway create
③根據提示選擇server模板
④運行express網關:npm start
5分鍾入門教程
目標:
1.選擇一個微服務並且作為一個api暴露出去
2.定義一個api的消費者
3.使用key認證保證api的安全性
1.選擇一個微服務並且作為一個api暴露出去
①直接訪問微服務
curl http://httpbin.org/ip
②指定微服務
在express gateway的一個默認的管道中,服務將被分配到一個埠。一個管道指的是一個策略集合。Express Gateway有一個代理策略。在默認的管道中,會使用這個代理策略,網關現在擋在了 https://httpbin.org/ip 服務前面,並且並且路由其它請求到網關的埠。
在config/gateway.config.yml這個文件中,可以找到一個serviceEndpoints選項,這里定義了httpbin這個服務。
在默認管道的proxy選項的action中,可以找到serviceEndpoint: httpbin
③以api的方式公開微服務
通過Express Gateway,我們將暴露httpbin 服務到api埠。當通過api埠公開api後,外部可以訪問到api。
在config/gateway.config.yml這個文件中,可以找到apiEndpoints選項,這里定義了api。
現在我們有一個公共api浮出水面了,我們應該確保自己可以穿過express網關獲取到service的許可權。
2.定義一個api網關的消費者
管理我們api的人,在這里我們稱之為「Consumer」。
eg users create
3.使用key認證方式確保安全
①現在api暴露了出去,而且也獲得了訪問許可權。我們現在將為其加上key安全認證。
在config/gateway.config.yml這個文件中,可以找到pipelines選項,這里定義了key-auth。
②為Consumer Bob分配key。
eg credentials create -c bob -t key-auth -q
③Bob沒有加key直接訪問。
④Bob加了key進行訪問。
That's it!