自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

億級流量架構(gòu)演進實戰(zhàn):從零構(gòu)建億級流量 API 網(wǎng)關(guān)

開發(fā) 架構(gòu)
架構(gòu)設(shè)計是種經(jīng)驗,我有幸參與到多個億級系統(tǒng)的架構(gòu)設(shè)計中,有所收獲的同時也希望把這些收獲分享與大家。

[[428860]]

這不是一個講概念的專欄,而且我也不擅長講概念,每一篇文章都是一個故事,我希望你可以通過這些故事了解我當(dāng)時在實際工作中遇到問題和背后的思考,架構(gòu)設(shè)計是種經(jīng)驗,我有幸參與到多個億級系統(tǒng)的架構(gòu)設(shè)計中,有所收獲的同時也希望把這些收獲分享與大家。

2013年,我在做 APP 服務(wù)端的平臺化轉(zhuǎn)型,故事就從這里開始。

在最開始做網(wǎng)關(guān)時,我并沒有一開始就明確說要做個 API 網(wǎng)關(guān),而是做著做著發(fā)現(xiàn)這是個網(wǎng)關(guān)。因為當(dāng)時我是在做服務(wù)端的平臺化轉(zhuǎn)型,最開始時只是提供了客戶端登錄、獲取插件列表、插件啟動授權(quán)幾個簡單的 API,其中客戶端登錄是通過 RSA 和 AES 非對稱加密算法來實現(xiàn),登錄之后平臺頒發(fā) token 給客戶端,有了 token 之后,客戶端就通過 OAuth 2.0 協(xié)議來調(diào)用獲取插件列表、插件啟動授權(quán)等 API,不過由于最開始沒想清楚,提供出去的 API 接口定義和格式不統(tǒng)一,雖然都是 json 格式,但幾乎每個 API 都有自己的的格式定義,即每個 method 在服務(wù)端都實現(xiàn)了一個 Servlet 服務(wù),客戶端天天是要這接口要那接口,搞了上百個接口還是被客戶端碾著走,更糟糕的是代碼越來越臃腫還老出問題。

后來就想為何不把接口定義和格式統(tǒng)一了,就只提供一個 Serlvet 服務(wù),通過解析 API 接口參數(shù)在后端進行服務(wù)的分發(fā),這樣至少可以減少每個 API 都寫一遍 Servlet 的工作,當(dāng)時的這個架構(gòu)是 C/S 的架構(gòu),客戶端通過公網(wǎng)訪問彈內(nèi)的服務(wù)器,這個功能上線其實是上線了一個新的 API,之后客戶端的新功能都必須使用新的 API,老的 API 在客戶端線上的版本逐步下線后,服務(wù)端再對老的 API 進行清理,當(dāng)整個架構(gòu)逐漸形成之后,服務(wù)端的開發(fā)效率得到了顯著的提升,也是這時,我覺得這其實是個網(wǎng)關(guān)的雛形,所以整個平臺演進的過程,在這一階段我總結(jié)為:統(tǒng)一服務(wù)接口。

1. 什么是網(wǎng)關(guān)?

現(xiàn)在來談?wù)?API 網(wǎng)關(guān),關(guān)于 API 網(wǎng)關(guān)的定義,有很多的說法,其字面意思就是系統(tǒng)的統(tǒng)一 API 入口。說白了, 就是將客戶端的所有請求統(tǒng)一通過 API 網(wǎng)關(guān)接入服務(wù)端,并完成認證、授權(quán)、安全、流控、熔斷、調(diào)度、轉(zhuǎn)發(fā)、監(jiān) 控等處理過程。API 網(wǎng)關(guān)的價值,就是為實現(xiàn)更加安全、高效和穩(wěn)定的 API 調(diào)用提供服務(wù)保障。

就我當(dāng)時負責(zé)的平臺而言,統(tǒng)一了服務(wù)接口還不能說是做了一個網(wǎng)關(guān),因為這僅僅是實現(xiàn)了網(wǎng)關(guān)統(tǒng)一接入組件的一個點,那網(wǎng)關(guān)的統(tǒng)一接入組件又是什么?下面我們先聊下網(wǎng)關(guān)的每一個組件,以及每一個組件的職責(zé)。

