本文由喜馬拉雅技術(shù)團(tuán)隊(duì)原創(chuàng)分享,原題《喜馬拉雅自研網(wǎng)關(guān)架構(gòu)實(shí)踐》,有改動(dòng)。
1、引言
網(wǎng)關(guān)是一個(gè)比較成熟的產(chǎn)品,基本上各大互聯(lián)網(wǎng)公司都會(huì)有網(wǎng)關(guān)這個(gè)中間件,來解決一些公有業(yè)務(wù)的上浮,而且能快速的更新迭代。如果沒有網(wǎng)關(guān),要更新一個(gè)公有特性,就要推動(dòng)所有業(yè)務(wù)方都更新和發(fā)布,那是效率極低的事,有網(wǎng)關(guān)后,這一切都變得不是問題。
喜馬拉雅也是一樣,用戶數(shù)增長(zhǎng)達(dá)到 6 億多的級(jí)別,Web 服務(wù)個(gè)數(shù)達(dá)到500+,目前我們網(wǎng)關(guān)日處理 200 億+次調(diào)用,單機(jī) QPS 高峰達(dá)到 4w+。
網(wǎng)關(guān)除了要實(shí)現(xiàn)最基本的功能反向代理外,還有公有特性,比如黑白名單,流控,鑒權(quán),熔斷,API 發(fā)布,監(jiān)控和報(bào)警等。我們還根據(jù)業(yè)務(wù)方的需求實(shí)現(xiàn)了流量調(diào)度,流量 Copy,預(yù)發(fā)布,智能化升降級(jí),流量預(yù)熱等相關(guān)功能。
從技術(shù)上來說,喜馬拉雅API網(wǎng)關(guān)的技術(shù)演進(jìn)路線圖大致如下:
本文將分享在喜馬拉雅API網(wǎng)關(guān)在億級(jí)流量前提下,進(jìn)行的技術(shù)演進(jìn)發(fā)展歷程和實(shí)踐經(jīng)驗(yàn)總結(jié)。
(本文同步發(fā)布于:http://www.52im.net/thread-3564-1-1.html)
2、專題目錄
本文是系列文章的第5篇,總目錄如下:
《長(zhǎng)連接網(wǎng)關(guān)技術(shù)專題(一):京東京麥的生產(chǎn)級(jí)TCP網(wǎng)關(guān)技術(shù)實(shí)踐總結(jié)》
《長(zhǎng)連接網(wǎng)關(guān)技術(shù)專題(二):知乎千萬級(jí)并發(fā)的高性能長(zhǎng)連接網(wǎng)關(guān)技術(shù)實(shí)踐》
《長(zhǎng)連接網(wǎng)關(guān)技術(shù)專題(三):手淘億級(jí)移動(dòng)端接入層網(wǎng)關(guān)的技術(shù)演進(jìn)之路》
《長(zhǎng)連接網(wǎng)關(guān)技術(shù)專題(四):愛奇藝WebSocket實(shí)時(shí)推送網(wǎng)關(guān)技術(shù)實(shí)踐》
《長(zhǎng)連接網(wǎng)關(guān)技術(shù)專題(五):喜馬拉雅自研億級(jí)API網(wǎng)關(guān)技術(shù)實(shí)踐》(* 本文)
3、第1版:Tomcat NIO+Async Servlet
網(wǎng)關(guān)在架構(gòu)設(shè)計(jì)時(shí)最為關(guān)鍵點(diǎn),就是網(wǎng)關(guān)在接收到請(qǐng)求,調(diào)用后端服務(wù)時(shí)不能阻塞 Block,否則網(wǎng)關(guān)的吞吐量很難上去,因?yàn)樽詈臅r(shí)的就是調(diào)用后端服務(wù)這個(gè)遠(yuǎn)程調(diào)用過程。
如果這里是阻塞的,Tomcat 的工作線程都 block 住了,在等待后端服務(wù)響應(yīng)的過程中,不能去處理其他的請(qǐng)求,這個(gè)地方一定要異步。
架構(gòu)圖如下:
這版我們實(shí)現(xiàn)單獨(dú)的 Push 層,作為網(wǎng)關(guān)收到響應(yīng)后,響應(yīng)客戶端時(shí),通過這層實(shí)現(xiàn),和后端服務(wù)的通信是 HttpNioClient,對(duì)業(yè)務(wù)的支持黑白名單,流控,鑒權(quán),API 發(fā)布等功能。
但是這版只是功能上達(dá)到網(wǎng)關(guān)的要求,處理能力很快就成了瓶頸,單機(jī) QPS 到 5K 的時(shí)候,就會(huì)不停的 Full GC。
后面通過 Dump 線上的堆分析,發(fā)現(xiàn)全是 Tomcat 緩存了很多 HTTP 的請(qǐng)求,因?yàn)?Tomcat 默認(rèn)會(huì)緩存 200 個(gè) requestProcessor,每個(gè) prcessor 都關(guān)聯(lián)了一個(gè) request。
還有就是 Servlet 3.0 Tomcat 的異步實(shí)現(xiàn)會(huì)出現(xiàn)內(nèi)存泄漏,后面通過減少這個(gè)配置,效果明顯。
但性能肯定就下降了,總結(jié)了下,基于 Tomcat 做為接入端,有如下幾個(gè)問題。
Tomcat 自身的問題:
- 1)緩存太多,Tomcat 用了很多對(duì)象池技術(shù),內(nèi)存有限的情況下,流量一高很容易觸發(fā) GC;
- 2)內(nèi)存 Copy,Tomcat 的默認(rèn)是用堆內(nèi)存,所以數(shù)據(jù)需要讀到堆內(nèi),而我們后端服務(wù)是 Netty,有堆外內(nèi)存,需要通過數(shù)次 Copy;
- 3)Tomcat 還有個(gè)問題是讀 body 是阻塞的, Tomcat 的 NIO 模型和 reactor 模型不一樣,讀 body 是 block 的。
這里再分享一張 Tomcat buffer 的關(guān)系圖:
通過上面的圖,我們可以看出,Tomcat 對(duì)外封裝的很好,內(nèi)部默認(rèn)的情況下會(huì)有三次 copy。
HttpNioClient 的問題:獲取和釋放連接都需要加鎖,對(duì)應(yīng)網(wǎng)關(guān)這樣的代理服務(wù)場(chǎng)景,會(huì)頻繁的建連和關(guān)閉連接,勢(shì)必會(huì)影響性能。
基于 Tomcat 的存在的這些問題,我們后面對(duì)接入端做改造,用 Netty 做接入層和服務(wù)調(diào)用層,也就是我們的第二版,能徹底解決上面的問題,達(dá)到理想的性能。
4、第2版:Netty+全異步
基于 Netty 的優(yōu)勢(shì),我們實(shí)現(xiàn)了全異步,無鎖,分層的架構(gòu)。
先看下我們基于 Netty 做接入端的架構(gòu)圖:
PS:如果你對(duì)Netty和Java NIO了解太少,下面幾篇資料請(qǐng)務(wù)必閱讀:
《少啰嗦!一分鐘帶你讀懂Java的NIO和經(jīng)典IO的區(qū)別》
《Java的BIO和NIO很難懂?用代碼實(shí)踐給你看,再不懂我轉(zhuǎn)行!》
《史上最強(qiáng)Java NIO入門:擔(dān)心從入門到放棄的,請(qǐng)讀這篇!》
《寫給初學(xué)者:Java高性能NIO框架Netty的學(xué)習(xí)方法和進(jìn)階策略》
《新手入門:目前為止最透徹的的Netty高性能原理和框架架構(gòu)解析》
《史上最通俗Netty框架入門長(zhǎng)文:基本介紹、環(huán)境搭建、動(dòng)手實(shí)戰(zhàn)》
4.1 接入層
Netty 的 IO 線程,負(fù)責(zé) HTTP 協(xié)議的編解碼工作,同時(shí)對(duì)協(xié)議層面的異常做監(jiān)控報(bào)警。
對(duì) HTTP 協(xié)議的編解碼做了優(yōu)化,對(duì)異常,攻擊性請(qǐng)求監(jiān)控可視化。比如我們對(duì) HTTP 的請(qǐng)求行和請(qǐng)求頭大小是有限制的,Tomcat 是請(qǐng)求行和請(qǐng)求加在一起,不超過 8K,Netty 是分別有大小限制。
假如客戶端發(fā)送了超過閥值的請(qǐng)求,帶 cookie 的請(qǐng)求很容易超過,正常情況下,Netty 就直接響應(yīng) 400 給客戶端。
經(jīng)過改造后,我們只取正常大小的部分,同時(shí)標(biāo)記協(xié)議解析失敗,到業(yè)務(wù)層后,就可以判斷出是那個(gè)服務(wù)出現(xiàn)這類問題,其他的一些攻擊性的請(qǐng)求,比如只發(fā)請(qǐng)求頭,不發(fā) body 或者發(fā)部分這些都需要監(jiān)控和報(bào)警。
4.2 業(yè)務(wù)邏輯層
負(fù)責(zé)對(duì) API 路由,流量調(diào)度等一序列的支持業(yè)務(wù)的公有邏輯,都在這層實(shí)現(xiàn),采樣責(zé)任鏈模式,這層不會(huì)有 IO 操作。
在業(yè)界和一些大廠的網(wǎng)關(guān)設(shè)計(jì)中,業(yè)務(wù)邏輯層基本都是設(shè)計(jì)成責(zé)任鏈模式,公有的業(yè)務(wù)邏輯也在這層實(shí)現(xiàn)。
我們?cè)谶@層也是相同的套路,支持了:
- 1)用戶鑒權(quán)和登陸校驗(yàn),支持接口級(jí)別配置;
- 2)黑白名單:分全局和應(yīng)用,以及 IP 維度,參數(shù)級(jí)別;
- 3)流量控制:支持自動(dòng)和手動(dòng),自動(dòng)是對(duì)超大流量自動(dòng)攔截,通過令牌桶算法實(shí)現(xiàn);
- 4)智能熔斷:在 Histrix 的基礎(chǔ)上做了改進(jìn),支持自動(dòng)升降級(jí),我們是全部自動(dòng)的,也支持手動(dòng)配置立即熔斷,就是發(fā)現(xiàn)服務(wù)異常比例達(dá)到閥值,就自動(dòng)觸發(fā)熔斷;
- 5)灰度發(fā)布:我對(duì)新啟動(dòng)的機(jī)器的流量支持類似 TCP 的慢啟動(dòng)機(jī)制,給機(jī)器一個(gè)預(yù)熱的時(shí)間窗口;
- 6)統(tǒng)一降級(jí):我們對(duì)所有轉(zhuǎn)發(fā)失敗的請(qǐng)求都會(huì)找統(tǒng)一降級(jí)的邏輯,只要業(yè)務(wù)方配了降級(jí)規(guī)則,都會(huì)降級(jí),我們對(duì)降級(jí)規(guī)則是支持到參數(shù)級(jí)別的,包含請(qǐng)求頭里的值,是非常細(xì)粒度的,另外我們還會(huì)和 varnish 打通,支持 varnish 的優(yōu)雅降級(jí);
- 7)流量調(diào)度:支持業(yè)務(wù)根據(jù)篩選規(guī)則,對(duì)流量篩選到對(duì)應(yīng)的機(jī)器,也支持只讓篩選的流量訪問這臺(tái)機(jī)器,這在查問題/新功能發(fā)布驗(yàn)證時(shí)非常用,可以先通過小部分流量驗(yàn)證再大面積發(fā)布上線;
- 8)流量 copy:我們支持對(duì)線上的原始請(qǐng)求根據(jù)規(guī)則 copy 一份,寫入到 MQ 或者其他的 upstream,來做線上跨機(jī)房驗(yàn)證和壓力測(cè)試;
- 9)請(qǐng)求日志采樣:我們對(duì)所有的失敗的請(qǐng)求都會(huì)采樣落盤,提供業(yè)務(wù)方排查問題支持,也支持業(yè)務(wù)方根據(jù)規(guī)則進(jìn)行個(gè)性化采樣,我們采樣了整個(gè)生命周期的數(shù)據(jù),包含請(qǐng)求和響應(yīng)相關(guān)的所有數(shù)據(jù)。
上面提到的這么多都是對(duì)流量的治理,我們每個(gè)功能都是一個(gè) filter,處理失敗都不影響轉(zhuǎn)發(fā)流程,而且所有的這些規(guī)則的元數(shù)據(jù)在網(wǎng)關(guān)啟動(dòng)時(shí)就會(huì)全部初始化好。
在執(zhí)行的過程中,不會(huì)有 IO 操作,目前有些設(shè)計(jì)會(huì)對(duì)多個(gè) filter 做并發(fā)執(zhí)行,由于我們的都是內(nèi)存操作,開銷并不大,所以我們目前并沒有支持并發(fā)執(zhí)行。
還有個(gè)就是規(guī)則會(huì)修改,我們修改規(guī)則時(shí),會(huì)通知網(wǎng)關(guān)服務(wù),做實(shí)時(shí)刷新,我們對(duì)內(nèi)部自己的這種元數(shù)據(jù)更新的請(qǐng)求,通過獨(dú)立的線程處理,防止 IO 在操作時(shí)影響業(yè)務(wù)線程。
4.3 服務(wù)調(diào)用層
服務(wù)調(diào)用對(duì)于代理網(wǎng)關(guān)服務(wù)是關(guān)鍵的地方,一定需要異步,我們通過 Netty 實(shí)現(xiàn),同時(shí)也很好的利用了 Netty 提供的連接池,做到了獲取和釋放都是無鎖操作。
4.3.1)異步 Push:
網(wǎng)關(guān)在發(fā)起服務(wù)調(diào)用后,讓工作線程繼續(xù)處理其他的請(qǐng)求,而不需要等待服務(wù)端返回。
這里的設(shè)計(jì)是我們?yōu)槊總€(gè)請(qǐng)求都會(huì)創(chuàng)建一個(gè)上下文,我們?cè)诎l(fā)完請(qǐng)求后,把該請(qǐng)求的 context 綁定到對(duì)應(yīng)的連接上,等 Netty 收到服務(wù)端響應(yīng)時(shí),就會(huì)在給連接上執(zhí)行 read 操作。
解碼完后,再?gòu)慕o連接上獲取對(duì)應(yīng)的 context,通過 context 可以獲取到接入端的 session。
這樣 push 就通過 session 把響應(yīng)寫回客戶端了,這樣設(shè)計(jì)也是基于 HTTP 的連接是獨(dú)占的,即連接和請(qǐng)求上下文綁定。
4.3.2)連接池:
連接池的原理如下圖:
服務(wù)調(diào)用層除了異步發(fā)起遠(yuǎn)程調(diào)用外,還需要對(duì)后端服務(wù)的連接進(jìn)行管理。
HTTP 不同于 RPC,HTTP 的連接是獨(dú)占的,所以在釋放的時(shí)候要特別小心,一定要等服務(wù)端響應(yīng)完了才能釋放,還有就是連接關(guān)閉的處理也要小心。
總結(jié)如下幾點(diǎn):
- 1)Connection:close;
- 2)空閑超時(shí),關(guān)閉連接;
- 3)讀超時(shí)關(guān)閉連接;
- 4)寫超時(shí),關(guān)閉連接;
- 5)Fin、Reset。
上面幾種需要關(guān)閉連接的場(chǎng)景,下面主要說下 Connection:close 和空閑寫超時(shí)兩種,其他的應(yīng)該是比較常見的比如讀超時(shí),連接空閑超時(shí),收到 fin,reset 碼這幾個(gè)。
4.3.3)Connection:close:
后端服務(wù)是 Tomcat,Tomcat 對(duì)連接重用的次數(shù)是有限制的,默認(rèn)是 100 次。
當(dāng)達(dá)到 100 次后,Tomcat 會(huì)通過在響應(yīng)頭里添加 Connection:close,讓客戶端關(guān)閉該連接,否則如果再用該連接發(fā)送的話,會(huì)出現(xiàn) 400。
還有就是如果端上的請(qǐng)求帶了 connection:close,那 Tomcat 就不等這個(gè)連接重用到 100 次,即一次就關(guān)閉。
通過在響應(yīng)頭里添加 Connection:close,即成了短連接,這個(gè)在和 Tomcat 保持長(zhǎng)連接時(shí),需要注意的,如果要利用,就要主動(dòng) remove 掉這個(gè) close 頭。
4.3.4)寫超時(shí):
首先網(wǎng)關(guān)什么時(shí)候開始計(jì)算服務(wù)的超時(shí)時(shí)間,如果從調(diào)用 writeAndFlush 開始就計(jì)算,這其實(shí)是包含了 Netty 對(duì) HTTP 的 encode 時(shí)間和從隊(duì)列里把請(qǐng)求發(fā)出去即 flush 的時(shí)間,這樣是對(duì)后端服務(wù)不公平的。
所以需要在真正 flush 成功后開始計(jì)時(shí),這樣是和服務(wù)端最接近的,當(dāng)然還包含了網(wǎng)絡(luò)往返時(shí)間和內(nèi)核協(xié)議棧處理的時(shí)間,這個(gè)不可避免,但基本不變。
所以我們是 flush 成功回調(diào)后開始啟動(dòng)超時(shí)任務(wù)。
這里就有個(gè)注意的地方:如果 flush 不能快速回調(diào),比如來了一個(gè)大的 post 請(qǐng)求,body 部分比較大,而 Netty 發(fā)送的時(shí)候第一次默認(rèn)是發(fā) 1k 的大小。
如果還沒有發(fā)完,則增大發(fā)送的大小繼續(xù)發(fā),如果在 Netty 在 16 次后還沒有發(fā)送完成,則不會(huì)再繼續(xù)發(fā)送,而是提交一個(gè) flushTask 到任務(wù)隊(duì)列,待下次執(zhí)行到后再發(fā)送。
這時(shí) flush 回調(diào)的時(shí)間就比較大,導(dǎo)致這樣的請(qǐng)求不能及時(shí)關(guān)閉,而且后端服務(wù) Tomcat 會(huì)一直阻塞在讀 body 的地方,基于上面的分析,所以我們需要一個(gè)寫超時(shí),對(duì)大的 body 請(qǐng)求,通過寫超時(shí)來及時(shí)關(guān)閉。
5、全鏈路超時(shí)機(jī)制
上圖是我們?cè)谡麄€(gè)鏈路超時(shí)處理的機(jī)制:
- 1)協(xié)議解析超時(shí);
- 2)等待隊(duì)列超時(shí);
- 3)建連超時(shí);
- 4)等待連接超時(shí);
- 5)寫前檢查是否超時(shí);
- 6)寫超時(shí);
- 7)響應(yīng)超時(shí)。
6、監(jiān)控報(bào)警
網(wǎng)關(guān)業(yè)務(wù)方能看到的是監(jiān)控和報(bào)警,我們是實(shí)現(xiàn)秒級(jí)別報(bào)警和秒級(jí)別的監(jiān)控,監(jiān)控?cái)?shù)據(jù)定時(shí)上報(bào)給我們的管理系統(tǒng),由管理系統(tǒng)負(fù)責(zé)聚合統(tǒng)計(jì),落盤到 influxdb。
我們對(duì) HTTP 協(xié)議做了全面的監(jiān)控和報(bào)警,無論是協(xié)議層的還是服務(wù)層的。
協(xié)議層:
- 1)攻擊性請(qǐng)求,只發(fā)頭,不發(fā)/發(fā)部分 body,采樣落盤,還原現(xiàn)場(chǎng),并報(bào)警;
- 2)Line or Head or Body 過大的請(qǐng)求,采樣落盤,還原現(xiàn)場(chǎng),并報(bào)警。
應(yīng)用層:
- 1)耗時(shí)監(jiān)控:有慢請(qǐng)求,超時(shí)請(qǐng)求,以及 tp99,tp999 等;
- 2)OPS 監(jiān)控和報(bào)警;
- 3)帶寬監(jiān)控和報(bào)警:支持對(duì)請(qǐng)求和響應(yīng)的行,頭,body 單獨(dú)監(jiān)控;
- 4)響應(yīng)碼監(jiān)控:特別是 400,和 404;
- 5)連接監(jiān)控:我們對(duì)接入端的連接,以及和后端服務(wù)的連接,后端服務(wù)連接上待發(fā)送字節(jié)大小也都做了監(jiān)控;
- 6)失敗請(qǐng)求監(jiān)控;
- 7)流量抖動(dòng)報(bào)警:這是非常有必要的,流量抖動(dòng)要么是出了問題,要么就是出問題的前兆。
總體架構(gòu):
7、性能優(yōu)化實(shí)踐
7.1 對(duì)象池技術(shù)
對(duì)于高并發(fā)系統(tǒng),頻繁的創(chuàng)建對(duì)象不僅有分配內(nèi)存的開銷外,還有對(duì)gc會(huì)造成壓力,我們?cè)趯?shí)現(xiàn)時(shí)會(huì)對(duì)頻繁使用的比如線程池的任務(wù)task,StringBuffer等會(huì)做寫重用,減少頻繁的申請(qǐng)內(nèi)存的開銷。
7.2 上下文切換
高并發(fā)系統(tǒng),通常都采用異步設(shè)計(jì),異步化后,不得不考慮線程上下文切換的問題。
我們的線程模型如下:
我們整個(gè)網(wǎng)關(guān)沒有涉及到io操作,但我們?cè)跇I(yè)務(wù)邏輯這塊還是和netty的io編解碼線程異步。
是有兩個(gè)原因:
- 1)是防止開發(fā)寫的代碼有阻塞;
- 2)是業(yè)務(wù)邏輯打日志可能會(huì)比較多,在突發(fā)的情況下,但是我們?cè)趐ush線程時(shí),支持用netty的io線程替代,這里做的工作比較少,這里有異步修改為同步后(通過修改配置調(diào)整),cpu的上下文切換減少20%,進(jìn)而提高了整體的吞吐量,就是不能為了異步而異步,zull2的設(shè)計(jì)和我們的類似。
7.3 GC優(yōu)化
在高并發(fā)系統(tǒng),gc的優(yōu)化不可避免,我們?cè)谟昧藢?duì)象池技術(shù)和堆外內(nèi)存時(shí),對(duì)象很少進(jìn)入老年代,另外我們年輕代會(huì)設(shè)置的比較大,而且SurvivorRatio=2,晉升年齡設(shè)置最大15,盡量對(duì)象在年輕代就回收掉, 但監(jiān)控發(fā)現(xiàn)老年代的內(nèi)存還是會(huì)緩慢增長(zhǎng),通過dump分析,我們每個(gè)后端服務(wù)創(chuàng)建一個(gè)鏈接,都時(shí)有一個(gè)socket,socket的AbstractPlainSocketImpl,而AbstractPlainSocketImpl就重寫了Object類的finalize方法。
實(shí)現(xiàn)如下:
/**
* Cleans up if the user forgets to close it.
*/
protected void finalize() throws IOException {
close();
}
是為了我們沒有主動(dòng)關(guān)閉鏈接,做的一個(gè)兜底,在gc回收的時(shí)候,先把對(duì)應(yīng)的鏈接資源給釋放了。
由于finalize的機(jī)制是通過jvm的Finalizer線程來處理的,而且Finalizer線程的優(yōu)先級(jí)不高,默認(rèn)是8,需要等到Finalizer線程把ReferenceQueue的對(duì)象對(duì)于的finalize方法執(zhí)行完,還要等到下次gc時(shí),才能把該對(duì)象回收,導(dǎo)致創(chuàng)建鏈接的這些對(duì)象在年輕代不能立即回收,從而進(jìn)入了老年代,這也是為啥老年代會(huì)一直緩慢增長(zhǎng)的問題。
7.4 日志
高并發(fā)下,特別是 Netty 的 IO 線程除了要執(zhí)行該線程上的 IO 讀寫操作,還有執(zhí)行異步任務(wù)和定時(shí)任務(wù),如果 IO 線程處理不過來隊(duì)列里的任務(wù),很有可能導(dǎo)致新進(jìn)來異步任務(wù)出現(xiàn)被拒絕的情況。
那什么情況下可能呢?IO 是異步讀寫的問題不大,就是多耗點(diǎn) CPU,最有可能 block 住 IO 線程的是我們打的日志。
目前 Log4j 的 ConsoleAppender 日志 immediateFlush 屬性默認(rèn)為 true,即每次打 log 都是同步寫 flush 到磁盤的,這個(gè)對(duì)于內(nèi)存操作來說,慢了很多。
同時(shí) AsyncAppender 的日志隊(duì)列滿了也會(huì) block 住線程,log4j 默認(rèn)的 buffer 大小是 128,而且是 block 的。
即如果 buffer 的大小達(dá)到 128,就阻塞了寫日志的線程,在并發(fā)寫日志量大的的情況下,特別是堆棧很多時(shí),log4j 的 Dispatcher 線程會(huì)出現(xiàn)變慢要刷盤。
這樣 buffer 就不能快速消費(fèi),很容易寫滿日志事件,導(dǎo)致 Netty IO 線程 block 住,所以我們?cè)诖蛉罩緯r(shí),也要注意精簡(jiǎn)。
8、未來規(guī)劃
現(xiàn)在我們都是基于 HTTP/1,現(xiàn)在 HTTP/2 相對(duì)于 HTTP/1 關(guān)鍵實(shí)現(xiàn)了在連接層面的服務(wù),即一個(gè)連接上可以發(fā)送多個(gè) HTTP 請(qǐng)求。
即 HTTP 連接也能和 RPC 連接一樣,建幾個(gè)連接就可以了,徹底解決了 HTTP/1 連接不能復(fù)用導(dǎo)致每次都建連和慢啟動(dòng)的開銷。
我們也在基于 Netty 升級(jí)到 HTTP/2,除了技術(shù)升級(jí)外,我們對(duì)監(jiān)控報(bào)警也一直在持續(xù)優(yōu)化,怎么提供給業(yè)務(wù)方準(zhǔn)確無誤的報(bào)警,也是一直在努力。
還有一個(gè)就是降級(jí),作為統(tǒng)一接入網(wǎng)關(guān),和業(yè)務(wù)方做好全方位的降級(jí)措施,也是一直在完善的點(diǎn),保證全站任何故障都能通過網(wǎng)關(guān)第一時(shí)間降級(jí),也是我們的重點(diǎn)。
9、寫在最后
網(wǎng)關(guān)已經(jīng)是一個(gè)互聯(lián)網(wǎng)公司的標(biāo)配,這里總結(jié)實(shí)踐過程中的一些心得和體會(huì),希望給大家一些參考以及一些問題的解決思路,我們也還在不斷完善中,同時(shí)我們也在做多活的項(xiàng)目,歡迎交流。
附錄:更多相關(guān)資料
[1] NIO異步網(wǎng)絡(luò)編程資料:
《Java新一代網(wǎng)絡(luò)編程模型AIO原理及Linux系統(tǒng)AIO介紹》
《有關(guān)“為何選擇Netty”的11個(gè)疑問及解答》
《MINA、Netty的源代碼(在線閱讀版)已整理發(fā)布》
《詳解Netty的安全性:原理介紹、代碼演示(上篇)》
《詳解Netty的安全性:原理介紹、代碼演示(下篇)》
《詳解Netty的優(yōu)雅退出機(jī)制和原理》
《NIO框架詳解:Netty的高性能之道》
《Twitter:如何使用Netty 4來減少JVM的GC開銷(譯文)》
《絕對(duì)干貨:基于Netty實(shí)現(xiàn)海量接入的推送服務(wù)技術(shù)要點(diǎn)》
《新手入門:目前為止最透徹的的Netty高性能原理和框架架構(gòu)解析》
《寫給初學(xué)者:Java高性能NIO框架Netty的學(xué)習(xí)方法和進(jìn)階策略》
《少啰嗦!一分鐘帶你讀懂Java的NIO和經(jīng)典IO的區(qū)別》
《史上最強(qiáng)Java NIO入門:擔(dān)心從入門到放棄的,請(qǐng)讀這篇!》
《手把手教你用Netty實(shí)現(xiàn)網(wǎng)絡(luò)通信程序的心跳機(jī)制、斷線重連機(jī)制》
《Java的BIO和NIO很難懂?用代碼實(shí)踐給你看,再不懂我轉(zhuǎn)行!》
《史上最通俗Netty框架入門長(zhǎng)文:基本介紹、環(huán)境搭建、動(dòng)手實(shí)戰(zhàn)》
《長(zhǎng)連接網(wǎng)關(guān)技術(shù)專題(一):京東京麥的生產(chǎn)級(jí)TCP網(wǎng)關(guān)技術(shù)實(shí)踐總結(jié)》
《長(zhǎng)連接網(wǎng)關(guān)技術(shù)專題(五):喜馬拉雅自研億級(jí)API網(wǎng)關(guān)技術(shù)實(shí)踐》
>> 更多同類文章 ……
[2] 有關(guān)IM架構(gòu)設(shè)計(jì)的文章:
《淺談IM系統(tǒng)的架構(gòu)設(shè)計(jì)》
《簡(jiǎn)述移動(dòng)端IM開發(fā)的那些坑:架構(gòu)設(shè)計(jì)、通信協(xié)議和客戶端》
《一套海量在線用戶的移動(dòng)端IM架構(gòu)設(shè)計(jì)實(shí)踐分享(含詳細(xì)圖文)》
《一套原創(chuàng)分布式即時(shí)通訊(IM)系統(tǒng)理論架構(gòu)方案》
《從零到卓越:京東客服即時(shí)通訊系統(tǒng)的技術(shù)架構(gòu)演進(jìn)歷程》
《蘑菇街即時(shí)通訊/IM服務(wù)器開發(fā)之架構(gòu)選擇》
《騰訊QQ1.4億在線用戶的技術(shù)挑戰(zhàn)和架構(gòu)演進(jìn)之路PPT》
《如何解讀《微信技術(shù)總監(jiān)談架構(gòu):微信之道——大道至簡(jiǎn)》》
《快速裂變:見證微信強(qiáng)大后臺(tái)架構(gòu)從0到1的演進(jìn)歷程(一)》
《移動(dòng)端IM中大規(guī)模群消息的推送如何保證效率、實(shí)時(shí)性?》
《現(xiàn)代IM系統(tǒng)中聊天消息的同步和存儲(chǔ)方案探討》
《微信朋友圈千億訪問量背后的技術(shù)挑戰(zhàn)和實(shí)踐總結(jié)》
《騰訊資深架構(gòu)師干貨總結(jié):一文讀懂大型分布式系統(tǒng)設(shè)計(jì)的方方面面》
《以微博類應(yīng)用場(chǎng)景為例,總結(jié)海量社交系統(tǒng)的架構(gòu)設(shè)計(jì)步驟》
《子彈短信光鮮的背后:網(wǎng)易云信首席架構(gòu)師分享億級(jí)IM平臺(tái)的技術(shù)實(shí)踐》
《一套高可用、易伸縮、高并發(fā)的IM群聊、單聊架構(gòu)方案設(shè)計(jì)實(shí)踐》
《社交軟件紅包技術(shù)解密(一):全面解密QQ紅包技術(shù)方案——架構(gòu)、技術(shù)實(shí)現(xiàn)等》
《即時(shí)通訊新手入門:一文讀懂什么是Nginx?它能否實(shí)現(xiàn)IM的負(fù)載均衡?》
《從游擊隊(duì)到正規(guī)軍(一):馬蜂窩旅游網(wǎng)的IM系統(tǒng)架構(gòu)演進(jìn)之路》
《從游擊隊(duì)到正規(guī)軍(二):馬蜂窩旅游網(wǎng)的IM客戶端架構(gòu)演進(jìn)和實(shí)踐總結(jié)》
《從游擊隊(duì)到正規(guī)軍(三):基于Go的馬蜂窩旅游網(wǎng)分布式IM系統(tǒng)技術(shù)實(shí)踐》
《瓜子IM智能客服系統(tǒng)的數(shù)據(jù)架構(gòu)設(shè)計(jì)(整理自現(xiàn)場(chǎng)演講,有配套PPT)》
《阿里釘釘技術(shù)分享:企業(yè)級(jí)IM王者——釘釘在后端架構(gòu)上的過人之處》
《微信后臺(tái)基于時(shí)間序的新一代海量數(shù)據(jù)存儲(chǔ)架構(gòu)的設(shè)計(jì)實(shí)踐》
《IM開發(fā)基礎(chǔ)知識(shí)補(bǔ)課(九):想開發(fā)IM集群?先搞懂什么是RPC!》
《阿里技術(shù)分享:電商IM消息平臺(tái),在群聊、直播場(chǎng)景下的技術(shù)實(shí)踐》
《一套億級(jí)用戶的IM架構(gòu)技術(shù)干貨(上篇):整體架構(gòu)、服務(wù)拆分等》
《一套億級(jí)用戶的IM架構(gòu)技術(shù)干貨(下篇):可靠性、有序性、弱網(wǎng)優(yōu)化等》
《從新手到專家:如何設(shè)計(jì)一套億級(jí)消息量的分布式IM系統(tǒng)》
>> 更多同類文章 ……
[3] 更多其它架構(gòu)設(shè)計(jì)相關(guān)文章:
《騰訊資深架構(gòu)師干貨總結(jié):一文讀懂大型分布式系統(tǒng)設(shè)計(jì)的方方面面》
《快速理解高性能HTTP服務(wù)端的負(fù)載均衡技術(shù)原理》
《子彈短信光鮮的背后:網(wǎng)易云信首席架構(gòu)師分享億級(jí)IM平臺(tái)的技術(shù)實(shí)踐》
《知乎技術(shù)分享:從單機(jī)到2000萬QPS并發(fā)的Redis高性能緩存實(shí)踐之路》
《新手入門:零基礎(chǔ)理解大型分布式架構(gòu)的演進(jìn)歷史、技術(shù)原理、最佳實(shí)踐》
《阿里技術(shù)分享:深度揭秘阿里數(shù)據(jù)庫(kù)技術(shù)方案的10年變遷史》
《阿里技術(shù)分享:阿里自研金融級(jí)數(shù)據(jù)庫(kù)OceanBase的艱辛成長(zhǎng)之路》
《達(dá)達(dá)O2O后臺(tái)架構(gòu)演進(jìn)實(shí)踐:從0到4000高并發(fā)請(qǐng)求背后的努力》
《優(yōu)秀后端架構(gòu)師必會(huì)知識(shí):史上最全MySQL大表優(yōu)化方案總結(jié)》
《小米技術(shù)分享:解密小米搶購(gòu)系統(tǒng)千萬高并發(fā)架構(gòu)的演進(jìn)和實(shí)踐》
《一篇讀懂分布式架構(gòu)下的負(fù)載均衡技術(shù):分類、原理、算法、常見方案等》
《通俗易懂:如何設(shè)計(jì)能支撐百萬并發(fā)的數(shù)據(jù)庫(kù)架構(gòu)?》
《多維度對(duì)比5款主流分布式MQ消息隊(duì)列,媽媽再也不擔(dān)心我的技術(shù)選型了》
《從新手到架構(gòu)師,一篇就夠:從100到1000萬高并發(fā)的架構(gòu)演進(jìn)之路》
《美團(tuán)技術(shù)分享:深度解密美團(tuán)的分布式ID生成算法》
《12306搶票帶來的啟示:看我如何用Go實(shí)現(xiàn)百萬QPS的秒殺系統(tǒng)(含源碼)》
>> 更多同類文章 ……
本文已同步發(fā)布于“即時(shí)通訊技術(shù)圈”公眾號(hào)。

▲ 本文在公眾號(hào)上的鏈接是:點(diǎn)此進(jìn)入。同步發(fā)布鏈接是:http://www.52im.net/thread-3564-1-1.html