RPC是什么?為什么要學(xué)習(xí)RPC?
隨著近幾年分布式、微服務(wù)架構(gòu)的火熱,RPC在開發(fā)工作中使用的越來越多,也變的越來越重要。
今天我們來看RPC是什么,為什么要了解RPC,通過學(xué)習(xí)RPC我們能掌握什么內(nèi)容?
什么是「RPC」
RPC 全稱 Remote Procedure Call, wikipedia的部分說明:
RPC is a request–response protocol. An RPC is initiated by the client , which sends a request message to a known remote server to execute a specified procedure with supplied parameters. The remote server sends a response to the client, and the application continues its process. |
首先這里的重點(diǎn)是「protocol」,其次是 RPC中的R -「Remote」。所以這里的RPC的意義是一個(gè)調(diào)用執(zhí)行遠(yuǎn)程方法的協(xié)議。我們對(duì)于方法的調(diào)用一般類似這樣
- Echo echo = child.say("Hello World");
這種一般是指調(diào)用自己本地的方法,比如 Java 應(yīng)用是指調(diào)用在同一個(gè) JVM 內(nèi)的方法。
如果上述的代碼要換成我們以RPC的形式去調(diào)用,寫法有什么區(qū)別呢?
其實(shí)是沒有的。
我們?cè)谡{(diào)用時(shí)仍然按這個(gè)形式,僅需要在配置中指定這個(gè)方法對(duì)應(yīng)的「遠(yuǎn)程地址」即可。
再舉個(gè)生活化的例子。
假設(shè)你是招攬游客的小販。每次集齊了游客你都在賣力的吆喝,在各種神奇的網(wǎng)站的搜索,找對(duì)應(yīng)景點(diǎn)的導(dǎo)游。后來有一天,你和街邊多個(gè)打印店談了合作。符合條件可以導(dǎo)對(duì)應(yīng)景點(diǎn)的都可以在打印店「登記」,你下次來的時(shí)候根據(jù)記錄,直接「聯(lián)系」對(duì)應(yīng)的人即可,省力不少哇。
這里我們看到兩種RPC的使用形式:
- 直接在配置中固定寫好遠(yuǎn)程方法的地址,請(qǐng)求是一步到位
- 在配置中提供的「注冊(cè)處」的地址,方法請(qǐng)求時(shí)先到注冊(cè)處查方法地址再執(zhí)行
看到這里,你不禁要說,調(diào)用個(gè)遠(yuǎn)程方法嘛,又不難,有啥看的。
那我們繼續(xù)這個(gè)生活化的例子。
在你集齊了游客聯(lián)系經(jīng)常合作的導(dǎo)游時(shí),他生病了。你要找誰? 你說我有「?jìng)浞荨孤铮怯浱幱涗浟撕枚嗄亍?/p>
那好,這好多個(gè)導(dǎo)游里,你「選哪一個(gè)」?
你說,靠,我那管那么多,隨便挑一個(gè)打電話就是了。好,這時(shí)你就已經(jīng)在用到了RPC中的「負(fù)載均衡LoadBalance」了,只不過你的策略是用的「隨機(jī)」。
如果在導(dǎo)游登記的時(shí)候每個(gè)提供了照片和歷史認(rèn)證評(píng)級(jí),那你可能不會(huì)隨便挑一個(gè)打,可能會(huì)看看照片,哪個(gè)感覺更靠譜,哪個(gè)評(píng)級(jí)更高。此時(shí)這些項(xiàng)都做為你聯(lián)系他的一個(gè)「權(quán)重」。在多個(gè)導(dǎo)游間,這個(gè)權(quán)重決定了被聯(lián)系次數(shù)的多少。此時(shí)你的LB不再是簡(jiǎn)單隨機(jī),而是根據(jù)「權(quán)重」進(jìn)行。
再比如你們合作多次,固定的幾個(gè)景點(diǎn)就是固定的幾個(gè)導(dǎo)游,老相識(shí),每次帶人來都找他。此時(shí)你的策略又變成了「一致性Hash」。
后來,有導(dǎo)游和你說,最近像他們這類自找生意的導(dǎo)游,被發(fā)現(xiàn)在主動(dòng)拉生意,可能會(huì)罰款,下次聯(lián)系他的時(shí)候別說那么多。于是你們訂了個(gè)簡(jiǎn)單「協(xié)議」:先說「0或1」,代表是否空閑,再說「1到100」代表你們所帶游客游覽的景點(diǎn)。再說「0或1」代表是否可以帶購物。
你會(huì)發(fā)現(xiàn),此時(shí)你們的協(xié)議里有「編碼」,有壓縮,每個(gè)人在聽到對(duì)方信息時(shí),需要再在你這里解碼,還原成真實(shí)的信息。在 RPC 里也一樣,在方法調(diào)用前,需要將對(duì)應(yīng)的參數(shù)序列化,以指定的「格式」傳遞,到達(dá)后再對(duì)應(yīng)的還原回去執(zhí)行方法。
過了一段時(shí)間,你的業(yè)務(wù)發(fā)展壯大,一個(gè)景區(qū)附近的導(dǎo)游們自動(dòng)組隊(duì)。在你請(qǐng)求到達(dá)時(shí),這個(gè)景區(qū)的導(dǎo)游里自動(dòng)根據(jù)上面的權(quán)重選一個(gè)人出來,這些導(dǎo)游組成的,就是一個(gè)「Cluster」
業(yè)務(wù)發(fā)展的同時(shí),你成立了一個(gè)秘書團(tuán),這些人負(fù)責(zé)過一段時(shí)間聯(lián)系一下各個(gè)導(dǎo)游組,判斷這個(gè)景區(qū)是否能提供,這個(gè)時(shí)候,秘書團(tuán)就在進(jìn)行「監(jiān)控」。
(一口老血,編不下去了……)
接下來要說的是,我們?yōu)槭裁匆獙W(xué)習(xí) RPC。
為什么要學(xué)習(xí) RPC
為什么要學(xué)習(xí) RPC呢? 我們開頭時(shí)也提到,微服務(wù)、分布式應(yīng)用的開發(fā)越來越常見, RPC 是其中相當(dāng)重要的組件。通過 RPC 的學(xué)習(xí),可以更好的理解和進(jìn)行較大型應(yīng)用的設(shè)計(jì)與開發(fā)。
同時(shí), RPC 中涉及到的各類技術(shù),也會(huì)使學(xué)習(xí)者知識(shí)面更寬廣,每個(gè)方面,都值得深入。而對(duì)于技術(shù),特別是源碼的學(xué)習(xí),又會(huì)返過來促使更好的理解 RPC,你寫出更好的代碼。
學(xué)習(xí) RPC 我們能掌握什么
我們上面的生活化例子中,提到了這些技術(shù)
- 注冊(cè)處
- 集群
- 負(fù)載均衡
- 協(xié)議
- 序列化編碼、解碼
- 一致性Hash
- 監(jiān)控
- ……
這些技術(shù),也是 RPC 中很重要的一些內(nèi)容。 我們看 Dubbo 的源碼中,從代碼的組織上,也能一窺究竟。
這張圖里,比我們?cè)谏厦胬永锾岬降募夹g(shù),多一些「Filter」,「Config」還有「Remoting」,包含了更完整的 RPC 的配置管理,請(qǐng)求過濾,多協(xié)議支持等內(nèi)容。
而對(duì) RPC 學(xué)習(xí),例如負(fù)載均衡,除技術(shù)之外,還可以學(xué)習(xí)一種思想,是一種可遷移的東西。這種負(fù)載均衡的使用和實(shí)現(xiàn),在 Nginx、Apache 做反向代理,在 應(yīng)用服務(wù)器做集群搭建時(shí),都會(huì)用的到。
像一致性Hash,對(duì)于通過 Hash思想來實(shí)現(xiàn)請(qǐng)求均衡的實(shí)現(xiàn)中,一致性 Hash 的思路,能更大程度的保證請(qǐng)求 Hash到原來的服務(wù)器上,在增減服務(wù)器時(shí),影響減小。
再比如「注冊(cè)處」Registry 中,我們可以了解到通過 zk, redis,甚至廣播 的注冊(cè)處實(shí)現(xiàn)。這種注冊(cè)處的學(xué)習(xí),可以在我們后續(xù)的微服務(wù),分布式應(yīng)用中常用的「注冊(cè)中心」提供實(shí)現(xiàn)的思路。
再比如 我們遠(yuǎn)程調(diào)用時(shí)參數(shù)、信息的序列化,我們 Java 默認(rèn)的序列化在性能上不能滿足 RPC 這種高頻序列化的應(yīng)用場(chǎng)景,那有什么好的辦法來提升序列化性能呢?
你會(huì)發(fā)現(xiàn) Dubbo 中集成了 kryo,hessian2,fastjson等支持,可以比較學(xué)習(xí)這些不同的序列化實(shí)現(xiàn),在自己的業(yè)務(wù)場(chǎng)景中有需要時(shí),就發(fā)現(xiàn)你的技能工具箱中又多了一件工具。
類似的內(nèi)容還有很多,學(xué)習(xí)這些都能讓我們更好的成長。
【本文為51CTO專欄作者“侯樹成”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過作者微信公眾號(hào)『Tomcat那些事兒』獲取授權(quán)】