API 網(wǎng)關(guān)的核心組件

從 API 調(diào)用的過程來看,我把 API 網(wǎng)關(guān)劃分為四個組件:

  • 統(tǒng)一接入組件,管理所有的請求接入,負責(zé)認證鑒權(quán)、安全、校驗、限流、降級和熔斷等,它就像 API 網(wǎng)關(guān)的護城河;

  • 服務(wù)調(diào)度組件,管理請求的路由和調(diào)度,負責(zé)協(xié)議解析、路由、轉(zhuǎn)換、映射和服務(wù)編排等,它是外部請求調(diào)度后端服務(wù)的中間樞紐,也是 API 網(wǎng)關(guān)的大腦(只有大腦才知道哪個 API 應(yīng)去哪里調(diào)度);

  • 服務(wù)發(fā)布組件,管理 API 的注冊和訂閱,負責(zé)服務(wù)發(fā)現(xiàn)、服務(wù)訂閱和服務(wù)更新等,它是 API 網(wǎng)關(guān)的心臟(心臟會不斷的把 API 信息同步給網(wǎng)關(guān));

  • 服務(wù)監(jiān)控組件,是對所有 API 請求的統(tǒng)一監(jiān)控,負責(zé)日志、監(jiān)控、告警和統(tǒng)計分析等,它是 API 網(wǎng)關(guān)的守衛(wèi)。

這里我畫了一張 API 網(wǎng)關(guān)的架構(gòu)示意圖。

統(tǒng)一接入組件

當(dāng)時,統(tǒng)一了服務(wù)接口的確實現(xiàn)了 API 的統(tǒng)一接入點,但很快也暴露出了新的問題 —— 這個接入點很快就過熱了,之前的登錄 API 和插件 API 都是分開的,現(xiàn)在統(tǒng)一后,有些 API 出故障后影響面很大,印象非常深刻的一次是客戶端上線了一個定時查詢待出庫訂單數(shù)的功能,結(jié)果整個服務(wù)端全面打爆,服務(wù)重啟很快又被打爆,這其實是統(tǒng)一之后服務(wù)端沒有及時跟上必要的限流、熔斷等防御手段。

所以,那次之后,服務(wù)端進行了第一次的系統(tǒng)拆分 —— 網(wǎng)關(guān)和服務(wù)中心。

2. 分層架構(gòu)

平臺提供的所有端能力進行服務(wù)下沉,搭建服務(wù)中心新系統(tǒng),原系統(tǒng)作為網(wǎng)關(guān)將重點負責(zé) API 接入、安全、流控、熔斷、路由、分發(fā)、調(diào)度、監(jiān)控等功能。除了垂直拆分,還做了水平拆分,即對平臺 API 和業(yè)務(wù) API 進行了隔離,簡單說,就是提供了兩個 Servlet。當(dāng)時,還沒有微服務(wù)化的概念,只是想著隔離平臺調(diào)用與業(yè)務(wù)調(diào)用的相互影響,能解決當(dāng)時的問題。后來,在認識了微服務(wù)之后,有一種后知后覺的感覺,這次系統(tǒng)的拆分使得平臺整體的穩(wěn)定性得到很大的提升,不過后來玩微服務(wù)有點玩壞了,而這就是后話了。

重構(gòu)之后的網(wǎng)關(guān)架構(gòu)比較整潔,在實現(xiàn)上,統(tǒng)一接入組件采用的是類似于責(zé)任鏈的方式,由于這時期的 API 調(diào)用主要是 HTTP 請求,所以網(wǎng)關(guān)是基于 Servlet 來提供 API 服務(wù)的,通過攔截器進行安全、流控、熔斷等功能的實現(xiàn)。

