發表日期 3/25/2022, 2:41:10 PM
嘉賓 | 王建新
編輯 | 嚴強
隨著公司規模的擴大以及業務量與用戶量的激增,為瞭滿足係統高可用、高並發的要求,單體應用逐步演化為服務 / 微服務的架構模式。此時,我們急需一種高效的應用程序之間的通訊手段來滿足這種需求,因此 RPC 得以大顯身手。
RPC 即遠程過程調用協議(Remote Procedure Call Protocol),可以讓我們像調用本地對象一樣發起遠程調用。RPC 憑藉其強大的治理功能,成為解決分布式係統通信問題的一大利器。
然而,怎樣選擇一個閤適的 RPC 框架依然是個令人睏擾的問題。雖然社區裏已經有很多開源的 RPC 項目,它們簡單易用,但從框架特性、性能、成熟度、技術支持、社區活躍度等等方麵綜閤考慮,適閤自己的卻很少。而開發一個完整的 RPC 框架,對於大部分中小團隊來說,人力成本和時間成本都是無法接受的。
到底該如何選擇一套適閤自己的 RPC 框架?自研 RPC 框架的過程中遇到睏難該如何破解?從事 RPC 框架的開發怎樣纔能少走彎路?針對以上問題,我們邀請瞭轉轉架構部服務治理負責人王建新老師,來和大傢一起談談轉轉 RPC 框架的進化史,以及 RPC 開發和個人成長的經驗,希望能給大傢在工作和個人成長上帶來幫助。
同時王建新老師還在 QCon+ 案例研習社【分布式鎖業務實踐】 專題中為大傢帶來瞭 [轉轉分布式鎖原理及最佳實踐] 的分享,歡迎收看!
以下是對王建新老師的專訪:
InfoQ:先和大傢聊聊你在轉轉目前負責什麼工作吧。
王建新: 我目前在轉轉主要負責服務治理相關的工作,主要以 RPC 框架為核心,還有其周邊的一些配套係統,包括注冊中心、配置中心、分布式調用跟蹤係統等。同時我也負責其他一些中間件的開發工作,例如 Codis 分布式鎖、綫程池監控、數據庫連接池監控等。
InfoQ:既然有瞭 HTTP,為什麼還需要 RPC 框架呢?
王建新: 僅從通信的角度來講,直接使用 HttpClient 和 RPC 框架是沒有什麼區彆的,而且有的 RPC 框架底層還支持使用 HTTP 協議進行通信,比如 Spring Cloud Feign 和 Dubbo。RPC 框架的側重點在於,它不僅僅是為瞭通信,還是為瞭更簡單、更易用地通信。RPC 框架通過動態代理技術,實現瞭調用遠程方法和調用本地方法同樣的體驗,不需要手動構造請求體,也不需要考慮參數和返迴值的序列化,這一切都被 RPC 框架進行瞭很好地封裝。
許多 RPC 框架都設計瞭私有的通信協議,和 HTTP 協議相比更加緊湊,傳輸數據量更小,請求耗時更短。在某些復雜鏈路中可能會有幾韆次的 RPC 請求,高性能的 RPC 框架對效率的提升是很可觀的。而且私有的 RPC 協議往往支持連接的多路復用,減少連接數量,節省係統資源。
RPC 框架內部往往也集成瞭更多的高級功能,比如 Router、Filter、LoadBalance 等,並且允許用戶自由擴展,以實現更加高級的功能。更完善一些的係統還包括監控、分布式調用跟蹤、統一服務治理平台等。可以說 RPC 框架並不是僅僅為瞭滿足通信的需求,更是可以提供一個體係支撐。
InfoQ:開發一個完整的 RPC 框架人力成本和時間成本都是很高的,轉轉是基於什麼樣的考慮選擇自研 RPC 框架而不是采用開源框架呢?
王建新: 我認為 中間件的選型是開發還是自研,其實並沒有什麼銀彈,一切都要從公司的實際情況齣發。 轉轉的 RPC 框架繼承自 58 的 RPC 框架,轉轉是從 58 獨立齣來的,雖然在業務上已經沒有太多交集,但是在技術上仍然藕斷絲連。許多轉轉的服務仍然依賴 58 的服務,這就要求轉轉的 RPC 框架必須保持和 58 的 RPC 框架在協議上的一緻性。而 RPC 框架的 API 更是和業務代碼高度融閤,因此我們無法拋棄現有的 RPC 框架而選擇開源實現。
另外從技術角度來看,轉轉架構部也有實力進行 RPC 框架的自研。團隊自研中間件不僅更能貼閤自身的實際應用場景進行高度定製化的開發,在進行問題排查時也更能得心應手,畢竟每一行代碼都很熟悉。而開源 RPC 框架為瞭滿足各種各樣不同的需求,就會産生一定的弊端,比如在功能上有些過於豐富,代碼量巨大,引入公司內部使用時遇到問題更不容易排查等等。
InfoQ:在 RPC 框架重構過程中你麵臨的最大睏難是什麼?是通過怎樣的努力解決的?有哪些沉澱和啓發?
王建新: RPC 框架重構麵臨的最大睏難就是兼容問題。我們要保證 RPC 框架的新增功能盡量不破壞現有的 API,如果確實無法避免不兼容的情況齣現,也要盡量減少對業務的影響,減少 RD 的修改成本。
對於已知的不兼容情況,在發版之前,我們會對全公司的代碼倉庫進行掃描,提前通知服務負責人,並給齣解決方案。對於無法提前預料的不兼容情況,我們先對服務進行等級劃分,從重要到不重要分為 A、B、C、D、E、F 六個等級。每個等級的 POM 文件使用不同版本的 parent,在 parent 中規定瞭 RPC 框架的版本號。工程效率部門在進行項目編譯時,禁止直接在項目中指定 RPC 框架的版本號。
這種技術方案可以實現 RPC 框架的無感知升級,每次進行 RPC 框架發版都從不重要的服務開始進行灰度發布,逐漸過渡到重要的服務。如果有不兼容的情況或者齣現 bug,也能在低等級的服務上提前發現,減少損失。
RPC 框架作為公司的基礎設施,可謂牽一發而動全身。在轉轉 RPC 框架升級過程中,我們也曾遇到過綫上事故。事後我們進行瞭深入思考、復盤,製定瞭一係列的流程規範(包括上述的服務等級劃分)以及齣現事故後的快速響應機製,來避免下一次事故的發生,並能夠做到及時止損。
我認為技術手段能解決的問題,往往不是問題,比技術更難的是人的問題。RPC 框架齣現不兼容,對 RD 的工作或多或少都會造成影響。如何照顧到 RD 的情緒、如何說服 RD 從過期的 API 遷移到新版 API,這些問題更加考驗個人的智慧和能力。 溝通的方式和方法往往比技術問題更重要。
InfoQ:目前在工作中取得瞭怎樣的成果呢?和大傢分享一下成功經驗吧。
王建新: 通過個人和團隊的努力,我們主要取得以下幾個方麵的成果:
首先是轉轉 RPC 框架的穩定性獲得瞭不小的提升。這體現在底層通信 Netty 化、服務端優雅關閉、連接數量優化和服務端綫程模型優化、日誌規範化,以及心跳保活、權重、預熱與動態權重這些方麵。同時在過程中也修復瞭一些隱藏的多綫程安全問題。
其次,轉轉 RPC 框架的易用性和擴展性的提升。我們在協議兼容的基礎上,對 RPC 框架的整體架構和 API 進行瞭重構。整體架構上,我們抽象齣核心邏輯,開放擴展接口,增強瞭健壯性、擴展性,使架構層次更加分明;API 上,從麵嚮過程重構到麵嚮對象,增強瞭 RPC 框架的易用性。
再就是實現瞭轉轉全鏈路標簽路由功能。標簽路由功能的推齣需要架構部、工程效率和運維三部門聯閤纔能完成,開發完成後的推廣還需要業務部門的配閤,可以說是多部門協作項目的成功典範。轉轉的全鏈路標簽路由不僅可以在 RPC 調用之間進行路由,同樣可以在 MQ 的生産和消費時進行路由。在標簽路由項目完成後,轉轉測試環境的搭建耗時從 1~2 天縮減至 5 分鍾。
同樣藉助於標簽路由功能,我們完成瞭綫上壓測流量的隔離。在標簽路由功能上綫之後,鏈路變得更加復雜瞭,排查問題的難度也提高瞭。基於這個問題,我們又開發瞭分布式全鏈路跟蹤係統,實現瞭調用鏈路的可視化,大大降低瞭排查問題的難度。
最後,我們對轉轉注冊中心也進行瞭重構。重構後的轉轉注冊中心邏輯更簡單,鏈路更短,健壯性更強,能滿足轉轉在未來相當長一段時間內的業務需求。
這裏為大傢簡單介紹一下轉轉的標簽路由功能:
在沒有標簽路由功能之前,搭建一個測試環境,我們需要部署從第一個被測的服務到最後一個被測服務鏈路中的所有服務,哪怕中間所經過的服務並未修改。服務之間的 RPC 調用並沒有通過注冊中心進行注冊與發現,而是通過修改 Host 文件的方式將服務域名指嚮 127.0.0.1。MQ 則通過添加 topic 前綴的方式與穩定環境的 topic 進行區分。
如下圖所示的動態環境,需要修改 Host 文件,將 A.zhuaninc.com,B.zhuaninc.com,C.zhuaninc.com,D.zhuaninc.com 指嚮 127.0.0.1。此種部署方式搭建一個測試環境需要 1~2 天,而且需要一個超大內存(100GB)以上的虛擬機。
第一個版本的標簽路由以 IP 為標簽,服務間的 RPC 調用使用注冊中心,而 MQ 客戶端則自動檢測環境為 group 添加前綴,MQ 的路由發生在 Broker 內部,由 Broker 判斷動態環境 group 的存在決定消息的路由。這種方式隻需部署調用鏈路上的被測服務,沒有修改的服務則使用穩定環境。
優勢在於用戶無任何感知,標簽的獲取是自動化的,無需手動為流量打標。缺點在於動態環境的虛擬機無法進行內存擴容,在項目開始時無法預測要修改的服務數量,隨著被測服務的增加,需要重新申請虛擬機。此種部署方式搭建一個測試環境需要 30 分鍾~1 小時。
第二個版本的標簽路由不再使用 IP 作為標簽,而是需要在發起請求時通過 HTTP Header 手動傳入標簽,而 RPC 服務注冊時則會將環境的標簽注冊到注冊中心,MQ 客戶端則自動檢測環境標簽, 為 group 添加環境標簽作為前綴。動態環境則從虛擬機升級到 Docker,不再有內存限製,一個環境下可以部署任意數量的服務,隨時可以從環境內移除服務或者嚮環境內增加服務。
至此一個測試環境的搭建時間縮短至 5 分鍾左右。與第一個版本以 IP 為標簽的路由相比,雖然多瞭手動傳入標簽的工作量,但帶來的收益是巨大的。
標簽路由中標簽的跨綫程 / 綫程池傳遞使用瞭阿裏巴巴開源的 TransmittableThreadLocal,隻需要在 JVM 參數中添加 Java Agent 參數即可實現無感知的跨綫程 / 跨綫程池傳遞。
InfoQ:和對 RPC 框架開發感興趣的小夥伴們說些什麼吧!
王建新: 從事 RPC 框架的開發,掌握一些高級技術是必不可少的。例如動態代理、反射、多綫程、綫程安全、TCP/IP 協議等,這些都是必須要掌握的。除此之外,對設計模式掌握也十分重要。設計模式掌握程度的高低決定瞭框架架構的閤理性、可擴展性以及 API 易用性的優劣。不閤理的架構設計會嚴重影響未來的升級迭代,而不易用的 API 也會帶來糟糕的用戶體驗。
另外,閱讀開源代碼是個收益率非常高的自我提升路徑,站在巨人的肩膀上更容易取得成果。大量閱讀開源代碼,學習和吸收開源中間件的優秀設計思路,可以讓我們少走許多彎路,也更容易設計齣架構閤理的 RPC 框架。
多“造輪子”也是提升能力的重要方法。模仿成熟的開源中間件自己造個 Hello World 級彆的中間件,實現其中的核心功能。在“造輪子”的過程中,我們可以領悟到其中某些隻可意會不可言傳的“套路”。造得輪子多瞭,就可以嘗試開發生産級彆的中間件瞭。
InfoQ:當下你都在關注哪些新的技術熱點和趨勢?
王建新: 在服務治理方嚮上,當下最新的熱點就是 Service Mesh。Service Mesh 通過代理模式將服務發現、路由、負載均衡、監控等功能下沉到 Side Car 代理中。業務服務依賴的 lib 庫隻有薄薄的一層功能。Service Mesh 技術使得框架的升級在大部分情況下對服務透明,隻需要統一升級 Side Car 即可。
但是轉轉並沒有緊跟潮流引入 Service Mesh,因為 Servie Mesh 有它的缺點。通過 Side Car 代理之後,調用鏈路更長瞭,會造成性能的損失。相對於應用來說,Side Car 是個黑盒,係統復雜度提高瞭,齣現問題時排查變得更加睏難,這對 Service Mesh 的運維和管理是一個相當大的挑戰。
是否要緊跟潮流技術,需要從公司的實際情況齣發。就轉轉目前的情況,無論從人力資源配置上還是服務規模上來說都還不適閤引入 Service Mesh。
InfoQ:最後,瞭解到你是轉行自學編程的,你的心路曆程是怎樣的?有什麼心得可以和有同樣經曆的小夥伴分享一下嗎?
王建新: 我的自學之路走得很麯摺。剛開始我用一周左右的時間學完瞭 C 語言,學起來感覺並不難,但接下來的路程嚴重打擊瞭我的自信。我學習瞭很多計算機的基礎課程,像數據結構、操作係統、計算機網絡、C++、匯編語言、Intel 匯編、AT&T 匯編等,但是仍然寫不齣什麼有用的程序,沮喪到瞭極點,感覺自己到瞭要放棄的邊緣。
有朋友建議我學點實用的技術,比如 Java web。我從網上下載的 Java 基礎教程開始學習,又下載瞭培訓班的免費視頻教程,終於我在瀏覽器裏看到瞭“Hello, world”,還填寫瞭錶單提交到後端應用。到這裏我終於感覺自己好像能寫點“有用的”代碼瞭。
但是找工作的曆程還是很艱難,所有的招聘都要求 2~3 年工作經驗,由於沒有相關經驗,我的簡曆初篩可能都過不瞭。聽說 Java 培訓班的老師都會教怎麼修飾簡曆,在要不要修飾簡曆這件事上,我內心十分糾結和忐忑,最終還是沒有修飾我的簡曆。簡陋到不足一頁紙的簡曆,實在沒有亮點,根本過不瞭 HR 的法眼。投遞瞭幾百份簡曆都最終石沉大海,偶爾的一兩次麵試機會也都以失敗告終。不過最後還好有貴人相助,我拿到瞭第一份寫代碼的工作。
工作之後的經曆相對要順利得多瞭。既然起點低,那我就付齣更多的時間和努力,平時比彆人早來一兩個小時,周末也經常獨自一人在公司學習。在兩段小公司工作的經曆之後,我來到瞭 58,一年之後又來到瞭轉轉做中間件,在轉轉拿瞭一次季度優秀員工和年度優秀員工。
關於工作和學習,我有幾點心得分享給大傢:
興趣是最好的老師: 自學轉行最需要的就是內驅力,我的內驅力來源於興趣,寫代碼並不僅僅是為瞭掙錢。寫瞭這麼多年代碼,我依然興趣不減,寫齣優雅的代碼是一種享受,學到新的知識令我興奮。
書讀百遍,其義自見: 有很多書,有很多源碼,我都讀過多遍。一開始讀不懂、讀不完,沒關係,放那兒,過一段時間迴頭再來一次,如此往復終有一天你會茅塞頓開。但是這並不代錶每次遇到睏難不用思考直接放棄,而是在充分思考想到腦袋都要炸瞭依然沒有理解的情況下,先放下,下次再來。大傢知道衝擊鑽和普通電鑽的區彆嗎?仔細琢磨一下。
基礎很重要: 我仍然不後悔當初沒有直接學 Java web 開發,而先去學瞭很多“無聊”的計算機基礎知識,至今我仍然會去翻那些書。
目標要明確: 我們要充分瞭解自己,知道自己喜歡什麼,知道自己擅長什麼,明確學習目標,知道該往哪裏走。跳槽目標也要明確,不要為瞭跳槽而跳槽,也不要僅僅為瞭工資而跳槽。當然如果現在就差錢瞭,那就為瞭工資而跳槽。
嘉賓簡介
王建新
轉轉 架構部 服務治理負責人
資深後端開發,主要從事服務治理、RPC 框架、網關、分布式調用跟蹤、監控、分布式鎖等係統開發。從業 6 年,從做業務成長起來,到做架構走嚮成熟,實戰經驗豐富。能很好地理解業務開發痛點,開發好用的中間件解決開發難題。
活動推薦
在 4 月 24-25 日,ArchSummit 全球架構師峰會即將落地上海,數字化轉型是大趨勢,不管是金融轉型,還是汽車産業數字化轉型,製造業數字化轉型,一定會涉及到企業的産品形態,這裏麵包括市場定位和可行性的諸多因素,還有 ROI 評估模型。
點個在看少個 bug