日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java sofa rpc_【剖析 | SOFARPC 框架】

發(fā)布時間:2025/4/5 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java sofa rpc_【剖析 | SOFARPC 框架】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Scalable?Open?Financial?Architecture

是螞蟻金服自主研發(fā)的金融級分布式中間件,包含了構建金融級云原生架構所需的各個組件,是在金融場景里錘煉出來的最佳實踐。

本文為《剖析 | SOFARPC 框架》第十二篇,作者鷗波。

《剖析 | SOFARPC 框架》系列由 SOFA 團隊和源碼愛好者們出品,

項目代號:,官方目錄目前已經全部認領完畢,文末提供了已完成的文章目錄。

前言

隨著 TIOBE 10月份的編程語言排行的發(fā)布,C++ 重回第三的位置,新興的 Swift 和 Go 表現出強勁的上升趨勢。雖然目前 Java 的領頭位置尚未出現有力挑戰(zhàn),我們希望能夠在基礎設施的建設上預留跨語言的可擴展設計。同時,跨語言的挑戰(zhàn)也是工程實際面臨的現狀,螞蟻內部如 AI、IoT,算法等缺少 JVM 原生支持的領域,往往不可避免地需要涉及到跨語言調用的問題。

本文將為大家介紹 基于 SOFARPC 的微服務應用在面臨跨語言調用時的方案和實現。

總體設計

經過前面幾篇對 SOFARPC 的 BOLT 協議和序列化這些的介紹,相信大家已經對 RPC 有了一些理解,提到跨語言,我們會首先想到其他語言調用 Java,Java 調用其他語言,那么這里的跨,體現在代碼上,到底跨在哪里?

從跨語言的實現上來說,主要解決兩個方面的問題:跨語言的通訊協議和序列化協議

跨語言服務發(fā)現

另外從跨語言的落地來說,還得解決一個平滑兼容的問題。

業(yè)界常見的做法是一般是通過 DNS 和 HTTP 來解決跨語言的問題,但是在內部已經有完善技術棧體系的情況下,直接切換一個新的方案顯然是不合適的,所以螞蟻內部是在已有的技術體系基礎上進行改進。

螞蟻內部使用的通訊協議是 Bolt,序列化協議是 Hessian。我們知道,服務端和客戶端在請求和返回之間攜帶的結構化的業(yè)務數據,需要在傳輸到達對端后,被本地的語言能夠易于解析消費。由于語言本身特性的差異,同一對象的在序列化和反序列化的轉換后,結構可能有差異,但是需要保證其轉換操作是可逆的。以上這點Hessian做的不是很好,其跨語言的兼容性不能滿足跨語言的需求,所以另外一個可行的方案就是就是選擇其它基于 IDL 的序列化協議,例如 Protobuf。

現成的服務注冊中心一般都有一些多語言解決方案,像 Zookeeper、SOFARegistry、Consul、etcd 等都有多語言客戶端,所以服務發(fā)現這塊問題不算太大。

例如下面就是一個基于注冊中心 + Bolt協議 + Protobuf 序列化的設計圖

通訊協議和序列化協議

通訊協議只要跨語言各方約定清楚,大家安裝約定實現即可,而序列化協議則需要較多的考量。

序列化的協議選擇列出一些考慮要點:是否采用具備自我描述能力的序列化方案,如不需要借助一些 schema 或者接口描述文件。

是否為語言無關的,包括腳本語言在內。

是否壓縮比例足夠小,滿足網絡傳輸場景的要求。

是否序列化和反序列化的性能均足夠優(yōu)秀。

是否向前/向后兼容,能夠處理傳輸對象的新增屬性在服務端和客戶端版本不一致的情況。

是否支持加密、簽名、壓縮以及擴展的上下文。

1、JSON Over HTTP

首先,說到跨語言,序列化支持,肯定有同學會問,為什么不直接通過 Http的Json來搞定呢?

雖然得益于JSON和HTTP在各個語言的廣泛支持,在多語言場景下改造支持非常便捷,能夠低成本的解決網絡通訊和序列化的問題。服務發(fā)現的過程則可以使用最簡單的固定URL(協議+域名+端口+路徑)的形式,負載均衡依賴于F5或者LVS等實現。

但是這個方案的有明顯的局限性:HTTP 作為無狀態(tài)的應用層協議,在性能上相比基于傳輸層協議(TCP)的方案處于劣勢。HTTP/1.1后可以通過設置keep-alive使用長連接,可以一定程度上規(guī)避建立連接的時間損耗;然而最大的問題是,客戶端線程采用了 request-response 的模式,在發(fā)送了 request 之后被阻塞,直到拿到 response 之后才能繼續(xù)發(fā)送。這一問題直到 HTTP/2.0 才被解決。

JSON 是基于明文的序列化,較二進制的序列化方案,其序列化的結果可讀性強,但是壓縮率和性能仍有差距,這種對于互聯網高并發(fā)業(yè)務場景下,意味著硬件成本的提升。

對于網絡變化的響應。訂閱端處理不夠強大。

2、Hessian Over BOLT

在否決了上一個方案后,我們繼續(xù)看,螞蟻內部,最開始的時候,SOFARPC 還沒有支持 Protobuf 作為序列化方式,當時為了跨語言,NodeJs的同學已經在此基礎上,用 js 重寫了一個 hessian 的版本,完成了序列化。也已經在線上平穩(wěn)運行。但是當我們要擴展給其他語言的時候,重寫 hessian 的成本太高。而且 Java語言提供的接口和參數信息,其他語言也需要自己理解一遍,對應地轉換成自己的語言對象。因此該方案在特定場景下是可行的。但不具備推廣至其他語言的優(yōu)勢。