其中 FrequencyPipe 是負責(zé)流控和熔斷的攔截器,這里必須得說一下,畢竟是這里栽了跟頭。常見的限流算法有漏斗算法和令牌桶算法,我的理解,令牌桶常用于控制并發(fā),無論何時,令牌的總數(shù)是固定的,每次調(diào)用開始都需要申請,調(diào)用結(jié)束都需要釋放;漏桶適用于控制 QPS,漏桶可以在每秒生成 m 個令牌,每次調(diào)用開始都需要申請,但調(diào)用結(jié)束不需要釋放,不過問題就是如果上一秒的調(diào)用沒有結(jié)束,實際調(diào)用會大于當(dāng)前生成的 m 個令牌控制的調(diào)用量。

在實現(xiàn)上,當(dāng)時了解 Guava 的 RateLimiter 與 Semaphore 都可以實現(xiàn),通過對比,網(wǎng)關(guān)使用的是 Guava 的 Semaphore 令牌桶策略來控制并發(fā)數(shù),不過,遇到的問題就是每次重啟都會有瞬時的流量超過并發(fā)數(shù)。而在后來隨著微服務(wù)與網(wǎng)關(guān)越來越火,又有 Hystrix 或 Sentinel 提供了更強大的功能,比如 Hystrix 的線程熔斷和 Sentinel 的異常熔斷等等。

3. 高可用架構(gòu)

日志的作用不言而言,網(wǎng)關(guān)的調(diào)用日志是必不可少的。而且下定決心要做全鏈路的日志,是已經(jīng)被各種查問題逼的不勝其煩的情況下了,你能想象到的,尤其是莫名被拉到一個群里,被@有個問題要查網(wǎng)關(guān)一次調(diào)用的一個參數(shù)對不對或有沒有,沒有個日志服務(wù)平臺,不僅要親自操刀上陣,更悲催的是還只能去每臺服務(wù)器上去找日志。

服務(wù)端在拆分了網(wǎng)關(guān)和服務(wù)中心之后,系統(tǒng)都開始往微服務(wù)架構(gòu)的方向演進,一次 API 調(diào)用就需要有全局唯一的標識進行串聯(lián),網(wǎng)關(guān)采用的是 UUID,在 API 每次調(diào)用時都會生成一個 UUID 傳遞給上游并返回給客戶端,這樣當(dāng)有問題需要查詢時,就可以通過 UID 準確查找相關(guān)日志了。

怎么進行日志的采集、查詢、統(tǒng)計,以及如何基于日志實現(xiàn)監(jiān)控告警?

通常來講,大多數(shù)系統(tǒng)打印日志采用的是 Log4j,網(wǎng)關(guān)也是,再通過集團提供的日志服務(wù)系統(tǒng),比如 Scribe、Flume 等進行日志采集,然后就可以在日志系統(tǒng)或監(jiān)控系統(tǒng)里看到數(shù)據(jù)了。

不過,日志采集看著簡單,做起來還是個技術(shù)活,網(wǎng)關(guān)的調(diào)用量本身是很大的,先不看記錄網(wǎng)關(guān)日志會有多大的存儲量,關(guān)鍵點是看打印日志會對網(wǎng)關(guān)性能有多大的影響。

首先談一下 Log4j,我們知道 Log4j 1.x 會引發(fā)線程 BLOCKED,所以 Log4j 1.x 不適合高并發(fā)的場景,解決方法一種是升級到 log4j2 或者更換為 logback,另一種是通過設(shè)置 BufferedIO 或者使用 AsyncAppender 來緩解出現(xiàn) BLOCKED 的概率。遺憾的是,網(wǎng)關(guān)采用的是后者,這主要是依賴沖突導(dǎo)致的,不過這只是做日志采集里的一個小點。

基于 MMap、Kafka、Storm、ElasticSearch 實現(xiàn)日志服務(wù)平臺

除此之外,網(wǎng)關(guān)自己還實現(xiàn)了一套日志服務(wù)系統(tǒng),這主要是開放給平臺用戶的,當(dāng)時集團的日志系統(tǒng)還不對外開發(fā),所以自己就又搞了一套。

