與入門詳解)
Dubbo RPC基礎(chǔ)與入門詳解定位Dubbo 第 01 篇入門篇講清 RPC 的本質(zhì)問題、Dubbo 的定位與角色模型并給出可運行的快速上手路徑與配置體系適用版本Dubbo 3.xJDK 8/17差異點標注 2.7.x目錄一、RPC 本質(zhì)與關(guān)鍵要素二、Dubbo 定位與版本演進三、核心角色與運行流程四、快速上手五、配置體系與優(yōu)先級六、總結(jié)七、常見高頻面試題一、RPC 本質(zhì)與關(guān)鍵要素1.1 RPC 要解決的四個核心問題RPCRemote Procedure Call遠程過程調(diào)用的目標是讓調(diào)用遠程服務(wù)像調(diào)用本地方法一樣簡單。但像本地只是表象底層必須解決四個本質(zhì)問題問題含義在 Dubbo 中的落點尋址目標服務(wù)在哪臺機器、哪個端口注冊中心 服務(wù)發(fā)現(xiàn)06 篇序列化內(nèi)存對象 → 可傳輸?shù)淖止?jié)流hessian2 / fastjson2 / protobuf05 篇傳輸字節(jié)可靠送達、結(jié)果可靠返回dubbo / triple 協(xié)議 Netty05 篇容錯網(wǎng)絡(luò)不可靠下的超時、重試、降級集群容錯 負載均衡04 篇這四件事任何 RPC 框架都逃不掉差別只在解決質(zhì)量與擴展性。1.2 本地調(diào)用與遠程調(diào)用的本質(zhì)差異這是理解一切分布式問題的起點本地調(diào)用 遠程調(diào)用 調(diào)用延遲 納秒級 毫秒級放大 ~10^5 倍 失敗模式 只有異常 異常 超時 半成功 重復執(zhí)行 參數(shù)語義 引用傳遞共享對象 值傳遞序列化 深拷貝 可用性 進程活著就能調(diào) 依賴網(wǎng)絡(luò) 對端 注冊中心三條推論貫穿整個 Dubbo 知識體系超時必須存在且必須顯式配置遠程調(diào)用可能發(fā)出去了但永遠沒響應(yīng)沒有超時 線程無限等待重試必須與冪等綁定超時不代表對端沒執(zhí)行可能執(zhí)行了但響應(yīng)丟了盲目重試會導致重復執(zhí)行出入?yún)⑹侵悼截愊M方拿到的返回對象與提供方內(nèi)存中的對象沒有任何關(guān)聯(lián)修改互不影響——也因此必須可序列化。1.3 RPC 框架的五要素一個完整的 RPC 框架由五個部件組成Dubbo 的目錄分篇正是圍繞它們展開調(diào)用方代碼 │ ① 動態(tài)代理把方法調(diào)用轉(zhuǎn)成遠程請求 ▼ 代理對象 ──⑤ 集群容錯重試/負載均衡/路由 │ ▼ ② 序列化對象 → 字節(jié) ④ 服務(wù)發(fā)現(xiàn)從注冊中心獲取地址列表 │ ▼ ③ 網(wǎng)絡(luò)傳輸長連接 多路復用Netty │ ▼ 提供方逆序還原執(zhí)行動態(tài)代理第02 篇講生成與調(diào)用鏈序列化第05 篇講格式選型與安全網(wǎng)絡(luò)傳輸?shù)?5 篇講協(xié)議幀結(jié)構(gòu)與連接模型服務(wù)發(fā)現(xiàn)第06 篇講注冊、訂閱、推送與容災集群容錯第04 篇講六大容錯策略與負載均衡算法。二、Dubbo 定位與版本演進2.1 一句話定位Dubbo 高性能 RPC 框架 面向微服務(wù)的治理體系。它不只是發(fā)請求收響應(yīng)的通信庫而是把服務(wù)發(fā)現(xiàn)、負載均衡、容錯、路由、降級、可觀測性整合在一起的一體化方案。2.2 版本演進版本關(guān)鍵變化2.6 及以前經(jīng)典形態(tài)接口級注冊發(fā)現(xiàn) dubbo 私有協(xié)議 Spring XML 配置為主2.7.x捐贈 Apache 后首個大版本異步編程模型改進CompletableFuture、元數(shù)據(jù)中心雛形、配置中心概念引入3.0兩大核心升級應(yīng)用級服務(wù)發(fā)現(xiàn)對齊云原生/Service MeshTriple 協(xié)議基于 HTTP/2兼容 gRPC3.3Triple 協(xié)議增強支持映射為標準 HTTP/JSON 接口curl、瀏覽器、網(wǎng)關(guān)可直調(diào)簡化多語言與前后端聯(lián)調(diào)兩條演進主線值得記住服務(wù)發(fā)現(xiàn)從接口級走向應(yīng)用級接口級在超大規(guī)模下注冊數(shù)據(jù)爆炸06 篇展開協(xié)議從私有二進制走向 HTTP/2 標準為了與 gRPC、Service Mesh、云原生生態(tài)互通05 篇展開。2.3 與主流方案對比維度DubboSpring CloudOpenFeigngRPC協(xié)議dubboTCP 私有/ tripleHTTP/2HTTP/1.1 JSON 為主HTTP/2 Protobuf性能高二進制 長連接多路復用中文本協(xié)議開銷大高服務(wù)治理內(nèi)置完整容錯/路由/降級/灰度組件拼裝各 starter弱需自建或配 mesh服務(wù)發(fā)現(xiàn)內(nèi)置多種注冊中心適配依賴注冊中心組件通常外接xDS 等跨語言3.x Triple 后顯著改善天然HTTP原生跨語言典型場景Java 生態(tài)內(nèi)部高頻服務(wù)調(diào)用HTTP 生態(tài)、異構(gòu)系統(tǒng)多跨語言、與 Mesh 結(jié)合選型結(jié)論Java 技術(shù)棧內(nèi)部服務(wù)間高頻調(diào)用Dubbo 的性能與治理完整度是首選對外/異構(gòu)系統(tǒng)走 HTTPtriple 也可承擔跨語言強訴求或多語言中臺選 gRPC 或 triple。三、核心角色與運行流程3.1 四大角色┌────────────┐ 注冊 ──→ │ Registry │ ←── 訂閱 └─────┬──────┘ │ 地址變更推送 ▼ ┌──────────┐ 調(diào)用 ┌──────────┐ │ Provider │ ←─────── │ Consumer │ └────┬─────┘ └────┬─────┘ └──── 調(diào)用統(tǒng)計異步 ──→ Monitor可選角色職責關(guān)鍵點Provider暴露服務(wù)啟動時向注冊中心注冊自己的地址與接口Consumer調(diào)用遠程服務(wù)啟動時訂閱運行期收推送維護本地地址列表Registry服務(wù)目錄只存誰提供了什么、在哪不經(jīng)手業(yè)務(wù)調(diào)用Monitor統(tǒng)計中心異步收集調(diào)用次數(shù)與耗時不在調(diào)用關(guān)鍵路徑3.2 運行流程四步0. 注冊Provider 啟動 → 把接口 地址 參數(shù)寫入注冊中心 1. 訂閱Consumer 啟動 → 向注冊中心訂閱所需接口 2. 推送提供方上下線 → 注冊中心把最新地址列表推給所有訂閱者 3. 調(diào)用Consumer 從【本地緩存】的地址列表中經(jīng)負載均衡選一臺直連調(diào)用兩個決定性的設(shè)計推模型 本地緩存Consumer 拿到地址后保存在內(nèi)存調(diào)用時不經(jīng)過注冊中心。好處調(diào)用延遲不受注冊中心影響注冊中心短暫抖動甚至宕機已訂閱的服務(wù)仍可繼續(xù)調(diào)用06 篇講容災細節(jié)監(jiān)控旁路化調(diào)用統(tǒng)計是異步上報Monitor 掛了不影響調(diào)用。這也回答了高頻疑問“注冊中心掛了服務(wù)還能調(diào)嗎”——能但新的注冊/地址變更會失效新上線的 Provider 不會被發(fā)現(xiàn)。3.3 與 3.x 應(yīng)用級發(fā)現(xiàn)的銜接上述流程是經(jīng)典接口級模型。Dubbo 3.x 默認演進方向是應(yīng)用級服務(wù)發(fā)現(xiàn)注冊單元從接口變?yōu)閼?yīng)用實例接口與實例的映射放元數(shù)據(jù)中心。本篇只需知道兩種模式并存細節(jié)在 06 篇展開。四、快速上手以 Spring Boot 注解方式為例3.x 標準姿勢。4.1 工程三件套demo-api ← 接口 出入?yún)?POJOProvider/Consumer 共同依賴 demo-provider ← 實現(xiàn)并暴露服務(wù) demo-consumer ← 引用并調(diào)用服務(wù)API 模塊設(shè)計紀律生產(chǎn)級要求只放接口與出入?yún)⒛P筒环湃魏螌崿F(xiàn)避免實現(xiàn)類被打進消費方出入?yún)⒈仨殞崿F(xiàn)Serializable禁止透傳 DO/內(nèi)部對象——接口是契約內(nèi)部模型是私產(chǎn)演進策略加方法、加字段可以改簽名、刪字段、改字段語義必須升 version 或新接口保證新舊提供方共存期不炸。4.2 定義接口demo-apipublicinterfaceGreetingService{StringsayHello(Stringname);}publicclassUserDTOimplementsSerializable{privatestaticfinallongserialVersionUID1L;privateLongid;privateStringname;// getter/setter ...}4.3 Provider 暴露demo-provider依賴dependencygroupIdorg.apache.dubbo/groupIdartifactIddubbo-spring-boot-starter/artifactId/dependencydependencygroupIdorg.apache.dubbo/groupIdartifactIddubbo-nacos/artifactId!-- 或 dubbo-zookeeper按注冊中心選 --/dependency實現(xiàn)并暴露DubboService// org.apache.dubbo.config.annotation.DubboServicepublicclassGreetingServiceImplimplementsGreetingService{OverridepublicStringsayHello(Stringname){returnHello, name;}}配置application.ymldubbo:application:name:demo-providerregistry:address:nacos://127.0.0.1:8848protocol:name:dubbo# 默認私有協(xié)議3.x 可換 tripleport:20880啟動類加EnableDubbo。啟動后服務(wù)即注冊到注冊中心。4.4 Consumer 引用demo-consumerRestControllerpublicclassGreetingController{DubboReference// 注入的是遠程代理不是本地 BeanprivateGreetingServicegreetingService;GetMapping(/hello)publicStringhello(RequestParamStringname){returngreetingService.sayHello(name);}}dubbo.application.name改為消費方自己的應(yīng)用名其余配置同提供方。調(diào)用sayHello時實際走了完整的代理 → 集群 → 序列化 → 網(wǎng)絡(luò)鏈路02 篇拆解。4.5 本地調(diào)試技巧直連模式繞過注冊中心本地沒有注冊中心時引用處直接指定地址DubboReference(urldubbo://127.0.0.1:20880)privateGreetingServicegreetingService;直連時注冊/訂閱環(huán)節(jié)被跳過適合聯(lián)調(diào)與單測環(huán)境。QOS 運維端口Dubbo 內(nèi)置運維通道默認 22222可查在線服務(wù)、手動上下線telnet 127.0.0.1 22222 ls # 列出已導出/引用的服務(wù)五、配置體系與優(yōu)先級5.1 配置模型分層Dubbo 配置按作用域從小到大組織小作用域覆蓋大作用域reference / service單服務(wù)級 ← 最高業(yè)務(wù)優(yōu)先級 ▲ 覆蓋 consumer / provider角色全局默認 ▲ 覆蓋 protocol / registry / application基礎(chǔ)設(shè)施常見配置項歸屬層級典型配置說明applicationname、qos 開關(guān)應(yīng)用身份注冊中心按此識別registryaddress、protocol支持多個注冊中心并存protocolname、port、threads暴露端口與協(xié)議providertimeout、retries、threads 默認值提供方全局兜底consumertimeout、retries、check消費方全局兜底check: false允許啟動時無提供方service / reference同上單服務(wù)覆蓋方法級還能再細DubboService(methods ...)超時覆蓋鏈04 篇深講方法級 接口級reference consumer 全局 provider 方法級 provider 接口級 provider 全局。消費方配置優(yōu)先于提供方——因為等多久應(yīng)由等待方?jīng)Q定。5.2 外部配置優(yōu)先級高 → 低JVM -D 參數(shù) ← 運維臨時覆蓋最高 配置中心外部化配置 ← 運行時動態(tài)下發(fā)支持不重啟變更 本地配置文件 ← application.yml / dubbo.properties API 編程 / 框架默認值 ← 最低實踐含義同一配置項出現(xiàn)在多處時高層覆蓋低層生產(chǎn)上把環(huán)境差異項放配置中心把應(yīng)急項留給 -D。5.3 服務(wù)匹配三元組Consumer 找到 Provider 的條件是三元組完全一致接口全限定名 version groupversion接口不兼容升級時新舊版本并存version 2.0.0消費方按版本路由group同一接口的不同實現(xiàn)分組如group perf性能壓測組實現(xiàn)環(huán)境/流量隔離。消費方不指定 version/group 時只能匹配同樣未指定的服務(wù)——跨版本/跨組匹配不到是常見找不到服務(wù)問題的根因。六、總結(jié)RPC 的本質(zhì)是解決尋址、序列化、傳輸、容錯四件事遠程調(diào)用與本地調(diào)用在延遲、失敗模式、參數(shù)語義上有本質(zhì)差異由此推出必須配超時、重試必須冪等、出入?yún)⒈仨毧尚蛄谢龡l紀律。Dubbo 定位是高性能 RPC 治理一體化演進主線兩條服務(wù)發(fā)現(xiàn)接口級 → 應(yīng)用級協(xié)議私有二進制 → HTTP/2Triple。四大角色中注冊中心只存目錄不經(jīng)手調(diào)用Consumer 本地緩存地址 推模型保證注冊中心抖動不影響存量調(diào)用??焖偕鲜秩譨pi契約、providerDubboService、consumerDubboReferenceAPI 模塊只放接口與可序列化模型。配置體系小作用域覆蓋大作用域方法 接口 全局外部優(yōu)先級 -D 配置中心 本地文件服務(wù)匹配靠接口 version group三元組。七、常見高頻面試題1. 什么是 RPC一個 RPC 框架要解決哪些核心問題要點RPC 讓遠程調(diào)用像本地方法調(diào)用。核心解決四件事——尋址服務(wù)發(fā)現(xiàn)定位目標、序列化對象轉(zhuǎn)字節(jié)流、傳輸可靠送達與返回、容錯超時/重試/降級。此外還需動態(tài)代理屏蔽遠程細節(jié)。關(guān)鍵認知遠程調(diào)用引入了本地調(diào)用沒有的失敗模式超時、半成功、重復執(zhí)行所以超時、冪等、可序列化是三條硬紀律。2. Dubbo 和 Spring Cloud 怎么選要點協(xié)議上 Dubbo 提供二進制私有協(xié)議/HTTP2 Triple性能高于 OpenFeign 的 HTTP/1.1JSON治理上 Dubbo 內(nèi)置完整容錯/路由/降級/灰度Spring Cloud 靠組件拼裝生態(tài)上 Spring Cloud 更貼 HTTP 生態(tài)與異構(gòu)系統(tǒng)。結(jié)論Java 內(nèi)部高頻服務(wù)調(diào)用選 Dubbo對外/異構(gòu)接口走 HTTP兩者可通過 triple 等協(xié)議互通并非互斥。3. Dubbo 的四大角色是什么描述一次完整的服務(wù)調(diào)用流程。要點Provider、Consumer、Registry、Monitor。流程① Provider 啟動向注冊中心注冊接口與地址② Consumer 啟動訂閱所需接口③ 地址變更由注冊中心推送給 Consumer 更新本地緩存④ Consumer 調(diào)用時從本地地址列表經(jīng)負載均衡選一臺直連 Provider不經(jīng)過注冊中心調(diào)用統(tǒng)計異步上報 Monitor。關(guān)鍵推模型 本地緩存注冊中心不在調(diào)用關(guān)鍵路徑。4. 注冊中心宕機了服務(wù)還能互相調(diào)用嗎要點存量調(diào)用可以——Consumer 本地緩存了地址列表調(diào)用不經(jīng)過注冊中心但新增能力失效新上線的 Provider 無法被發(fā)現(xiàn)地址變更無法推送。所以注冊中心要保證高可用集群部署同時 Dubbo 還有本地緩存文件兜底06 篇。5. Dubbo 2.7 與 3.x 的主要區(qū)別要點兩大升級——① 應(yīng)用級服務(wù)發(fā)現(xiàn)注冊單元從接口變?yōu)閼?yīng)用實例解決超大規(guī)模下接口級注冊數(shù)據(jù)爆炸并與云原生/K8s 體系對齊② Triple 協(xié)議基于 HTTP/2、兼容 gRPC改善跨語言與 Mesh 互通3.3 還支持映射為標準 HTTP/JSON。2.7 本身是 Apache 孵化版引入異步編程改進與配置中心。6. 設(shè)計 Dubbo API 接口模塊有哪些紀律要點api 模塊只放接口與出入?yún)⒛P筒环艑崿F(xiàn)出入?yún)崿F(xiàn) Serializable 且不透傳內(nèi)部 DO兼容性演進只加不改——改簽名/刪字段必須升 version 或新接口方法粒度要面向用例設(shè)計避免大而全接口同時注意默認超時與重試語義對接口契約的影響讀接口才可默認重試。7. Dubbo 配置有多個來源優(yōu)先級如何要點兩層規(guī)則。外部來源優(yōu)先級JVM -D 參數(shù) 配置中心外部化 本地配置文件application.yml/dubbo.properties API 編程與默認值。業(yè)務(wù)作用域優(yōu)先級方法級 接口級reference/service 角色全局consumer/provider。超時以消費方配置優(yōu)先因為等待方?jīng)Q定等待上限。8. Consumer 與 Provider 的 version 不一致會發(fā)生什么要點匹配不到。Dubbo 按接口 version group三元組精確匹配消費方未指定版本只能匹配未指定版本的服務(wù)跨版本不互通。這是服務(wù)已注冊但消費方報 no provider的常見根因之一多版本并存場景需消費方顯式指定目標 version或用*通配隨機選一版。9. 本地開發(fā)沒有注冊中心怎么調(diào)試要點兩種手段——① 直連模式DubboReference(url dubbo://127.0.0.1:20880)直接指定提供方地址跳過注冊訂閱② 使用內(nèi)嵌/本地注冊中心本地起 Nacos 或 Zookeeper 單機。另外 QOS 端口22222的ls命令可確認服務(wù)導出狀態(tài)。10. 為什么遠程調(diào)用必須顯式設(shè)置超時要點遠程調(diào)用存在請求發(fā)出但響應(yīng)永遠不來的可能對端卡死、網(wǎng)絡(luò)分區(qū)本地調(diào)用沒有這種狀態(tài)沒有超時調(diào)用線程會無限阻塞拖垮線程池進而雪崩。所以超時是遠程調(diào)用的必備防護且要按方法業(yè)務(wù)耗時合理設(shè)置默認 1s 不一定合適并遵循消費方優(yōu)先、層級覆蓋的配置規(guī)則。