RPC調(diào)用是現(xiàn)在中大型公司在分布式系統(tǒng)架構(gòu)栈戳、服務(wù)治理不可避免需要面對的問題。RPC框架也是各個大廠的必爭之地,例如Facebook開源框架Thrift棉磨、Google開源框架gRPC、Alibaba開源框架Dubbo学辱。做一個PRC框架并不難乘瓤,可是構(gòu)建一個高可用环形、高性能、可擴展的PRC框架可就是不那么容易了馅扣。萬丈高樓平地起斟赚,我們需要首先了解最基本的概念,才可以更容易理解這些開源框架差油。所以今天我們開始討論一下什么是RPC框架拗军。
故事現(xiàn)在正式開始:
今天新來的師弟問我:”師兄,什么是RPC蓄喇?“
”Remote Procedure Calls发侵,遠程過程調(diào)用“,我隨口一答妆偏。
師弟一臉茫然刃鳄,好像在說“英文我比你好,還用你說钱骂?”叔锐。我突然意識到這個不是他要的答案,我應(yīng)該用更容易理解的話來給一個大學(xué)剛畢業(yè)见秽,還沒有任何實戰(zhàn)經(jīng)驗的實習(xí)生講述一下什么是RPC愉烙。
“遠程調(diào)用對應(yīng)的就是本地調(diào)用,例如你在超市買蘋果解取,你這個買蘋果的動作你自己在執(zhí)行步责,可以看作本地調(diào)用≠骺啵”
“突然你的女朋友打電話過來蔓肯,讓你再買幾個香蕉。你女朋友沒有來執(zhí)行這個動作振乏,他只是調(diào)用你來做蔗包,所以你女朋友這個動作就是遠程調(diào)用』塾剩”
“哦气忠,我明白了。就是程序通過網(wǎng)絡(luò)中某種協(xié)議向另外一個計算機請求程序服務(wù)赋咽,這就是RPC調(diào)用旧噪。”
“差不多吧脓匿。但是PRC也遠沒有這么簡單淘钟,你可以...”
故事結(jié)束,下面我們就RPC做一下討論吧陪毡。
遠程過程調(diào)用
如果把事必躬親定義為本地調(diào)用米母,假手于人定義為遠程調(diào)用勾扭,那我們很容易想到就是B/S架構(gòu)的http調(diào)用,前些年比較熱的Web Service铁瞒,當(dāng)然還有國內(nèi)RPC開源框架Dubbo妙色,還有最近比較熱的微服務(wù)框架Spring Cloud. 我們可以對這些技術(shù)分別進行分析:
Http調(diào)用
HTTP協(xié)議(HyperText Transfer Protocol,超文本傳輸協(xié)議)是因特網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)傳輸協(xié)議慧耍。HTTP是一個基于TCP/IP通信協(xié)議來傳遞數(shù)據(jù)(HTML 文件, 圖片文件, 查詢結(jié)果等)身辨。HTTP協(xié)議是應(yīng)用層協(xié)議:
HTTP 協(xié)議用于B/S結(jié)構(gòu)(客戶端-服務(wù)器端)。限制每次連接只能處理一個請求芍碧,服務(wù)器處理完請求后煌珊,響應(yīng)處理后斷開連接。同時HTTP協(xié)議是無狀態(tài)協(xié)議泌豆,那就是說后續(xù)處理依賴前面的信息時定庵,需要重新發(fā)起請求。
當(dāng)然也很容用使用后端代碼來執(zhí)行HTTP調(diào)用:
// 指定URL
URL url = new URL(path);
// 獲取連接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 設(shè)置連接相關(guān)的參數(shù)
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
conn.setDoOutput(true);
conn.setDoInput(true);
//獲取URLConnection對象對應(yīng)的輸出流
PrintWriter out = new PrintWriter(conn.getOutputStream());
當(dāng)用原生的Http作為遠程調(diào)用時踪危,調(diào)用雙方需要線下溝通好協(xié)議蔬浙,這樣才可以保證正常的數(shù)據(jù)解析。如果服務(wù)端的數(shù)據(jù)格式發(fā)生變化贞远,調(diào)用無法同步感知畴博。后來 Web Servic 出現(xiàn),制訂了標(biāo)準兴革,從而緩解了這一矛盾。
Web Service
Web Service是一個平臺獨立的蜜唾,低耦合的杂曲,自包含的、基于可編程的web的應(yīng)用程序袁余,可使用開放的XML(標(biāo)準通用標(biāo)記語言下的一個子集)標(biāo)準來描述擎勘、發(fā)布、發(fā)現(xiàn)颖榜、協(xié)調(diào)和配置這些應(yīng)用程序棚饵,用于開發(fā)分布式的交互操作的應(yīng)用程序。
Web Service 的構(gòu)建思想是盡量把非核心功能交給其他人去做掩完,自己專注核心功能噪漾。自己網(wǎng)站只要能通過網(wǎng)絡(luò)調(diào)用網(wǎng)站的資源就好了。
Web Service是基于HTTP協(xié)議進行網(wǎng)絡(luò)傳輸?shù)那遗睿皇亲鳛橐粋€標(biāo)準(WSDL)欣硼,他定義了服務(wù)是什么(方法、參數(shù)恶阴、返回值)诈胜,在那里(服務(wù)的網(wǎng)絡(luò)地址URL)豹障,怎么調(diào)(通過什么方式來調(diào)用)的標(biāo)準。WSDL(Web Services Description Language)是一個基于XML的語言焦匈,用于描述Web Service及其函數(shù)血公、參數(shù)和返回值。
Web Service 除了定義了WSDL標(biāo)準在規(guī)范調(diào)用接口外缓熟,同時使用了 SOAP 規(guī)范(定義消息的XML 格式)累魔、UDDI 規(guī)范(介紹所提供的業(yè)務(wù)和服務(wù)的XML文件)。
Web Service 的特點:
- 平臺無關(guān)荚虚;
- 編程語言無關(guān)薛夜;
- 服務(wù)端運維不需要考慮客戶端兼容問題;
Web Serive 是基于Http協(xié)議的版述,同時定義了使用XML方式來做信息的交互梯澜,所以也有自己的局限性:
- 基于HTTP,每次調(diào)用都需要重復(fù)建立連接渴析,在高可用晚伙、高并發(fā)的場景下,效率很難保障俭茧;
- 使用SOAP規(guī)范的XML傳輸咆疗,傳輸內(nèi)容多且復(fù)雜,這樣傳輸?shù)男什桓吣刚F(xiàn)在逐漸趨向JSON午磁、字節(jié)碼方式等簡單方式進行傳輸;
- 在運維層面毡们,服務(wù)負載平衡已經(jīng)水平擴容都能復(fù)雜
PRC 框架 Dubbo
當(dāng)項目較小迅皇,域劃分簡單時,我們重點在建設(shè)數(shù)據(jù)庫衙熔,遠程調(diào)用只是輔助登颓,所以無論使用原生Http調(diào)用還是使用Web Service 都可以方便快捷的解決問題。當(dāng)面對大規(guī)模红氯、分布式系統(tǒng)來說框咙,我們需要更多的強調(diào)高可用、高并發(fā)痢甘。Dubbo RPC 框架就是在這一背景下產(chǎn)生喇嘱。
百度百科:
Dubbo 是阿里巴巴公司開源的一個高性能優(yōu)秀的服務(wù)框架,使得應(yīng)用可通過高性能的 RPC 實現(xiàn)服務(wù)的輸出和輸入功能塞栅,可以和Spring框架無縫集成婉称。
Dubbo 底層是基于TPC/IP(網(wǎng)絡(luò)層)來構(gòu)建的,使用長連接來保證調(diào)用的穩(wěn)定性和性能,同時 Dubbo 主要解決了下面的問題:
- 負載平衡:當(dāng)服務(wù)越來越多時王暗,服務(wù) URL 配置管理變得非常困難悔据,F(xiàn)5 硬件負載均衡器的單點壓力也越來越大。 此時需要一個服務(wù)注冊中心俗壹,動態(tài)地注冊和發(fā)現(xiàn)服務(wù)科汗,使服務(wù)的位置透明。并通過在消費方獲取服務(wù)提供方地址列表绷雏,實現(xiàn)軟負載均衡和 Failover头滔,降低對 F5 硬件負載均衡器的依賴,也能減少部分成本
- 服務(wù)治理:服務(wù)間依賴關(guān)系變得錯蹤復(fù)雜涎显,甚至分不清哪個應(yīng)用要在哪個應(yīng)用之前啟動坤检,架構(gòu)師都不能完整的描述應(yīng)用的架構(gòu)關(guān)系。 這時期吓,需要自動畫出應(yīng)用間的依賴關(guān)系圖早歇,以幫助架構(gòu)師理清關(guān)系
- 水平擴容:服務(wù)的調(diào)用量越來越大,服務(wù)的容量問題就暴露出來讨勤,這個服務(wù)需要多少機器支撐箭跳?什么時候該加機器?
整體 Dubbo 的架構(gòu):
節(jié)點 | 角色說明 |
---|---|
Provider | 暴露服務(wù)的服務(wù)提供方 |
Consumer | 調(diào)用遠程服務(wù)的服務(wù)消費方 |
Registry | 服務(wù)注冊與發(fā)現(xiàn)的注冊中心 |
Monitor | 統(tǒng)計服務(wù)的調(diào)用次數(shù)和調(diào)用時間的監(jiān)控中心 |
Container | Container |
Spring Cloud
隨著微服務(wù)的理念不斷深入Java開發(fā)者潭千,對微服務(wù)對管控谱姓、治理,負載均衡刨晴、異步消息等基礎(chǔ)設(shè)施變得更加迫切屉来。 Spring Boot 框架作為微服務(wù)的倡導(dǎo)者,對 Java 周邊的成熟的一系列框架進行整合集成狈癞,幫助Java開發(fā)者便利的使用相關(guān)框架茄靠。
百度百科:
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的開發(fā)便利性巧妙地簡化了分布式系統(tǒng)基礎(chǔ)設(shè)施的開發(fā)亿驾,如服務(wù)發(fā)現(xiàn)注冊嘹黔、配置中心账嚎、消息總線莫瞬、負載均衡、斷路器郭蕉、數(shù)據(jù)監(jiān)控等疼邀,都可以用Spring Boot的開發(fā)風(fēng)格做到一鍵啟動和部署。Spring Cloud并沒有重復(fù)制造輪子召锈,它只是將各家公司開發(fā)的比較成熟旁振、經(jīng)得起實際考驗的服務(wù)框架組合起來,通過Spring Boot風(fēng)格進行再封裝屏蔽掉了復(fù)雜的配置和實現(xiàn)原理,最終給開發(fā)者留出了一套簡單易懂拐袜、易部署和易維護的分布式系統(tǒng)開發(fā)工具包吉嚣。
總起來來說,Spring Cloud 整合的項目分兩類:成熟框架封裝蹬铺、自主實現(xiàn)了部分基礎(chǔ)設(shè)施:
項目 | 作用 |
---|---|
Spring Cloud Netflix | 是對Netflix開發(fā)的一套分布式服務(wù)框架的封裝尝哆,包括服務(wù)的發(fā)現(xiàn)和注冊,負載均衡甜攀、斷路器秋泄、REST客戶端、請求路由等规阀。 |
Spring Cloud Config | 將配置信息中央化保存, 配置Spring Cloud Bus可以實現(xiàn)動態(tài)修改配置文件 |
Spring Cloud Bus | 分布式消息隊列恒序,是對Kafka, MQ的封裝 |
Spring Cloud Security | 對Spring Security的封裝,并能配合Netflix使用 |
Spring Cloud Zookeeper | 對Zookeeper的封裝谁撼,使之能配置其它Spring Cloud的子項目使用 |
Spring Cloud Eureka | Spring Cloud Eureka 是 Spring Cloud Netflix 微服務(wù)套件中的一部分歧胁,它基于Netflix Eureka 做了二次封裝,主要負責(zé)完成微服務(wù)架構(gòu)中的服務(wù)治理功能 |
Spring Cloud 提供的一整套的應(yīng)用建設(shè)方案彤敛,真正和PRC相關(guān)的是其封裝的 Spring Cloud Netflix与帆。Spring Cloud Netflix 調(diào)用也是基于HTTP的,序列化反序列化一般采用的是jackson墨榄。
Spring Cloud 對中小企業(yè)來說是一種不錯的選擇玄糟。這些企業(yè)往往沒有精力和資金投入此類基礎(chǔ)設(shè)施的開發(fā),并且業(yè)務(wù)并不是特別的復(fù)雜袄秩,Spring Cloud 這種一站式的解決方案會節(jié)省很大的成本阵翎。
Http調(diào)用和PRC調(diào)用區(qū)別
廣義上我們認為無論是Http調(diào)用,Web Service 的調(diào)用之剧,Dubbo框架的服務(wù)調(diào)用郭卫,Spring Cloud 下的服務(wù)調(diào)用都是RPC調(diào)用。在狹義上講背稼,我愿意把RPC調(diào)用定義在TPC傳輸協(xié)議上的為RPC調(diào)用贰军。
Http調(diào)用、Web Service 的調(diào)用蟹肘、Spring Cloud 下的服務(wù)調(diào)用都是基于HTTP協(xié)議的词疼,接口一盤是XML或者是JSON,比較容易理解帘腹,開發(fā)起來也比較便利贰盗。但是對于更為復(fù)雜的系統(tǒng),成千上萬級別的系統(tǒng)需要交互時阳欲,我們可能更關(guān)注穩(wěn)定性和性能舵盈,這是基于網(wǎng)絡(luò)傳輸層(TCP)的框架往往會占有優(yōu)勢陋率,因為他可以減少連接握手次數(shù)(長鏈接),從而減少網(wǎng)絡(luò)開銷秽晚。
無論哪種方式瓦糟,為了系統(tǒng)可維護、可運維赴蝇,都需要一整套的周邊設(shè)施來幫助狸页,以便可以長期穩(wěn)定的發(fā)展。無論Web Service 提供的 WSDL 標(biāo)準扯再,Spring Cloud 一整套的微服務(wù)治理系統(tǒng)芍耘,還是 Dubbo 的服務(wù)管理端,都是為了這一目的熄阻。
在選擇RPC框架時斋竞,需要根據(jù)自己的項目特點,進行適當(dāng)?shù)倪x擇秃殉,不要為了某項技術(shù)而違背了自己的初衷坝初。