當(dāng)時技術(shù)選型沒有選擇 Scribe、Flume,而是自己基于 MMap 技術(shù)來實現(xiàn),這也受限于服務(wù)器 agent 權(quán)限,所以,基本思路是通過 Kafka 進行日志收集,然后 Storm 接收后寫到 ElasticSearch 提供服務(wù)查詢,這里有個技術(shù)點,最開始寫日志是直接發(fā) Kafka,不過線上發(fā)現(xiàn)網(wǎng)絡(luò)的抖動會影響寫 Kafka 的 RT,后來,我們嘗試了2種方案,第一種是采用線程池異步寫,另一種是基于 MMap 技術(shù)將日志先落盤,然后再異步的讀文件發(fā) Kafka,相比之下,第二種方案更不會丟數(shù)據(jù)。

日志打不好,找問題不僅抓瞎,弄不好系統(tǒng)還要撲街?

說到最后,也談?wù)劥蛉罩境龅膯栴}。

第一,throw Exception,這點尤其注意,微服務(wù)架構(gòu)里,如果服務(wù)提供方服務(wù)異常,一定不要將異常堆棧也傳給服務(wù)調(diào)用方,雖然通過異常信息可以快速定位問題,但異常信息會占用大量的網(wǎng)絡(luò)資源,嚴重的就變成服務(wù)不可用了,這里,我是有血的教訓(xùn)的,所以,我推薦的方式是定義返回結(jié)果對象里的返回值和錯誤碼。

基于多維度的限流熔斷策略,構(gòu)建實時 API 成功率監(jiān)控能力

上文說了全鏈路日志和實時監(jiān)控,本文就說下限流降級,這里都是故事。網(wǎng)關(guān)系統(tǒng),需要對調(diào)用 API 進行實時的性能監(jiān)控和錯誤碼監(jiān)控,由于是實時計算,所以采用了 NoSQL 來緩存數(shù)據(jù),因為是對 API 進行監(jiān)控,所以將 API 接口名作為緩存 Key,可當(dāng) API 調(diào)用異常猛增時,緩存熱定問題就出現(xiàn)了,很快就出現(xiàn)了 failover,然后服務(wù)不可用。所以,在處理數(shù)據(jù)時一定要考慮好數(shù)據(jù)熱點問題,無論是 NoSQL 還是 MySQL。

4. 總結(jié)

言而總之,本篇文章重點講述了API網(wǎng)關(guān)的統(tǒng)一接入、分層架構(gòu)、高可用架構(gòu)。下篇文章,我將繼續(xù)介紹流量調(diào)度的配置中心、泛化調(diào)用。如果你覺得有收獲,歡迎你把今天的內(nèi)容分享給更多的朋友。

 

責(zé)任編輯:張燕妮 來源: 松然聊技術(shù)
相關(guān)推薦

2021-03-02 07:54:18

流量網(wǎng)關(guān)設(shè)計

2021-12-03 10:47:28

WOT技術(shù)峰會技術(shù)

2021-06-28 10:09:59

架構(gòu)網(wǎng)關(guān)技術(shù)

2020-09-01 07:49:14

JVM流量系統(tǒng)

2021-10-12 10:00:25

架構(gòu)運維技術(shù)

2020-01-17 11:00:23

流量系統(tǒng)架構(gòu)

2024-05-27 08:32:45

2016-11-23 12:55:09

京東活動系統(tǒng)流量

2023-12-14 08:39:52

2017-03-24 17:17:35

限流節(jié)流系統(tǒng)

2021-02-24 16:17:18

架構(gòu)運維技術(shù)

2020-10-27 07:29:43

架構(gòu)系統(tǒng)流量

2020-12-09 08:12:30

系統(tǒng)架構(gòu)

2021-11-04 14:38:05

API騰訊會議

2018-10-23 09:22:06

2018-11-26 08:06:24

API網(wǎng)關(guān)億級

2025-04-22 08:57:27

2021-04-09 08:13:14

API網(wǎng)關(guān)互聯(lián)網(wǎng)

2020-04-07 15:12:07

微服務(wù)架構(gòu)數(shù)據(jù)

2022-08-23 07:46:45

數(shù)據(jù)一致性數(shù)據(jù)庫
點贊
收藏

51CTO技術(shù)棧公眾號