微服務調用為什么用RPC框架?
RPC是一種概念,http是RPC實現的一種方式,用http交互其實就已經屬于rpc了!
RPC 協議名詞解釋在一個典型RPC的使用場景中,包含了服務發現、負載、容錯、網絡傳輸、序列化等組件,其中RPC協議就指明了程序如何進行網絡傳輸和序列化 。也就是說一個RPC協議的實現就等于一個非透明的RPC調用,如何做到的的呢?
RPC 協議的組成1.地址:服務提供者地址
2.端口:協議指定開放的端口
3.運行服務
nettyminaRMI服務servlet容器(jetty/tomcat/Jboss)4.報文編碼:協議報文編碼 。注①:http 報文編碼 。注②:Dubbo 報文編碼
5.序列化方式
Hessian2SerializationDubboSerializationJavaSerializationJsonSerializationRPC協議報文編碼與實現詳解1、HTTP協議報文
2、Dubbo協議報文
協議編解碼過程Dubbo 支持的RPC協議列表1、dubbo
實現描述: 傳輸服務: mina, netty(默認), grizzy序列化: dubbo, hessian2(默認), java, fastjson 自定義報文
連接描述:
單個長連接NIO異步傳輸
適用場景:
1、常規RPC調用2、傳輸數據量小 3、提供者少于消費者
2、rmi
實現描述:
傳輸:java rmi 服務序列化:java原生二進制序列化
連接描述:
多個短連接BIO同步傳輸
適用場景:
1、常規RPC調用2、與原RMI客戶端集成 3、可傳少量文件 4、不支持防火墻穿透
3、hessian
實現描述:
傳輸服務:servlet容器序列化:hessian二進制序列化
連接描述:
基于Http 協議傳輸,依懶servlet容器配置
適用場景:
1、提供者多于消費者2、可傳大字段和文件 3、跨語言調用
4、http
實現描述:
傳輸服務:servlet容器序列化:http表單
連接描述:
依懶servlet容器配置
適用場景:
1、數據包大小混合
RPC 傳輸實現RPC的協議的傳輸是基于 TCP/IP 做為基礎使用Socket 或Netty、mina等網絡編程組件實現。但有個問題是TCP是面向字節流的無邊邊界協議,其只管負責數據傳輸并不會區分每次請求所對應的消息,這樣就會出現TCP協義傳輸當中的拆包與粘包問題
拆包與粘包產生的原因們知道tcp是以流動的方式傳輸數據,傳輸的最小單位為一個報文段(segment)。tcp Header中有個Options標識位,常見的標識為mss(Maximum Segment Size)指的是,連接層每次傳輸的數據有個最大限制MTU(Maximum Transmission Unit),一般是1500比特,超過這個量要分成多個報文段,mss則是這個最大限制減去TCP的header,光是要傳輸的數據的大小,一般為1460比特。換算成字節,也就是180多字節。
tcp 為 提高性能,發送端會將需要發送的數據發送到緩沖區,等待緩沖區滿了之后,再將緩沖中的數據發送到接收方。同理,接收方也有緩沖區這樣的機制,來接收數據。這時就會出現以下情況:
應用程序寫入的數據大于MSS大小,這將會發生拆包應用程序寫入數據小于MSS大小,這將會發生粘包接收方法不及時讀取套接字緩沖區數據,這將發生粘包。拆包與粘包解決辦法設置定長消息,服務端每次讀取既定長度的內容作為一條完整消息{"type":"message","content":"hello"}\n使用帶消息頭的協議、消息頭存儲消息開始標識及消息長度信息,服務端獲取消息頭的時候解析出消息長度,然后向后讀取該長度的內容。