自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

徹底搞懂 RSocket 協(xié)議

網(wǎng)絡(luò) 網(wǎng)絡(luò)優(yōu)化
今天我們系統(tǒng)討論了 RSocket 這款新的高性能網(wǎng)絡(luò)通信協(xié)議。與 HTTP 協(xié)議相比,RSocket 提供了四種不同的交互模式來實現(xiàn)多樣化的網(wǎng)絡(luò)通信。

我們知道,常見的 RESTful Web 服務(wù)采用的都是基于 HTTP 協(xié)議實現(xiàn)的請求 - 響應(yīng)式交互方式。這種交互方案很簡單,但是因為只支持單一的交互方式,也就無法應(yīng)對所有日常開發(fā)需求場景,例如服務(wù)端主動向客戶端推送數(shù)據(jù)。

請求 - 響應(yīng)模式請求 - 響應(yīng)模式

那么,能不能在網(wǎng)絡(luò)協(xié)議層上具備更加豐富的交互方式呢?答案是肯定的,這就是我們今天要討論的 RSocket 協(xié)議。RSocket 協(xié)議提供了多種客戶端和服務(wù)端之間的交互方式,它并不是對 HTTP 協(xié)議的補充,而是一個基于響應(yīng)式編程技術(shù)的全新的、高性能網(wǎng)絡(luò)通訊協(xié)議。

在引入 RSocket 協(xié)議之前,你必須要了解為什么需要這樣一個協(xié)議,讓我們從傳統(tǒng)的請求 - 響應(yīng)模式所存在的問題開始說起。

RSocket 協(xié)議解決了什么問題?

請求 - 響應(yīng)模式的問題

請求 - 響應(yīng)模式的一個問題是,高并發(fā)場景下,性能和響應(yīng)性上存在瓶頸。因為整個處理過程是同步阻塞的,如果某個請求的響應(yīng)時間過長,會導(dǎo)致其他請求無法及時響應(yīng)。這一點我之前在之前的響應(yīng)式編程一課中有詳細講解。

更重要的是,對很多應(yīng)用場景來說,HTTP 協(xié)議提供的請求 - 響應(yīng)模式是不合適的。典型的例子是消息推送,如果客戶端需要獲取最新的推送消息,就必須使用輪詢,客戶端不停的發(fā)送請求到服務(wù)器來檢查更新,無疑這會造成了大量資源浪費。

客戶端輪詢模式客戶端輪詢模式

你可能會說,我們可以使用服務(wù)器發(fā)送事件(Server-Sent Events,SSE)技術(shù)實現(xiàn)從服務(wù)端向客戶端推送消息。不過,SSE 也是一個構(gòu)建在 HTTP 協(xié)議上的處理機制,一般只用來傳送文本,提供的功能非常有限。

服務(wù)器發(fā)送事件服務(wù)器發(fā)送事件

幸運的是,業(yè)界認識到了異步、多向交互通信的必要性。在 2015 年,RSocket 協(xié)議就在這樣的背景下誕生了。

RSocket 協(xié)議的解決方案

RSocket 是一種語言無關(guān)的二進制網(wǎng)絡(luò)協(xié)議,用來解決現(xiàn)有網(wǎng)絡(luò)傳輸協(xié)議存在的單一請求 - 響應(yīng)模式以及性能問題。那么,它是怎么解決這個問題的呢?

RSocket 以異步消息的方式提供 4 種交互模式,除了請求 - 響應(yīng)(request/response)模式之外,還包括請求 - 響應(yīng)流(request/stream)、即發(fā)即棄(fire-and-forget)和通道(channel)這三種新的交互模式。

RSocket 協(xié)議的四種交互模式RSocket 協(xié)議的四種交互模式

我們來看這四種交互模式的特點:

請求 - 響應(yīng)模式:這是最典型也最常見的模式。發(fā)送方在發(fā)送消息給接收方之后,等待與之對應(yīng)的響應(yīng)消息

請求 - 響應(yīng)流模式:發(fā)送方的每個請求消息,都對應(yīng)接收方的一個消息流作為響應(yīng)

即發(fā)即忘模式:發(fā)送方的請求消息沒有與之對應(yīng)的響應(yīng)

通道模式:在發(fā)送方和接收方之間建立一個雙向傳輸?shù)耐ǖ?/span>

我們可以從請求與響應(yīng)的數(shù)量對應(yīng)關(guān)系來對上述四種交互模式做一個總結(jié)。

