一個(gè)請(qǐng)求過來都經(jīng)過了什么?(Thrift版)

一、背景

最初遇到這個(gè)問題是去58面試。部門領(lǐng)導(dǎo)是原同事,所以面試比較水。水到什么程度呢?

面試就是走個(gè)形式而已,不會(huì)不過的。

一面面試官就問了一個(gè)問題:“一個(gè)請(qǐng)求過來都經(jīng)過了什么?”? 剩下的全是閑聊。順便展示一下公司和部門的優(yōu)勢(shì)。期待加入的意思。

聲明

面試如此之松是基于兩點(diǎn):

第一點(diǎn),與原同事多年的共事已經(jīng)展示了能力和綜合素質(zhì),比幾個(gè)小時(shí)的面試得到的結(jié)論靠譜的多。

第二點(diǎn),原同事本身認(rèn)人識(shí)人的能力得到了其他人的認(rèn)可,所以大家放心他推薦的人。

畢竟沒人愿意讓一個(gè)不合適的人加入自己團(tuán)隊(duì)拉低整體水準(zhǔn)。

二、問題考察點(diǎn)

深度和廣度的綜合考察

三、靜兒的答案

建立虛擬場(chǎng)景

☆ 項(xiàng)目

容器調(diào)度服務(wù)(根據(jù)用戶傳入的機(jī)房、CPU、內(nèi)存等信息給用戶創(chuàng)建所需要的機(jī)器)。

項(xiàng)目所用技術(shù)棧:SpringBoot、Thrift、緩存、mysql、k8s

☆ 需求

程序中需要用thrift(RPC調(diào)用)請(qǐng)求基礎(chǔ)服務(wù)取所有的機(jī)房信息。

☆ 設(shè)計(jì)

基礎(chǔ)服務(wù)提供了「傻瓜式」客戶端給調(diào)用方。客戶端只需要引入jar包,就可以像調(diào)用本地接口一樣進(jìn)行訪問。

客戶端實(shí)現(xiàn)方法

因?yàn)闄C(jī)房信息是低頻的、對(duì)變更一定時(shí)延不敏感的資源信息。所以客戶端首先RPC去遠(yuǎn)程取結(jié)果放到本地JVM緩存中。每次調(diào)用直接返回JVM緩存信息。客戶端有定時(shí)任務(wù)定時(shí)將最新結(jié)果刷新到JVM緩存。

設(shè)計(jì)特點(diǎn):

1、對(duì)thrift接口做封裝,封裝包括設(shè)定了遠(yuǎn)程獲取異常的重試次數(shù)、重試間隔、遠(yuǎn)程服務(wù)信息等。原因:基礎(chǔ)服務(wù)提供方自己最清楚自己服務(wù)的響應(yīng)時(shí)間、服務(wù)可用性等信息,自己設(shè)置更為精確,避免對(duì)使用方造成困擾。

2、每次返回本地JVM存的機(jī)房信息。信息更新通過自帶定時(shí)任務(wù)。原因:基礎(chǔ)服務(wù)提供方自己最清楚自己的資源被更新頻率如何,提供數(shù)據(jù)的實(shí)時(shí)性重要性如何。怎么保持?jǐn)?shù)據(jù)一致性。怎樣更高效。這些難題不應(yīng)該拋給調(diào)用方。

3、懶加載處理。原因:不能因?yàn)閖ar包被引用就直接占用內(nèi)存、CPU等資源。要按需提供。

服務(wù)端實(shí)現(xiàn)方法

服務(wù)端收到請(qǐng)求,考慮到這個(gè)是基礎(chǔ)服務(wù),使用方多。為了防止壓力直接作用于數(shù)據(jù)庫(kù),上面加了一層集中式緩存。不穿透的情況下,直接返回緩存信息。

