一個請求過來都經過了什麼?(Thrift版)
一、背景
最初遇到這個問題是去58面試。部門領導是原同事,所以面試比較水。水到什麼程度呢?
面試就是走個形式而已,不會不過的。
一面面試官就問了一個問題:“一個請求過來都經過了什麼?” 剩下的全是閒聊。順便展示一下公司和部門的優勢。期待加入的意思。
宣告
面試如此之松是基於兩點:
第一點,與原同事多年的共事已經展示了能力和綜合素質,比幾個小時的面試得到的結論靠譜的多。
第二點,原同事本身認人識人的能力得到了其他人的認可,所以大家放心他推薦的人。
畢竟沒人願意讓一個不合適的人加入自己團隊拉低整體水準。
二、問題考察點
深度和廣度的綜合考察
三、靜兒的答案
建立虛擬場景
專案
容器排程服務(根據使用者傳入的機房、CPU、記憶體等資訊給使用者建立所需要的機器)。
專案所用技術棧:SpringBoot、Thrift、快取、mysql、k8s
需求
程式中需要用thrift(RPC呼叫)請求基礎服務取所有的機房資訊。
設計
基礎服務提供了「傻瓜式」客戶端給呼叫方。客戶端只需要引入jar包,就可以像呼叫本地介面一樣進行訪問。
客戶端實現方法
因為機房資訊是低頻的、對變更一定時延不敏感的資源資訊。所以客戶端首先RPC去遠端取結果放到本地JVM快取中。每次呼叫直接返回JVM快取資訊。客戶端有定時任務定時將最新結果重新整理到JVM快取。
設計特點:
1、對thrift介面做封裝,封裝包括設定了遠端獲取異常的重試次數、重試間隔、遠端服務資訊等。原因:基礎服務提供方自己最清楚自己服務的響應時間、服務可用性等資訊,自己設定更為精確,避免對使用方造成困擾。
2、每次返回本地JVM存的機房資訊。資訊更新透過自帶定時任務。原因:基礎服務提供方自己最清楚自己的資源被更新頻率如何,提供資料的實時性重要性如何。怎麼保持資料一致性。怎樣更高效。這些難題不應該拋給呼叫方。
3、懶載入處理。原因:不能因為jar包被引用就直接佔用記憶體、CPU等資源。要按需提供。
服務端實現方法
服務端收到請求,考慮到這個是基礎服務,使用方多。為了防止壓力直接作用於資料庫,上面加了一層集中式快取。不穿透的情況下,直接返回快取資訊。
資料庫中的所有機房資訊是從k8s標籤中獲取過濾的。有變化直接刷快取。即資料庫中存的是所有的標籤資訊,其中一個小功能是從所有標籤中過濾機房標籤。這種設計是區別於有個機房管理系統錄入這種管理,機房資訊永遠是實時準確的。(這塊涉及到內部系統的設計問題,如果看不懂直接忽略即可。)
請求過來經過了什麼
從程式設計上,大體經過的如上圖。限於篇幅(如果你想了解不限於篇幅是個什麼狀態,可以閱讀下面一篇《一個請求過來都經過了什麼?(2017年http版)》),本篇不講JVM經過了怎樣的過程,主記憶體和工作記憶體互動,記憶體可能的分頁,numa綁核、定頻非定頻等等。深度上只介紹thrift呼叫這一層。
籠統的過程如上圖。大體分為三個部分:
1、有IP直接訪問IP,沒有IP透過其他資訊獲取到IP。
在此部分中,第一次連線需要根據環境和服務標識獲取機器列表。客戶端一般會有本地程式代理。對於美團OCTO來說,就是Sg_Agent(服務治理代理)。代理會和OCTO伺服器進行通訊,及時獲取最新資訊。連線建立後,下次訪問就是直接IP訪問了。
2、透過IP訪問服務端,根據類名+方法簽名獲取方法。
3、透過攔截器認證的請求被服務端處理後返回結果。
Thrift內部的架構是分層次的。客戶端和服務端都可大體分為程式碼層、協議層、傳輸層、IO處理層四部分。客戶端和服務端的IO處理層直接互動。
程式碼層:
程式碼在美團OCTO體系中MtThrift中會直接由框架自動從java程式碼轉成IDL檔案,框架再根據IDL檔案生成程式碼實現資料的讀寫。
協議層(實現Tprotocol介面):
將資料編碼、解碼。最三種的三種傳輸格式支援是:二進位制格式、壓縮格式、Json格式。
傳輸層(實現Ttransport介面):
提供從網路等媒介讀取和寫入資料的方式。常用的有:向檔案進行讀寫、從記憶體上讀寫、壓縮讀寫。
IO處理層:
這層所做的就是阻塞、非阻塞,單執行緒、多執行緒這些。一般像獲取所有機房資訊這樣的讀操作用的是多執行緒阻塞方式。寫操作一般用多執行緒非阻塞方式。
再往下linux系統層的東西也是可以講講的,內容有點多,大家自己做思考題吧。還有涉及網路傳輸的通道、全雙工傳輸模式這些,大家可以自己想一想,查一查。
作者:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4729/viewspace-2821922/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 在瀏覽器輸入一個地址, 傳送請求, 經歷了哪些過程?瀏覽器
- PHPer 請下來好好過一看過去 PHP、Java、Go都發生過什麼?這對於未來的發展很重要PHPJavaGo
- 對tomcat來說,每一個進來的請求(request)都需要一個執行緒,直到該請求結束。Tomcat執行緒
- 執行一條sql語句都經歷了什麼?SQL
- Web請求過程Web
- 一個完整的 Web 請求到底發生了什麼Web
- [譯文]請求一個URL時發生了什麼
- 什麼會導致HTTP出現429請求過多錯誤?HTTP
- 為什麼15年來我工作過的地方都沒有成功實施過OKR? - RedditOKR
- HTTP的請求過程HTTP
- 你的JavaScript程式碼都經歷了什麼JavaScript
- 手機通過 fiddler 抓包,有些請求為什麼就得不到返回資料了
- 【PHP】一次請求過程的解析PHP
- 一次完整的 HTTP 請求過程HTTP
- 一次完整的HTTP請求過程HTTP
- 遊戲策劃成長的四個階段,你都經歷過了嗎?遊戲
- 首充系統都長一樣,你想過為什麼嗎?
- 開源了一個 JavaScript 版敏感詞過濾庫JavaScript
- 2018年,JavaScript都經歷了什麼?JavaScript
- 為了一個HTTP請求問題,差點和iOS幹起來HTTPiOS
- [服務端與網路]一條http請求(一次回車後)到底經歷了什麼服務端HTTP
- 月薪過萬的運維都需要什麼技能運維
- 一文讀懂一個URL請求的過程是怎樣的
- 精盡Spring MVC原始碼分析 - 一個請求的旅行過程SpringMVC原始碼
- 一個HTTP請求,把網站打裂開了HTTP網站
- 完整的一次 HTTP 請求響應過程(一)HTTP
- 從原始碼聊聊mybatis一次查詢都經歷了些什麼原始碼MyBatis
- 通過PowerShell傳送TCP請求TCP
- 你在業餘時間都開發過什麼?
- 【PHP-FPM】一次請求過程的解析PHP
- 什麼是跨域請求?跨域
- GitLab 旗艦版的整體經濟影響研究報告都說了什麼?Gitlab
- 透過簡單實現 PHP 請求模擬賺了 50 元PHP
- 老王帶你看原始碼|Laravel 的路由匹配的過程都幹了些什麼?原始碼Laravel路由
- 精通一門比什麼都來一點要重要
- 當我第一次透過Kotlin和Compose來實現一個Canvas時, 我收穫了什麼?KotlinCanvas
- 恆訊科技講解什麼是代理伺服器?它請求過程是怎麼樣呢?伺服器
- Redis資料已經過期了,為什麼還佔用記憶體?Redis記憶體