Ⅰ 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的方案,對於多語言支持也更友好。
Ⅱ nginx如何實現負載均衡、限流、緩存、黑白名單和灰度發布
1.負載均衡配置
2.失敗重試配置
在fail_timeout時間內失敗了max_fails次請求後,認為上游伺服器不可用,就會將服務地址剔除掉,fail_timeout時間後會再次將伺服器加入存活列表進行重試。
limit_req_zone指令設置參數
參數說明
limit_req_zone定義在http塊中,$binary_remote_addr表示保存客戶端IP地址的二進制形式。
Zone定義IP狀態及URL訪問頻率的共享內存區域。zone=keyword標識區域的名字,以及冒號後面跟區域大小。16000個IP地址的狀態信息約1MB,例子區域可以存儲160000個IP地址。
Rate定義最大請求速率。示例中速率不能超過每秒10個請求。
設置限流
burs排隊大小,nodelay不限制單個請求間的時間。具體使用可以查看高並發場景如何使用nginx實現限流-實戰篇
不限流白名單
該配置說明 192.168.1.0/24網段的ip訪問是不限流的,其它限流。ip後面數字的含義
24表示子網掩碼:255.255.255.0
16表示子網掩碼:255.255.0.0
8表示子網掩碼:255.0.0.0
1.瀏覽器緩存 靜態資源緩存用expire
Response Header中添加了Expires和Cache-Control
所謂的靜態資源一般包括一直不變的圖像,如網站的logo,js、css靜態文件還有可下載的內容,媒體文件
協商緩存(add_header ETag/Last-Modified value)包括html文件,經常替換的圖片,經常需要修改的js、css文件和基本不變的api介面
不需要緩存包括用戶隱私等敏感數據,用戶經常變動的api介面
2.代理層緩存
在本地磁碟創建一個文件目錄,根據我們的配置把請求資源以k(key自定義,這邊用url的hash值)->v形式緩存到目錄里,並根據需求對內容設置緩存時長,比如狀態碼為200緩存10分鍾,其餘的緩存1分鍾等待。要清理緩存可以藉助purger的功能。如果ab測試/個性化需求時應禁用瀏覽器緩存,否則會因為緩存導致誤差。
方式一
方式二 lua+redis動態黑名單(openresty)
配置(/usr/local/openresty/nginx/conf/nginx.conf)
lua腳本編寫(ip_blacklist.lua)
1.根據cookie實現灰度發布
根據cooke查詢version值,根據version跳轉到對應的host,如果沒有匹配上的就跳轉到默認配置。
2.根據來路ip實現灰度發布
Ⅲ 淘寶提示api限流什麼意思
淘寶客API限流是做淘寶客的數據介面許可權被限制了,在應用上的源碼中接入API數據口,就可以在應用上使用API數據等信息。
API 是淘寶網一個數據開放介面,主要是面向開發人員的,如果是具備開發能力可以到淘寶開放平台去看參考文檔自己開發基於API的淘寶客程序。
(3)api限流緩存擴展閱讀:
API限流最直接的原因就是伺服器爆滿,限制部分用戶登陸。
API(Application Programming Interface,應用程序編程介面)是一些預先定義的函數,目的是提供應用程序與開發人員基於某軟體或硬體的以訪問一組常式的能力,而又無需訪問源碼,或理解內部工作機制的細節。
Ⅳ win API串口 緩存問題~~~~~
COMSTAT comstat
ClearCommError(.......&comstat);
comstat.cbInQue就是接受緩沖區中位元組數量