可以看到,當(dāng)我們選擇具體的交互模式時,請求 - 響應(yīng)、請求 - 響應(yīng)流和即發(fā)即忘這三種交互模式的請求數(shù)量都是 1,并能夠獲取不同數(shù)量的響應(yīng)結(jié)果。我們就可以根據(jù)這一特性來重構(gòu)現(xiàn)有的請求處理過程。而通道模式則比較特殊,它的請求數(shù)量和響應(yīng)數(shù)量都是 N,決定了我們可以選擇它來應(yīng)對雙向的數(shù)據(jù)流處理場景。

RSocket 協(xié)議專門設(shè)計用來和響應(yīng)式編程技術(shù)風(fēng)格的應(yīng)用程序配合使用,在使用 RSocket 協(xié)議時,響應(yīng)式編程體系中的數(shù)據(jù)流機制仍然有效。

為了更好的理解 RSocket 協(xié)議,我們對比它和 HTTP 協(xié)議。在交互模式上,與 HTTP 的請求 - 響應(yīng)這種單向交互模式不同,RSocket 倡導(dǎo)的是對等通信。這種對等通信不是傳統(tǒng)單向交互模式的改進,而是在客戶端和服務(wù)端之間可以自由的相互發(fā)送和處理請求。

RSocket 協(xié)議的交互方式RSocket 協(xié)議的交互方式

另一方面,從性能上講,我們知道 HTTP 協(xié)議為了兼容各種應(yīng)用方式,本身有一定的復(fù)雜性和冗余性,性能一般。而 RSocket 采用的是自定義二進制協(xié)議,本身的定位就是高性能通訊協(xié)議,性能上比 HTTP 高出一個數(shù)量級。

如何正確使用 RSocket 協(xié)議?

到這里,我們就明白了 RSocket 協(xié)議是要解決什么問題,以及是如何解決的了。接下來,我們具體看看如何正確使用 RSocket 協(xié)議。

RSocket 接口

我們先來看一下 RSocket 協(xié)議中最核心的接口,即 RSocket 接口的定義,如下所示。

public interface RSocket extends Availability, Closeable {
 //推送元信息,數(shù)據(jù)可以自定義
 Mono<Void> metadataPush(Payload payload);
    //請求-響應(yīng)模式,發(fā)送一 個請求并接收一個響應(yīng)
 Mono<Payload> requestResponse(Payload payload);
    //即發(fā)-即忘模式,請求-響應(yīng)的優(yōu)化,在不需要響應(yīng)時非常有用
    Mono<Void> fireAndForget(Payload payload);
    //請求-響應(yīng)流模式,類似于返回集合的請求/響應(yīng),集合將以流的方式返回,而不是等到查詢完成
    Flux<Payload> requestStream(Payload payload);
    //通道模式,允許任意交互模型的雙向消息流
    Flux<Payload> requestChannel(Publisher<Payload> payloads);
}

顯然,RSocket 接口通過四個方法分別實現(xiàn)了它所提供的四種交互模式,這里的 Payload 代表的就是一種消息對象,由兩部分組成,即元信息 metadata 和數(shù)據(jù) data,類似于常見的消息通信中的消息頭和消息體的概念。

同時,你注意到嗎,這里出現(xiàn)了兩個新的數(shù)據(jù)結(jié)構(gòu) Mono 和 Flux。在響應(yīng)式編程中,Mono 代表只包含 0 個或 1 個元素的數(shù)據(jù)流,而對應(yīng)的 Flux 則是一個包含 0 到 n 個元素的數(shù)據(jù)流。

所以 fireAndForget() 方法返回的是一個 Mono 流,符合即發(fā) - 即棄模式的語義。而 requestStream() 作為請求 - 響應(yīng)流模式的實現(xiàn),與 requestResponse() 的區(qū)別在于它的返回值是一個 Flux 流,而不是一個 Mono 對象。而且,RSocket 提供的請求 - 響應(yīng)模式也比 HTTP 更具優(yōu)勢,因為它是異步且多路復(fù)用的。

另一方面,與其他方法不同,requestChannel() 方法返回的并不是一個 Payload 消息對象,而是一個代表響應(yīng)式流的 Publisher 對象,意味著這種模式下的輸入輸出都是響應(yīng)式流,也就是說可以實現(xiàn)客戶端和服務(wù)端之間的雙向交互,這也和通道模式的定義一致。

