import webbrowser
python提供webbrowser模塊,可以調用這個模塊的open()方法打開指定網頁!
requests模塊屬于第三方模塊,因此需要安裝此模塊才可以使用:
pip install requests
requests.get()方法內需放置欲下載網頁信息的網址當參數,這個方法可以傳回網頁的HTML源文件。
由上述可知requests.get()方法傳回的數據類型是Response對象!!!!!那什么是Response對象呢??
Response對象有幾個重要屬性:
status_code:如果值是requests.codes.ok,表示獲得的網頁內容成功。
text:網頁內容。
有些網頁由反爬蟲機制,會造成網頁下載失敗。使用拋出異常可以處理類似問題。Response對象有raise_for_status()方法,可以針對網址正確但是后續文件名錯誤的狀況產生異常處理。也可以預防錯誤網址!!!
數是一組一起執行一個任務的語句。每個 C++ 程序都至少有一個函數,即主函數 main() ,所有簡單的程序都可以定義其他額外的函數。
您可以把代碼劃分到不同的函數中。如何劃分代碼到不同的函數中是由您來決定的,但在邏輯上,劃分通常是根據每個函數執行一個特定的任務來進行的。
函數聲明告訴編譯器函數的名稱、返回類型和參數。函數定義提供了函數的實際主體。
C++ 標準庫提供了大量的程序可以調用的內置函數。例如,函數 strcat() 用來連接兩個字符串,函數 memcpy() 用來復制內存到另一個位置。
函數還有很多叫法,比如方法、子例程或程序,等等。
定義函數
C++ 中的函數定義的一般形式如下:
return_typefunction_name(parameterlist){bodyofthefunction}
在 C++ 中,函數由一個函數頭和一個函數主體組成。下面列出一個函數的所有組成部分:
返回類型:一個函數可以返回一個值。return_type 是函數返回的值的數據類型。有些函數執行所需的操作而不返回值,在這種情況下,return_type 是關鍵字 void。
函數名稱:這是函數的實際名稱。函數名和參數列表一起構成了函數簽名。
參數:參數就像是占位符。當函數被調用時,您向參數傳遞一個值,這個值被稱為實際參數。參數列表包括函數參數的類型、順序、數量。參數是可選的,也就是說,函數可能不包含參數。
函數主體:函數主體包含一組定義函數執行任務的語句。
實例
以下是 max() 函數的源代碼。該函數有兩個參數 num1 和 num2,會返回這兩個數中較大的那個數:
// 函數返回兩個數中較大的那個數intmax(intnum1, intnum2){// 局部變量聲明intresult; if(num1 > num2)result = num1; elseresult = num2; returnresult; }
函數聲明
函數聲明會告訴編譯器函數名稱及如何調用函數。函數的實際主體可以單獨定義。
函數聲明包括以下幾個部分:
return_type function_name( parameter list );
針對上面定義的函數 max(),以下是函數聲明:
int max(int num1, int num2);
在函數聲明中,參數的名稱并不重要,只有參數的類型是必需的,因此下面也是有效的聲明:
int max(int, int);
當您在一個源文件中定義函數且在另一個文件中調用函數時,函數聲明是必需的。在這種情況下,您應該在調用函數的文件頂部聲明函數。
調用函數
創建 C++ 函數時,會定義函數做什么,然后通過調用函數來完成已定義的任務。
當程序調用函數時,程序控制權會轉移給被調用的函數。被調用的函數執行已定義的任務,當函數的返回語句被執行時,或到達函數的結束括號時,會把程序控制權交還給主程序。
調用函數時,傳遞所需參數,如果函數返回一個值,則可以存儲返回值。例如:
實例
#include<iostream>usingnamespacestd; // 函數聲明intmax(intnum1, intnum2); intmain(){// 局部變量聲明inta = 100; intb = 200; intret; // 調用函數來獲取最大值ret = max(a, b); cout << "Max value is : " << ret << endl; return0;}// 函數返回兩個數中較大的那個數intmax(intnum1, intnum2){// 局部變量聲明intresult; if(num1 > num2)result = num1; elseresult = num2; returnresult; }
把 max() 函數和 main() 函數放一塊,編譯源代碼。當運行最后的可執行文件時,會產生下列結果:
Max value is : 200
函數參數
如果函數要使用參數,則必須聲明接受參數值的變量。這些變量稱為函數的形式參數。
形式參數就像函數內的其他局部變量,在進入函數時被創建,退出函數時被銷毀。
當調用函數時,有兩種向函數傳遞參數的方式:
調用類型 | 描述 |
---|---|
傳值調用 | 該方法把參數的實際值復制給函數的形式參數。在這種情況下,修改函數內的形式參數對實際參數沒有影響。 |
指針調用 | 該方法把參數的地址復制給形式參數。在函數內,該地址用于訪問調用中要用到的實際參數。這意味著,修改形式參數會影響實際參數。 |
引用調用 | 該方法把參數的引用復制給形式參數。在函數內,該引用用于訪問調用中要用到的實際參數。這意味著,修改形式參數會影響實際參數。 |
默認情況下,C++ 使用傳值調用來傳遞參數。一般來說,這意味著函數內的代碼不能改變用于調用函數的參數。之前提到的實例,調用 max() 函數時,使用了相同的方法。
參數的默認值
當您定義一個函數,您可以為參數列表中后邊的每一個參數指定默認值。當調用函數時,如果實際參數的值留空,則使用這個默認值。
這是通過在函數定義中使用賦值運算符來為參數賦值的。調用函數時,如果未傳遞參數的值,則會使用默認值,如果指定了值,則會忽略默認值,使用傳遞的值。請看下面的實例:
實例
#include<iostream>usingnamespacestd; intsum(inta, intb=20){intresult; result = a + b; return(result);}intmain(){// 局部變量聲明inta = 100; intb = 200; intresult; // 調用函數來添加值result = sum(a, b); cout << "Total value is :" << result << endl; // 再次調用函數result = sum(a); cout << "Total value is :" << result << endl; return0;}
當上面的代碼被編譯和執行時,它會產生下列結果:
Total value is :300Total value is :120
Lambda 函數與表達式
C++11 提供了對匿名函數的支持,稱為 Lambda 函數(也叫 Lambda 表達式)。
Lambda 表達式把函數看作對象。Lambda 表達式可以像對象一樣使用,比如可以將它們賦給變量和作為參數傳遞,還可以像函數一樣對其求值。
Lambda 表達式本質上與函數聲明非常類似。Lambda 表達式具體形式如下:
[capture](parameters)->return-type{body}
例如:
[](int x, int y){ return x < y ; }
如果沒有參數可以表示為:
[capture](parameters){body}
例如:
[]{ ++global_x; }
在一個更為復雜的例子中,返回類型可以被明確的指定如下:
[](int x, int y) -> int { int z = x + y; return z + x; }
本例中,一個臨時的參數 z 被創建用來存儲中間結果。如同一般的函數,z 的值不會保留到下一次該不具名函數再次被調用時。
如果 lambda 函數沒有傳回值(例如 void),其回返類型可被完全忽略。
在Lambda表達式內可以訪問當前作用域的變量,這是Lambda表達式的閉包(Closure)行為。 與JavaScript閉包不同,C++變量傳遞有傳值和傳引用的區別。可以通過前面的[]來指定:
[] // 沒有定義任何變量。使用未定義變量會引發錯誤。[x, &y] // x以傳值方式傳入(默認),y以引用方式傳入。[&] // 任何被使用到的外部變量都隱式地以引用方式加以引用。[=] // 任何被使用到的外部變量都隱式地以傳值方式加以引用。[&, x] // x顯式地以傳值方式加以引用。其余變量以引用方式加以引用。[=, &z] // z顯式地以引用方式加以引用。其余變量以傳值方式加以引用。
另外有一點需要注意。對于[=]或[&]的形式,lambda 表達式可以直接使用 this 指針。但是,對于[]的形式,如果要使用 this 指針,必須顯式傳入:
[this]() { this->someFunc(); }();
者:人月神話,新浪博客同名
簡介:多年SOA規劃建設,私有云PaaS平臺架構設計經驗,長期從事一線項目實踐
今天準備再詳細講解下API網關的基礎概念,使用場景和核心功能,以及基于API網關核心引擎做的API全生命周期管理功能擴展等,最好再介紹下當前主流的開源API網關引擎。
在微服務架構體系里面,我們一般會使用到微服務網關或叫API網關。
大家都比較清楚,在微服務架構體系下本身是去中心化的架構,通過服務注冊中心來實現服務注冊發現和消費調用,那么為何又需要使用API網關?
在傳統的ESB總線進行服務集成的時候我們就經常談到一個概念就是位置透明,即需要屏蔽底層業務模塊提供API接口服務地址信息,并實現多個微服務API接口的統一出口。即類似設計模式里面經常談到的門面模式。
如何給API網關一個定義?
簡單來說API網關就是將所有的微服務提供的API接口服務能力全部匯聚進來,統一接入進行管理,也正是通過統一攔截,就可以通過網關實現對API接口的安全,日志,限流熔斷等共性需求。如果再簡單說下,通過網關實現了幾個關鍵能力。
從這里,我們就可以看到API網關和傳統架構里面的ESB總線是類似的,這些關鍵能力本身也是ESB服務總線的能力,但是ESB服務總線由于要考慮遺留系統的接入,因此增加了:
對于兩者,我原來做過一個簡單的對比,大家可以參考。
這個概念理解后,我們再回到微服務架構里面。
對于微服務架構大家經常說的最多的就是去中心化的架構,認為ESB中心化架構模式已經過時。而實際上經過上面分析你可以看到。在微服務架構里面的API網關仍然是中心化的架構模式,所有的API接口都要經過網關這個點。
對于微服務架構里面有無去中心化的架構?當然是有的,即我們常說的微服務模塊之間可以通過服務注冊中心來實現服務發現查找,服務間的點對點調用即使去中心化的。
如果一個單體拆分為微服務后,完全不需要和外部應用打交道,也不需要共享自己的接口能力,那么這個微服務體系里面就不需要用API網關,僅僅使用服務注冊中心即可。通過服務注冊中心實現完全的去中心化和接口調用更高的性能。
什么時候需要使用API網關?
如果一個微服務架構下,雖然不會外部的其它應用進行交互和集成,但是整個應用本身存在APP應用端,而APP應用端通過前后端分析開發,同時需要通過互聯網訪問。本身存在需要一個統一訪問API訪問入口,同時也需要考慮和內部微服務模塊進一步進行安全隔離。
當我們談到這里的時候,你會發現我們常說的API網關的服務代理或透傳能力,實際和我們常說的Ngnix反向代理或路由是一個意思。
如果你僅僅是為了統一API接口的訪問出口,并考慮類似DMZ區的安全隔離,那么在你架構前期完全不需要馬上實施API網關,直接采用Ngnix進行服務路由代理即可。因為在這種架構下,API接口消費端,提供端全部是一個開發團隊開發,各種問題分析排查都相當方便,類似API接口安全訪問等也可以通過JWT,Auth2.0等統一實現,而且這個過程也并不復雜。
能力開放或多應用外部集成對API管控治理需要
但是當我們面臨是和多個外部應用集成,或者說將自己的API接口服務能力開放給外部多個合作伙伴使用的時候,這個時候對于API接口的管控治理要求自然增加。
即在常規的服務代理路由基礎上,需要增加類似負載均衡,安全,日志,限流熔斷等各種能力,而且我們不希望這些能力在API接口開發的時候考慮,而是希望這些能力是在API接入到網關的時候統一靈活配置來實現管控。
那么這個時候使用API網關作用就體現出來。
對于API網關實際上前面已經多次強調,可以看做是ESB總線的輕量化實現,不再需要復雜的協議轉換,適配和數據映射等能力,但是提升了流量控制和安全,實時監控等方面的能力。對于API網關引擎部分提供的核心功能,再簡單總結如下:
1.實現統一服務代理和服務統一出口
這點是網關和常規點對點服務注冊中心最大的一個區別點,就是位置透明,消費端只需要和網關打交道,具體網關如何和后臺的微服務模塊打交道,后臺微服務模塊的部署邏輯,模塊提供服務的IP地址等都不用關心。
由于實現了位置透明,帶來一點就是數據流必須通過網關,那么網關本身又成為了去中心的微服務架構中的中心化節點,那么就必須考慮網關節點的性能,可靠性和彈性擴展能力。
網關要實現位置透明,延伸出來對應的網關必須提供的能力就包括了
在這里準備重點強調下負載均衡能力,實際上對于API網關往往并不是必須具備負載均衡能力。
我們可以看下對于注冊和接入到API網關服務的三種場景,只有場景一需要由API網關來提供負載均衡能力。
注意API網關是否需要具備負載均衡能力,是必須考慮的一個點,即如果底層微服務模塊提供的API接口服務本身能夠提供負載均衡后的地址,那么網關不需要進行負載均衡。如果底層模塊不具備這個能力,那么網關必須具備負載均衡能力。
微服務模塊本身可以基于容器化資源池提供的能力進行動態擴展,因此這個地方本身又有兩層負載均衡,一個是kubernates提供的集群能力,一個是多個API網關本身提供的集群能力。當然API網關本身也具備負載均衡功能,可以和Kubernate進行銜接。
2. 通過網關的攔截能力來實現所有共性能力抽取和實現
剛才已經談到啟用網關后就承載了數據流,因此可以通過對接口訪問輸入和輸出的攔截來實現所有共性可復用能力的抽取和實現。這些共性能力可以理解為網關實現的一個個攔截插件,本身可插拔,靈活可配置。
這些插件能力中最核心的就是安全,日志,流控。
其中安全可以實現訪問安全,傳輸安全,數據安全等,其中訪問安全本身又可以實現類似Token,IP,用戶名密碼等多種安全控制策略。包括對Auth2.0等標準規范的支持等。
對于日志也是網關提供的一個關鍵能力,即可以實現對服務消費日志,詳細的輸入和輸出報文的查詢能力,這個在各開源網關往往并不具備這個能力,也無法面向業務系統人員去使用,因此這塊能力提升往往都需要在開源網關基礎上做大量擴展。
流控是我們談的另外一個關鍵能力,包括了服務限流和服務熔斷。對于服務限流主要是實現對服務消費前線程數控制,資源分配實現消費前等待。而對于服務熔斷,即直接對服務進行下線或禁用,以避免大并發服務消費調用對網關造成的影響或帶來的服務雪崩等。
一個網關來說,流控能力相對關鍵,因為網關是中心化節點,必須保證網關的高可靠運行。因此網關流控能力強弱直接影響到網關的高可靠性和性能,而判斷流控能力強弱的關鍵則在于靈活的流量控制策略配置,只有這樣才能夠做到既實現流控,又不影響到關鍵業務和接口服務的訪問。
3. 滿足前后端分離的需求
注意,如果一個企業開發的業務系統涉及到手機APP端,而手機APP端一定涉及到公網訪問,按業務系統內部部署安全策略也一定涉及到DMZ區的設置和硬件防火墻隔離。
而對于API網關本身恰好又是可以部署到DMZ區的一個內容,既實現了服務代理路由,又實現了安全隔離,如果存在這種場景,即使業務應用不和外部系統打交道,為了前后端的隔離和外部訪問,往往也需要API網關能力支撐。當然前期你也可以使用Ngnix來替代API網關實現統一代理。
4. 灰度發布或金絲雀發布
這個在我原來談網關的文章的時候很少談到這點,但是實際上在DevOps和微服務架構實施下,對于灰度發布能力往往也是必須的。比如我們對已有的一個接口服務做了修改,我們想先在某些業務系統試用,沒有問題再發布到所有的業務系統。這個時候就涉及到金絲雀發布的問題。當然你可以配置是按系統,按IP,按用戶還是其他的發布策略。
這塊的能力不僅僅是DevOps的自動部署,同時也必須考慮網關層能夠基于動態發布的內容進行路由。確保服務調用消費的路由路徑是隔離開的。而對于金絲雀發布策略允許你直接只導入指定量的流量到新的版本,API網關就可以幫你來做這件事情。你可以配置10%的請求到新的版本,然后一旦你確保了新版本沒有bug,你可以把流量切換到100%。
5. 服務組合能力
實際上當我們談API網關的時候,一般不會談服務組合能力,因為一涉及到服務組合或編排,那么必然導入網關整體架構變重。從當前主流網關看,一般也不提供類似能力。
實際上服務組合編排難點在于,上個服務的輸出往往要成為下一個服務的輸入,同時服務輸入和輸出還存在大量的數據映射操作。我們回顧下類似智慧家庭里面的組合場景編排,實際上很簡單,比如我回到家后需要打開空調,關窗簾,打開熱水器,開燈的一系列動作,我只是需要簡單將這些動作編排在一起。
對應到API網關的服務組合,實際上我們也可以做輕量的服務組合,即去掉數據映射等復雜組合場景,只需要實現簡單的服務多次調用,服務返回數據的組合等即可。
對于具體的服務組合和編排,可以參考下面這篇文章:
從ESB服務組合編排到NetflixConductor微服務編排
可以看到,API網關更多是一個底層引擎,而要實現完整的API管控,往往還需要配合API全生命周期管理能力。這個完全可以在底層API網關引擎基礎上進行擴展開發。
API接口的定義
在定義API接口的時候首先要定義API分組,這個從京東,淘寶等OpenAPI能力開放平臺的API文檔都可以看到,首先要有API歸類分組,然后再定義詳細的API。
比如京東開放平臺,有商品,店鋪,倉儲,支付等多個類目,然后各類目下有詳細的API的定義。
API的定義包括兩個部分,一個是API基本信息定義,一個是詳細輸入輸出定義。
API基本信息仍然是包括了API的編碼,API名稱,API的分組,API的用途描述,API的緩存,安全等基本控制信息的定義等。還有就是這個API接口的訪問路徑定義,API接口是Get還是Post方法定義等。
API詳細信息主要就是API的輸入和輸出信息定義。
API的輸入參數注意實際有多種形式,一個就是在API訪問路徑上的路徑參數,還有一個就是在訪問路徑后?參數后面的查詢參數信息,還有就是一個完整的Request Body請求參數信息。
比如對于Http Rest查詢接口,這類Get方法接口,可以看到并沒有Body信息,更多的是通過路徑和查詢參數定義來完成查詢。而對于Post接口往往就涉及到具體的Body信息定義。
但是要注意,為了實現Http Rest接口和SOAP WS接口服務的互相轉換,對于SOAP WS查詢服務接口在自動轉換為Http Rest接口服務的時候實際上仍然為轉換為Post方法+Body參數模式。
對于API接口定義,仍需要預留標準的系統級參數部分內容。這部分內容是API網關實現統一標準化管理的基礎,不能隨便修改和變動。比如京東API平臺預留的API名稱,方法,版本,Token,APP_Key,Date等都是使用系統級別的參數定義,是每一個接口API暴露后都需要增加的參數頭信息。
API快速開發的支持
在API接口服務定義完成后,一方面是可以通過類似WADL或RAML等標準的Rest接口定義規范文件,另外一個就是需要提供客戶端和服務端的開發框架代碼。
在這個基礎上,還可以提供完整的示例代碼下載,方便開發商或合作伙伴對API接口進行快速開發。開發完成的后端原始服務接口,在注冊接入前還可以提供接口服務的模型匹配自校驗功能,確認開發的服務完全遵循從上到下方式-》API開發框架生成和API后端服務開發。
對于API接口管理,如果是標準的從頂朝下模式,即在定義了API接口后,實現生成類似WADL或RAML標準接口規范。后端服務基于我們標準的API接口契約進行開發,那么開發完成后就方便快速代理方式接入,在接入過程中就不再有參數映射和轉換的問題,否則我們的API接入過程會比較復雜。
API接口服務的注冊和接入
API接口定義過程和API接口的注冊接入最好分開。
在API接口定義完成后進行API接口服務的注冊,即選擇具體的后端服務,然后對服務進行接入。同時將后端服務對應到我們在前面定義的API接口代理服務上。注意在前面談到的API路徑定義,方法類型定義,實際上也可以在API接口服務注冊和接入的時候來完成。
API接口服務的后續變更發布,還可以考慮和DevOps平臺配合并支持灰度發布功能。
反向的后端服務快速接入并發布為API接口服務,即直接對后端已有的API服務進行快速接入,將API后端服務發布為代理服務,在整個接入過程中需要定義API接口名稱,API訪問路徑,API方法類型等信息。在發布為API接口服務后,對于后端服務的API參數信息也需要進行快速導入,以方便在API接口查詢中看到詳細的接口內容定義。
在將后端業務服務發布為API接口服務的時候,發布的代理服務要自動增加系統級的輸入參數信息,這個輸入參數最好的方式是在訪問路徑中進行增加,以減少對已有的后端服務的影響。
API接口在注冊和接入完成后,將自動進行服務部署和服務發布,即注冊接入完成后的服務可以通過發布的訪問路徑地址進行訪問。
服務接入適配能力
服務注冊接入本身分為兩個層面,一個是已有服務的注冊接入,一個是需要適配后的服務發布。在設計的時候需要考慮到兩個方面的需求。
對于已有服務的存代理接入最簡單,即只需要提供業務系統的Rest接口服務地址即可,在接入的時候,對相關的日志,安全,流控,負載均衡等策略進行配置,配置完成后即完成服務接入和注冊。同時對于路由服務接入需要單獨考慮,對于路由服務在接入的時候可以適配到多個原始業務系統的接口服務地址。
服務發布是對原來我們服務適配功能的一個改進,即直接從底向上的進行服務發布,而不需要實現定義服務元數據或模型,制定服務契約格式等,在服務發布完成后再生成相關的基礎數據到服務元數據庫即可。對于服務發布參考服務適配的能力,我們可以考慮如下場景下的需求。
對于服務發布而言,如果不僅僅是微服務網關能力,而是一個微服務支撐或微服務快速開發平臺的話,還可以提供完整的服務開發和設計能力。即在微服務平臺首先定義數據或對象模型,然后將對象模型轉換為Http Rest中的資源對象,并發布對應的Get , Post各種Http Rest接口服務。
對應發布的接口服務可以直接在微服務平臺上進行攔截,模擬生成相關的輸入或輸出數據。當然也可以直接將數據模型對象生成到對應的數據庫,同時將微服務API接口的實現生成對應的Java代碼框架并給出參考實現。而我們剩余的工作,僅僅是填充代碼邏輯即可。通過這種方式可以極大的提高我們進行微服務架構開發的速度。
API接口在線模擬測試功能
這個功能參考當前的OpenAPI能力開放平臺的做法來實現即可。即對于已經發布完成的API接口服務,提供在線測試工具進行在線測試。同時對接口服務調用的輸入參數進行結構化展示,方便用戶對測試需要的各種參數進行輸入。在輸入完成后形成完整的提交參數完整字符串。通過測試,可以返回最終的模擬調用返回結果字符串信息。
同樣,這里可以采用Swagger工具來完成,Swagger不僅僅是API接口的定義,接口文檔的生成,同時還可以根據可以接口定義,自動生成接口測試用例,對接口進行測試工作。我們也很容易將Swagger能力整合都API網關的管理平臺中。
API接口查詢功能
對于API接口查詢功能也是一個標準的功能,實際上可以考慮將查詢功能和API接口服務的分類瀏覽分開。對于API接口的分類瀏覽參考開放平臺的API接口文檔做法來實現接口。對于API接口查詢,即可以設置不同的動態查詢條件,對API接口進行查詢,返回結果集。對于查詢到的API接口清單列表,可以點擊詳細進入到API接口詳細的輸入和輸出信息查看界面。
API狀態管理功能
對于已經注冊和發布的API接口可以對其狀態進行管理。其中主要的狀態包括了待發布,上線,暫停,下線廢棄等幾種關鍵狀態。對于API狀態本身還需要和后續的API監控管理結合,能夠通過API性能監控動態的調整API接口的狀態。比如在API觸發熔斷后,自動對API接口狀態調整為暫停。
API版本管理能力
對于API需要啟用版本管理能力。當前一些API接口服務實現方法會在路徑參數中增加API版本信息,以確定究竟訪問哪個版本。但是由于不同的API版本可能存在返回的結果集的數據結構不一樣的問題,因此對于這種場景需要針對該API定義不同的大版本,不同的大版本實際上對應不同的后端原始服務。
在這里我們介紹下當前主流的一些API網關功能供參考。
在微服務架構之下,服務被拆的非常零散,降低了耦合度的同時也給服務的統一管理增加了難度。如上圖左所示,在舊的服務治理體系之下,鑒權,限流,日志,監控等通用功能需要在每個服務中單獨實現,這使得系統維護者沒有一個全局的視圖來統一管理這些功能。API 網關致力于解決的問題便是為微服務納管這些通用的功能,在此基礎上提高系統的可擴展性。
Kong 的插件機制是其高可擴展性的根源,Kong 可以很方便地為路由和服務提供各種插件,網關所需要的基本特性,Kong 都如數支持:
從上面圖可以看到,Kong網關是基于OpenResty應用服務器,OpenResty是一個基于 Nginx 與 Lua 的高性能 Web 平臺,其內部集成了大量精良的 Lua 庫、第三方模塊以及大多數的依賴項。用于方便地搭建能夠處理超高并發、擴展性極高的動態 Web 應用、Web 服務和動態網關。而Kong 核心基于OpenResty構建,并且擁有強大的插件擴展功能。
在Http請求到達Kong網關后,轉發給后端應用之前,可以通過網關的各種插件對請求進行流量控制,安全,日志等各方面的處理能力。當前Kong的插件分為開源版和社區版,社區版還有更多的定制功能,但是社區版是要收費的。
目前,KONG開源版本一共開放28個插件,如下:
acl、aws-lambda、basic-auth、bot-detection、correlation-id、cors、datadog、file-log、galileo、hmac-auth、http-log、ip-restriction、jwt、key-auth、ldap-auth、loggly、oauth2、rate-limiting、request-size-limiting、request-termination、request-transformer、response-ratelimiting、response-transformer、runscope、statsd、syslog、tcp-log、udp-log。
以上這些插件主要分五大類,Authentication認證,Security安全,Traffic Control流量控制,Analytics & Monitoring分析&監控,Logging日志,其他還有請求報文處理類。插件類似AOP開發中的橫切功能,可以靈活的配置進行攔截控制,下面選擇一些關鍵性的插件進行簡單的說明。
黑白名單控制能力-ip-restriction
Kong提供的IP黑白名單控制能力還算相當強,從配置項里面可以看到主要可以針對兩個維度進行配置,一個是針對所有的API接口還是針對特定的API接口,一個是針對所有的所有的消費方還是特定的某個消費方。對于IP配置可以是一個區段,也可以是特定的IP地址。但是黑白名單不能同時配置,其次當前沒有一個功能是針對某一個系統提供的所有服務都啟用黑名單或白名單功能。
日志記錄能力-syslog, file-log,http-log
這里主要日志的插件比較多,一個是sysLog在配置后可以直接將Kong產生的日志寫入到應用服務器的系統日志文件中。如果配置了file-log則是單獨寫入到你指定的file文件中。對于http-log則是對于http服務請求,可以詳細的記錄請求的輸入和輸出報文信息,但是具體是記錄到哪里,需要通過config.http_endpoint配置。具體關鍵的配置參數信息如下:
consumer_id: 可選參數,消費者id(啟用了消費者認證可以使用,根據id識別發出請求的消費者);
config.http_endpoint: 日志接收服務器(包括使用的協議,http or https);
config.method: 可選參數,默認POST,訪問日志服務器的請求方式(可選值:PUT,PATCH,POST);
config.timeout: 可選參數,默認10000毫秒,請求超時時間
config.keepalive: 可選參數,默認60000毫秒,連接在關閉之前可存活時間
熔斷插件-request-termination
該插件用來定義指定請求或服務不進行上層服務,而直接返回指定的內容.用來為指定的請求或指定的服務進行熔斷。注意Kong的熔斷插件感覺是臨時對服務的禁用,而不是說當達到某一種監控閾值的時候自動觸發熔斷,或者相關內容還沒有了解到。從官方文檔的應用場景也可以看到這點。
Temporarily disable a Service (e.g. it is under maintenance).
Temporarily disable a Route (e.g. the rest of the Service is up and running, but a particular endpoint must be disabled).
Temporarily disable a Consumer (e.g. excessive consumption).
如果僅僅是這種方式的熔斷話,實際上意義并不是很大。但是可用的地方就在于當某個業務系統進行發版部署的時候我們可以對該業務系統或該業務系統所提供的所有服務進行熔斷。
限流插件-rate-limiting
Kong當前提供的限流相對來說還是比較弱,即主要是控制某一個API接口服務在單位時間內最多只能夠調用多少次,如果超過這個次數那么網關就直接拒絕訪問并返回錯誤提示信息。而在前面我講限流和流量控制的時候經常會說到,就是限流實際上一個是根據服務調用次數,一個是根據服務調用數據量,需要在這兩個方面進行限流。而里面更加重要的反而是數據量的限流,因為大數據量報文往往更加容易造成內存溢出異常。
安全認證類插件
當前Kong網關提供basic-auth,key-auth、ldap-auth,hmac-auth多種認證插件。
Basic-auth基本認證插件,即我們根據用戶名和密碼來生成一個base64編碼,同時將該編碼和目標服務綁定,這樣在消費目標服務的時候就需要在報文頭填寫這個Base64編碼信息。
Key-auth認證插件則是利用提前預設好的關鍵字名稱,如下面設置的keynote = apices,然后為consumer設置一個key-auth 密鑰,假如key-auth=test@keyauth。在請求api的時候,將apikey=test@keyauth,作為一個參數附加到請求url后,或者放置到headers中。
Hmac-auth插件是設置綁定的service和rout,以啟動hmac驗證。然后在Consumers頁面中Hmac credentials of Consumer設置中添加一個username和secret。
請求報文容量限制-request-size-limiting
該插件用于限制請求報文的數據量大小,可以限制單個服務,也可以顯示所有的API接口服務。
支持OAuth2.0身份認證-oauth2
Kong網關支持OAuth2.0身份認證,OAuth2.0 協議根據使用不同的適用場景,定義了用于四種授權模式。
Authorization code(授權碼模式):標準的 Server 授權模式,非常適合 Server 端的 Web 應用。一旦資源的擁有者授權訪問他們的數據之后,他們將會被重定向到 Web 應用并在 URL 的查詢參數中附帶一個授權碼(code)。在客戶端里,該 code 用于請求訪問令牌(access_token)。并且該令牌交換的過程是兩個服務端之前完成的,防止其他人甚至是資源擁有者本人得到該令牌。另外,在該授權模式下可以通過 refresh_token 來刷新令牌以延長訪問授權時間,也是最為復雜的一種方式。
Implicit Grant(隱式模式):該模式是所有授權模式中最簡單的一種,并為運行于瀏覽器中的腳本應用做了優化。當用戶訪問該應用時,服務端會立即生成一個新的訪問令牌(access_token)并通過URL的#hash傳回客戶端。這時,客戶端就可以利用JavaScript等將其取出然后請求API接口。該模式不需要授權碼(code),當然也不會提供refresh token以獲得長期訪問的入口。
Resource Owner Password Credentials(密碼模式):自己有一套用戶體系,這種模式要求用戶提供用戶名和密碼來交換訪問令牌(access_token)。該模式僅用于非常值得信任的用戶,例如API提供者本人所寫的移動應用。雖然用戶也要求提供密碼,但并不需要存儲在設備上。因為初始驗證之后,只需將 OAuth 的令牌記錄下來即可。如果用戶希望取消授權,因為其真實密碼并沒有被記錄,因此無需修改密碼就可以立即取消授權。token本身也只是得到有限的授權,因此相比最傳統的 username/password 授權,該模式依然更為安全。
Client Credentials(客戶端模式):沒有用戶的概念,一種基于 APP 的密鑰直接進行授權,因此 APP 的權限非常大。它適合像數據庫或存儲服務器這種對 API 的訪問需求。
簡單轉換能力-request-transformer and response transformer
Kong網關提供對輸入和輸出報文簡單轉換的能力,這部分內容后續再詳細展開介紹。從當前配置來看,主要是對消息報文提供了Add, Replace,Rename,Append等各種簡單操作能力。
Kong網關和其它網關的一些對比。
從上面對比圖也可以看到,Kong網關在功能,性能,插件可擴展性各方面都能夠更好的滿足企業API網關的需求。因此我們也是基于Konga來進一步定制對Kong網關的管控治理平臺。
在整個定制中增加了基于DB適配的Http Rest API接口的自動發布,API服務自動化注冊,服務日志采集和服務日志查詢,常見映射模板定制,接口服務的自動化測試等方面的能力。
首先我們來看下阿里云提供的API網關產品的功能介紹:
API 網關(API Gateway),是提供API托管服務,涵蓋API發布、管理、運維、售賣的全生命周期管理。輔助用戶簡單、快速、低成本、低風險的實現微服務聚合、前后端分離、系統集成,向合作伙伴、開發者開放功能和數據。
阿里提供的API網關提供的關鍵功能,參考產品本身的功能文檔說明,主要如下:
API 生命周期管理
支持包括API 注冊和接入發布、API 測試、API 下線等生命周期管理功能。支持 API 日常管理、API 版本管理、API 快速回滾等維護功能。基本需要覆蓋API管理全生命周期。
全面的安全防護
支持多種認證方式,支持 HMAC (SHA-1,SHA-256) 算法簽名。支持 HTTPS 協議,支持 SSL 加密。防攻擊、防注入、請求防重放、請求防篡改。(沒看到是否支持Auth2.0和具體的Token驗證機制)
靈活的權限控制
用戶以 APP 作為請求 API 的身份,網關支持針對 APP 的權限控制。只有已經獲得授權的 APP 才能請求相應的 API。API 提供者可以將調用某個API 的權限主動授予給某個APP。若 API上架到 API 市場,購買者可以將已購買的 API 授權給自己的 APP。(沒看到是否基于IP進行控制,還是基于Token進行控制,即對于消費方分配獨立的Token信息)
精準的流量控制
流量控制可以用于管控 API的被訪問頻率、APP的請求頻率、用戶的請求頻率。流量控制的時間單位可以是分鐘、小時、天。支持流控例外,允許設置特殊的 APP 或者用戶。(流量控制只支持服務運行頻率,沒看到可以基于數據量進行流控)
請求校驗
支持參數類型、參數值(范圍、枚舉、正則、Json Schema)校驗,無效校驗會被 API 網關直接拒絕,以減少無效請求對后端造成的資源浪費,大幅降低后端服務的處理成本。(這個功能實際有一定的用處,并不會犧牲太多的性能,但是會實現一些簡單的參數完整性校驗能力。)
數據轉換
通過配置映射規則,實現前、后端數據翻譯。支持前端請求的數據轉換。支持返回結果的數據轉換。(暫時不清楚數據轉換功能能夠實現的能力)
監控報警
提供可視化的API實時監控,包括:調用量、流量大小、響應時間、錯誤率,在陸續增加維度。支持歷史情況查詢,以便統籌分析。可配置預警方式(短信、Email),訂閱預警信息,以便實時掌握API運行情況。
自動工具
自動生成 API 文檔,可供在線查看。API 網關提供多種語言 SDK 的示例。降低 API 的運維成本。提供可視化的界面調試工具,快速測試,快速上線。(當前網上也有不少的API接口文檔自動生成工具可選)
API 市場
可將 API 上架到 API 市場,供更多開發者采購和使用。
從整個功能的介紹可以看到對于API的全生命周期管理(注冊,接入,代理,路由,負載均衡),安全,權限,流量控制,監控和告警等是所有API網關都必須具備的功能。而對于API市場,API文檔自動生成,請求的參數校驗,數據的轉換等則可以看做是擴展功能。
對于API市場往往是一個重要的擴展能力,即對于API接口服務可以作為商品一樣進行訂購和使用,并根據相應的調用次數,調用的數據量等條件進行計費處理。這我們我們說的PaaS平臺的服務層能力作為產品和服務發布,能夠進行訂購生產訂單,能夠進行計費等完全是一個道理。
對于公有云上API網關存在的背景說明
對于類似亞馬遜,華為云,阿里云等公有云上為何要提供API網關類產品,其關鍵點還是在于一個企業如果內部的主動業務應用和系統都遷移到公有云后,那么當企業需要將內部多個業務系統的共享或發布給外部使用的時候如何做?這個時候必須要有一個API網關,來進行能力的統一發布,最基本是提供統一的服務目錄訪問,更加重要的是實現統一的安全管理,授權,服務日志監控預警能力。
因此一個企業遷移到公有云后,只要存在內部多業務系統,多組件都需要發布API接口能力給外部使用的時候,一定存在API網關的應用場景。
有贊團隊的API網關實踐
https://tech.youzan.com/api-gateway-in-practice/
有贊API網關目前承載著微商城、零售、微小店、餐飲、美業、AppSDK、部分PC、三方開發者等多個業務的調用,每天有著億級別的流量。
有贊后端服務最開始是由PHP搭建,隨著整個技術體系的升級,后面逐步從PHP遷移到基于Dubbo開發了一個新的框架Nova,兼容Dubbo調用,同時支持調用PHP服務。于是網關也支持了新的Nova協議,這樣就有Dubbo、Http、Nova三種協議。
在這篇文章中提到的網關核心設計部分相關內容可以參考
異步特性:我們使用Jetty容器來部署應用,并開啟Servlet3.0的異步特性,由于網關業務本身就是調用大量業務接口,因此IO操作會比較頻繁,使用該特性能較大提升網關整體并發能力及吞吐量。
緩存:為了進一步提升網關的性能,我們增加了一層分布式緩存(借用Codis實現),將一些不經常變更的API元數據緩存下來,這樣不僅減少了應用和DB的交互次數,還加快了讀取效率。
鏈式處理:在設計網關的時候,我們采用責任鏈模式來實現網關的核心處理流程,將每個處理邏輯看成一個Pipe,每個Pipe按照預先設定的順序先后執行
平滑限流:消除了簡單計數器限流帶來的短時間內流量不均的問題。目前網關支持IP、店鋪、API、應用ID和三方ID等多個維度的限流,也支持各維度的自由組合限流。
熔斷降級:使用Hystrix進行熔斷降級處理。Hystrix支持線程池和信號量2種模式的隔離方案,內部也開發了一個基于Hystrix的服務熔斷平臺
預警監控:實時地從Kafka消費API調用日志,如果發現某個API的RT或者錯誤次數超過配置的報警閾值,則會立即觸發報警
企業級API網關設計
https://cloud.tencent.com/developer/article/1080652
這篇文章是對企業級API網關設計必須系統化的產生,從API網關的概述,API網關所起的作用,當前主流的API網關功能對比分析,API網關的高可用性設計多方面進行了闡述。
網關層作為客戶端與服務端的一層擋板,主要起到了三大類作用:
API網關作為對外提供服務的入口,就像企業服務的大門。一方面,要有足夠的能力,應對大量的對外訪問,另一方面,還要給對內的服務提供一定的安全保障。除此之外,企業提供的API服務多種多樣,API網關要能夠對這些API的全生命周期進行便捷的管理,例如服務發布、調整、下架、計費、監控等。
企業API網關在功能設計上主要應該考慮如下內容:
API 生命周期管理功能:覆蓋 API 的定義、測試、發布的整個生命周期管理。
API開發和使用支持功能:
順著這篇文章,我們參考了另外一篇談如何設計高并發下API網關的一篇文章,重點對并發模型,SEDA基于事件的并發架構進行了闡述。
地址:https://mp.weixin.qq.com/s?__biz=MzI5MDEzMzg5Nw==&mid=412734308&idx=1&sn=f1c1bd5e22e2ae7dedf4b788a625e814&scene=21#wechat_redirect
傳統的并發編程模型主要有兩種:一種是Thread-based concurrency, 另一種是Event-driven concurrency。總結下兩種模式的特點如下:
基于線程的并發:每個任務一線程直線式的編程使用資源高昂,context切換代價高,競爭鎖昂貴,太多線程可能導致吞吐量下降,響應時間暴漲;
基于事件的并發:單線程處理事件的每個并發流實現為一個有限狀態機應用直接控制并發負載增加的時候,吞吐量飽和響應時間線性增長。
SEDA架構是目前云計算、微服務時代下一種優秀的消息處理架構,而且歷經考驗,穩定可靠。SEDA架構的核心思想:把一個請求處理過程分成幾個Stage,每個Stage可由不同的微服務進行處理,不同資源消耗的Stage使用不同數量的線程來處理,微服務之間采用異步通訊的模式。
開源API網關Goku
GoKu API Gateway,中文名:悟空API網關,是eoLinker旗下、國內首個企業級開源的go語言API網關,幫助企業進行API服務治理與API性能安全維護,為企業數字化賦能。
GoKu支持OpenAPI與微服務管理,支持私有云部署,實現API轉發、請求參數轉換、數據校驗等功能,提供圖形化界面管理,能夠快速管理多個API網關,提高API業務安全性。
Goku API Gateway (悟空 API 網關)是運行在企業系統服務邊界上的微服務網關。當您構建網站、App、IOT甚至是開放API交易時,Goku API Gateway 能夠幫你將內部系統中重復的組件抽取出來并放置在Goku網關上運行,如進行用戶授權、訪問控制、防火墻、數據轉換等;并且Goku 提供服務編排的功能,讓企業可以快速從各類服務上獲取需要的數據,對業務實現快速響應。
Goku API Gateway 的社區版本(CE)擁有完善的使用指南和二次開發指南,代碼使用純 Go 語言編寫,擁有良好的性能和擴展性,并且內置的插件系統能夠讓企業針對自身業務進行定制開發。并且 Goku API Gateway 支持與 EOLINKER 旗下的 API Studio 接口管理平臺結合,對 API 進行全面的管理、自動化測試、監控和運維。
產品關鍵特性
具體對比:https://help.eolinker.com/#/tutorial/?groupID=c-269&productID=19
從對比可以看到,開源版本對于關鍵的服務限流熔斷,服務降級,數據緩存,格式轉換,請求大小校驗等能力是沒有的,這些能力只在企業版本中提供。
由于該網關基于Go語言編寫,因此比類似Zuul網關有更好的性能,實際性能測試結果數據來看,和Kong網關的性能比較接近,比Kong網關性能略好。
關鍵內容說明
整個部署架構圖和常見的ESB總線或API網關產品類似,數據庫可以采用Oracle或Mysql數據庫,緩存采用Redis庫進行緩存。前端通過F5或Ngnix進行負載均衡,本身網關節點是無狀態的,支持集群化架構部署。
通過定期檢查后端服務器的可用情況,智能識別可用后端、屏蔽不可用后端,減少服務器開銷。這個實際類似對后端的業務服務進行心跳監測,出現問題后進行屏蔽或預警,后端服務不可用時候實際通過API網關封裝暴露的新代理服務本身也處于不可用狀態。
對于后端的業務服務本身可以再通過類似Ngnix集群或K8s集群暴露集群IP地址接入,當然網關本身也支持直接將多個后端業務多節點接入到網關中,由網關對后端業務服務器階段進行負載均衡,在采用了類似容器化和K8s或集群架構的后端來說,該功能往往并不會用到。
API健康檢查,文檔編寫完成之后,API 定期檢查節點運行狀態,若節點出現異常則通過郵件或者API發送告警信息,并自動嘗試重啟修復節點。實際我們看到對于API的監控檢查包括了兩個方面,一個是通過網關封裝后的API節點的監控檢查,一個是后端業務API服務的監控檢查。
API斷線重連:請求轉發失敗后,網關會進行一定次數的斷線重連,防止因網絡閃斷等原因導致API訪問質量下降。這個類似我們說的服務重試機制,傳統ESB總線的標準能力。該功能還是有用,主要是為了防止網絡閃斷引起的服務訪問異常。
在網關里可以給不同的調用方或客戶端設置訪問策略,不同的訪問策略可以設置不同的 API 訪問權限、鑒權方式以及插件功能等。網關支持 開放策略 與 普通策略:
網關的插件分為 策略插件 與 API插件。
鑒權的對象為 策略 (Strategy) ,策略可表示為一個公司、一個業務部門或一個用戶。開源版網關支持以下鑒權方式:Public、Basic、Apikey。暫時沒有看到基于消費訪問IP地址的服務訪問鑒權,不清楚是否企業版由對應的IP認證鑒權支持。
日志管理能力
網關系統的日志分為兩大部分:請求日志(access.log)和系統運行時日志;運行時日志又分為:控制臺的運行日志(console.log)、各節點的運行日志(node.log)。對于請求日志可以詳細的配置日志存放路徑,記錄周期,具體記錄的內容等。
整體相對來說,當前網關提供的日志管理能夠偏弱,特別是日志信息的查看,基于服務日志運行進行的API接口服務的運行分析統計等方面的能力。
參數映射:功能具備,但是使用起來會比較麻煩,暫時沒看到圖形化或者表格方式的參數映射界面。對于參數映射不一定完全的圖形化,但是提供類似阿里云API網關的表格化映射是一種可行的方式。
小豹API網關
http://www.xbgateway.com/architecture.html
這個是最近在網上查找API網關相關資料的時候搜索到的一個商用的API網關,從產品介紹材料來看,我們前面談過的網關的核心功能基本上全部包括,而且相當來說也比較完善。同時提供了一個較方便的API網關的治理管控平臺,可以方便的對API注冊接入和運行全生命周期, 方便對安全,流控,日志各方面進行靈活管控。
下面我們看下網站對API網關架構特點的一些說明:
基于Netty NIO的響應式架構;分布式緩存基于Redis;數據庫基于Mysql,分布式配置基于ZooKeeper
API配置緩存,運行時不依賴DB,配置更新后自動通知各網關節點;
支持自定義組件,動態加載,在不中斷網關服務的情況下重新加載配置和運行組件;
API服務連續異常后自動熔斷和自我恢復,訪問異常、超時處理;
網關核心運行過程不寫磁盤IO,避免磁盤IO性能影響網關吞吐量;
Docker容器化支持,拆分網關、管理服務、第三方中間件依賴等鏡像,便于靈活擴容。
RestCloud API企業微服務API開發
http://www.restcloud.cn/restcloud/mycms/apigateway.html
RestCloud API網關是完全自主研發的面向企業級的API網關,一且以簡單、易用、輕量級為目標進行研發,同時兼顧作為企業級的服務總線可以替換企業原有的ESB產品,RestCloud是集ESB和API網關于一體的企業級網關產品。這個不僅僅提供了API網關, 也提供了微服務快速開發平臺,API服務治理平臺,DaaS等相關組件。
另外RestCloud本身還提供了Http Rest API接口的快速開發平臺,可以將數據庫表,表對象,1多多對象關系的快速的發布為Http Rest API接口服務,同時支持多數據庫接口適配。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。