數(shù)據(jù)庫(kù)中的所有機(jī)房信息是從k8s標(biāo)簽中獲取過濾的。有變化直接刷緩存。即數(shù)據(jù)庫(kù)中存的是所有的標(biāo)簽信息,其中一個(gè)小功能是從所有標(biāo)簽中過濾機(jī)房標(biāo)簽。這種設(shè)計(jì)是區(qū)別于有個(gè)機(jī)房管理系統(tǒng)錄入這種管理,機(jī)房信息永遠(yuǎn)是實(shí)時(shí)準(zhǔn)確的。(這塊涉及到內(nèi)部系統(tǒng)的設(shè)計(jì)問題,如果看不懂直接忽略即可。)

☆ 請(qǐng)求過來經(jīng)過了什么

從程序設(shè)計(jì)上,大體經(jīng)過的如上圖。限于篇幅(如果你想了解不限于篇幅是個(gè)什么狀態(tài),可以閱讀下面一篇《一個(gè)請(qǐng)求過來都經(jīng)過了什么?(2017年http版)》),本篇不講JVM經(jīng)過了怎樣的過程,主內(nèi)存和工作內(nèi)存交互,內(nèi)存可能的分頁(yè),numa綁核、定頻非定頻等等。深度上只介紹thrift調(diào)用這一層。

籠統(tǒng)的過程如上圖。大體分為三個(gè)部分:

1、有IP直接訪問IP,沒有IP通過其他信息獲取到IP。

在此部分中,第一次連接需要根據(jù)環(huán)境和服務(wù)標(biāo)識(shí)獲取機(jī)器列表??蛻舳艘话銜?huì)有本地進(jìn)程代理。對(duì)于美團(tuán)OCTO來說,就是Sg_Agent(服務(wù)治理代理)。代理會(huì)和OCTO服務(wù)器進(jìn)行通信,及時(shí)獲取最新信息。連接建立后,下次訪問就是直接IP訪問了。

2、通過IP訪問服務(wù)端,根據(jù)類名+方法簽名獲取方法。

3、通過攔截器認(rèn)證的請(qǐng)求被服務(wù)端處理后返回結(jié)果。

Thrift內(nèi)部的架構(gòu)是分層次的??蛻舳撕头?wù)端都可大體分為代碼層、協(xié)議層、傳輸層、IO處理層四部分??蛻舳撕头?wù)端的IO處理層直接交互。

代碼層:

代碼在美團(tuán)OCTO體系中MtThrift中會(huì)直接由框架自動(dòng)從java代碼轉(zhuǎn)成IDL文件,框架再根據(jù)IDL文件生成代碼實(shí)現(xiàn)數(shù)據(jù)的讀寫。

協(xié)議層(實(shí)現(xiàn)Tprotocol接口):

將數(shù)據(jù)編碼、解碼。最三種的三種傳輸格式支持是:二進(jìn)制格式、壓縮格式、Json格式。

傳輸層(實(shí)現(xiàn)Ttransport接口):

提供從網(wǎng)絡(luò)等媒介讀取和寫入數(shù)據(jù)的方式。常用的有:向文件進(jìn)行讀寫、從內(nèi)存上讀寫、壓縮讀寫。

IO處理層:

這層所做的就是阻塞、非阻塞,單線程、多線程這些。一般像獲取所有機(jī)房信息這樣的讀操作用的是多線程阻塞方式。寫操作一般用多線程非阻塞方式。

再往下linux系統(tǒng)層的東西也是可以講講的,內(nèi)容有點(diǎn)多,大家自己做思考題吧。還有涉及網(wǎng)絡(luò)傳輸?shù)男诺?、全雙工傳輸模式這些,大家可以自己想一想,查一查。

四、總結(jié)

本次公眾號(hào)文章共三篇《一個(gè)請(qǐng)求過來都經(jīng)過了什么?(Thrift版)》、《一個(gè)請(qǐng)求過來都經(jīng)過了什么?(2017年http版)》、《思維發(fā)散的雙刃劍》。首篇是剛寫的,第二篇是17年寫的。最后一篇是一些總結(jié)思考。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容