RSocket 與框架集成

RSocket 接口過于底層,開發(fā)人員需要考慮服務(wù)器端和客戶端的具體構(gòu)建方式以及手工實現(xiàn)遠程調(diào)用的細節(jié)。所以,我通常不建議直接使用 RSocket 接口進行應(yīng)用程序的開發(fā),而是傾向于借助特定的開發(fā)框架。如果你使用的是 Spring Boot 框架,就可以構(gòu)建如下所示一個簡單 Controller:

@Controller
public class HelloController {
 @MessageMapping("hello")
 public Mono<String> hello(String name) {
   return Mono.just("Hello: " + name);
 }
}

這里引入了一個新的注解@MessageMapping,類似 Spring MVC 中的@RequestMapping 注解,@MessageMapping 是,Spring 中提供,用來指定 RSocket 協(xié)議中消息處理的目的地。然后,我們輸入了一個 String 類型的參數(shù)并返回一個 Mono 對象,符合請求 - 響應(yīng)交互模式的定義。

為了訪問這個 RSocket 端點,我們需要構(gòu)建一個 RSocketRequester 請求對象。基于該對象,我們就可以通過它的 route() 方法路由到前面通過@MessageMapping 注解構(gòu)建的"hello"端點,如下所示:

Mono<String> response = requester.route("hello")
        .data("Geektime")
        .retrieveMono(String.class);

我們再來看一個請求 - 響應(yīng)流的示例,如下所示:

@MessageMapping("stream")
Flux<Message> stream(Request request) {
       return Flux
               .interval(Duration.ofSeconds(1))
               .map(index -> new Message(request.getParam, index));
}

這里我們根據(jù)輸入的 Request 對象,返回一個 Flux 流,每一秒發(fā)送一個新的 Message 對象。

如果你想在其他框架中使用 RSocket 協(xié)議,也有很多選擇。Dubbo 在 3.0.0-SNAPSHOT 版本里基于 RSocket 對響應(yīng)式編程提供了支持,開發(fā)人員可以非常方便的使用 RSocket 的 API。而隨著 Spring 框架的持續(xù)升級,5.2 版本中也把 RSocket 作為缺省的網(wǎng)絡(luò)通信協(xié)議。

目前,RSocket 協(xié)議的應(yīng)用已經(jīng)越來越廣泛。相信隨著這項技術(shù)的不斷成熟,日常開發(fā)過程中也會出現(xiàn)更多的應(yīng)用場景和解決方案。

總結(jié)

今天我們系統(tǒng)討論了 RSocket 這款新的高性能網(wǎng)絡(luò)通信協(xié)議。與 HTTP 協(xié)議相比,RSocket 提供了四種不同的交互模式來實現(xiàn)多樣化的網(wǎng)絡(luò)通信。同時,RSocket 也無縫集成了響應(yīng)式編程技術(shù),我們可以通過 RSocket 協(xié)議來實現(xiàn)異步、非阻塞式的網(wǎng)絡(luò)通信。

責(zé)任編輯:武曉燕 來源: 程序猿技術(shù)充電站
相關(guān)推薦

2024-01-03 13:39:00

JS,Javascrip算法

2023-10-18 10:55:55

HashMap

2025-01-13 16:00:00

服務(wù)網(wǎng)關(guān)分布式系統(tǒng)架構(gòu)

2025-04-11 05:55:00

2017-12-05 17:44:31

機器學(xué)習(xí)CNN卷積層

2020-10-14 08:50:38

搞懂 Netty 線程

2020-04-15 08:00:00

計算機網(wǎng)絡(luò)通信設(shè)備通信協(xié)議

2021-12-29 17:29:07

KubernetesEvents集群

2023-09-28 08:15:05

SpringBean加載

2021-10-11 11:58:41

Channel原理recvq

2023-05-29 08:12:38

2025-03-17 00:21:00

2021-10-09 19:05:06

channelGo原理

2020-03-18 14:00:47

MySQL分區(qū)數(shù)據(jù)庫

2021-08-09 08:53:30

HTTP狀態(tài)化協(xié)議

2022-04-24 11:06:54

SpringBootjar代碼

2022-08-26 13:24:03

version源碼sources

2021-06-30 08:45:02

內(nèi)存管理面試

2022-06-07 10:13:22

前端沙箱對象

2020-12-07 06:19:50

監(jiān)控前端用戶
點贊
收藏

51CTO技術(shù)棧公眾號