Node的實現版本可以參考:https://github.com/alipay/sofa-rpc-node

3、Protobuf Over BOLT

Protobuf 基于 IDL,本身具備平臺無關、跨語言的特性,是一個理想的序列化方案。但是需要先編寫proto文件,結構化地描述傳輸的業(yè)務對象,并生成中間代碼。

由于要重點介紹一下這種方案,因此再次回顧一下 SOFABolt 的協議規(guī)范部分,便于后面的解釋。

對于現有的通信協議,我們改進時,將 content 部分存儲為入參對象和返回值,他們都是 pb 序列化之后的值。這樣將直接對接到現在的協議上。又利用了 BOLT 的通信協議。

以下描述了跨語言中對 Protobuf協議的使用:

首先我們看 header 部分,是簡單的扁平化的 KV。默認會增加以下三個 Entry:

KeyValue備注

sofa_head_method_name對方方法名對應 SofaRequest#methodName

sofa_head_target_app對方的應用名對應 SofaRequest#targetAppName

sofa_head_target_service對方的服務唯一命名對應 SofaRequest#targetServiceUniqueName

sofa_head_response_errortrue/false僅在響應中出現

我們再看 body 部分,根據 Protobuf 的實現,所有被序列化的對象均實現了 MessageLite 接口,然而由于多個 Classloader 存在的可能,代碼上為了避免強轉 MessageList 接口的失敗,并未直接調用 toByteArray 方法,而是通過反射機制調用 toByteArray 獲得 byte 數組。

針對 SofaRequest 這個 RPC 中的傳輸對象,由于 Protobuf 僅支持對于單個對象的序列化,因此 SofaRequest 類型的對象進行序列化,實際支持的是 SofaRequest#methodArgs 數組中的首個元素對象進行的序列化,也就是說目前我們僅支持一個入參對象。

針對 SofaResponse 這個響應對象,當出現框架異常或者返回對象是一個 Throwable 代表的業(yè)務異常時,直接將錯誤消息字符串序列化;并在響應頭中設置 sofa_head_response_error=true,其他情況才序列化業(yè)務返回對象。這樣可以避免比如 Java 語言的錯誤棧,由于含有 一些線程類和異常類,其他語言是無法解析的。

反序列化的過程稍復雜一些,上游調用傳入 SofaRequest/SofaResponse 的實例,先要在空白的 SofaRequest 對象中填入前文中在 header 反序列化中的解析的頭部信息,接著根據 Header 中接口+方法名找到等待反序列化對象的 class,并借助反射調用 parseFrom?接口生成對象,成為 SofaRequest#MethodArgs 的首個元素對象。

4、Others Over BOLT

在上一個方案的基礎上,我們也可以支持更多的語言,對 JSON、Kyro 的支持也分別處于開發(fā)和規(guī)劃中。 JSON 的支持已經開發(fā)完成待合并。這里不再做過多說明。

服務發(fā)現

跨語言各方約定了通訊協議和序列化協議后,就可以完成各自的服務端和客戶端實現,跨語言已經能完成點對點的調用了。但在實際的線上場景下,我們還是需要通過注冊中心等服務發(fā)現的形式,來保證跨語言調用的可用性。目前,有兩種可選的方案。

1、各語言對接注冊中心

對于服務發(fā)現,前面說到的最早進行跨語言的 NodeJs 實現了對接 SOFARegistry 的能力。直接通過對 Java 原生序列化和一些 hessian 的重寫,來操作完成了。在螞蟻內部,這種方案在只有 Node 的情況下是可以的,但是更通用的場景下。如果我們有了新的注冊中心,要對接更多的注冊中心,其他語言在語言表達上的差異性,使得這種方案很難推廣到其他項目。NodeJs 版本的 hessian:https://github.com/alipay/sofa-hessian-node

2、各語言對接SOFAMosn

由于每個語言都去對接對接中心存在一定的難度,也不具備可推廣性,而在螞蟻內部,我們已經在一些跨語言的場景下,運行 SOFAMosn,通過 SOFAMosn,我們對接了站內的注冊中心,其他的語言,僅需要將自己需要訂閱和發(fā)布的信息,通過 Http 的接口形式,通知 SOFAMosn,SOFAMosn 將會將這些信息和注冊中心進行注冊和訂閱,并維持地址信息。

這樣對于其他語言來說,僅需要非常簡單的 json請求,就完成了跨語言的服務注冊和訂閱。后續(xù)新注冊中心的對接等等。其他語言都不再需要理解。相關的 SDK 我們已經開發(fā)并實現完成。對于 SOFAMosn 的更多介紹,可以參看 SOFAMosn 官網:

http://www.sofastack.tech/sofa-mosn/docs/README

語言實現

pythonhttps://github.com/alipay/sofa-bolt-python

nodehttps://github.com/alipay/sofa-rpc-node

c++https://github.com/alipay/sofa-bolt-cpp

當然如果你并不需要進行服務尋址,或者能夠接受硬負載或者固定 IP的調用方式。也可以直接使用。

《新程序員》:云原生和全面數字化實踐50位技術專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的java sofa rpc_【剖析 | SOFARPC 框架】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。