rsocket-java 高效的服务间通讯

参考:
rsocket 官方文档
rsocket-java demo示例 - request/response模式下的路由请求
SpringBoot整合RSocket实时数据通信
spring官方文档介绍rsocket
集成spring-rsocket
spring官方集成rsocket高级配置

一、背景

大型分布式系统通常由不同的团队使用各种技术和编程语言以模块化方式实现。这些部件需要可靠地通信,并支持快速、独立的演进。在分布式系统中,模块之间有效且可扩展的通信是一个至关重要的问题。它显著影响用户体验的延迟程度以及构建和运行系统所需的资源量。

二、交互模型

Fire-and-Forget

即发即弃是一种请求/响应的优化,在不需要响应时非常有用。它可以实现显着的性能优化,不仅可以通过跳过响应来节省网络使用量,还可以节省客户端和服务器的处理时间,因为不需要记录来等待和关联响应或取消请求。

此交互模型对于支持有损的用例非常有用,例如非关键事件日志记录。

java 复制代码
Future<Void> completionSignalOfSend = socketClient.fireAndForget(message);

Request/Response (single-response)

仍然支持标准请求/响应语义,并且仍然期望代表 RSocket 连接上的大多数请求。这些请求/响应交互可以被视为优化的"只有 1 个响应的流",并且是通过单个连接复用的异步消息。

消费者"等待"响应消息,因此它看起来像典型的请求/响应,但其底层从不同步阻塞。

java 复制代码
Future<Payload> response = socketClient.requestResponse(requestPayload);

Request/Stream (multi-response, finite)

从Request/Response扩展而来的是Request/Stream,它允许将多个消息流式传输回来。将此视为"集合"或"列表"响应,但不是将所有数据作为单个响应返回,而是每个元素按顺序流式传输回来。

使用情景可能包括:

  • 获取视频列表
  • 获取目录中的产品
  • 逐行检索文件
java 复制代码
Publisher<Payload> response = socketClient.requestStream(requestPayload);

Channel

通道是双向的,在两个方向上都有消息流

常用于此交互模型的示例用例是:

  • 客户端请求一个数据流,该数据流最初会打破当前的世界观
  • 当发生变化时,增量/差异从服务器发送到客户端
  • 客户端随着时间的推移更新订阅以添加/删除标准/主题/等。

如果没有双向通道,客户端将不得不取消初始请求、重新请求并从头开​​始接收所有数据,而不是仅仅更新订阅并有效地获取差异。

java 复制代码
Publisher<Payload> output = socketClient.requestChannel(Publisher<Payload> input);

三、示例

Request/Response (single-response)

包含路由模式,通过指定不同的路由地址,自定义实现不同的服务处理逻辑

server:

java 复制代码
RSocketServer.create(
    SocketAcceptor.forRequestResponse(
        payload -> {
            final String route = decodeRoute(payload.sliceMetadata());

            log.info("接收来自客户端的路由请求[route={}]", route);

            payload.release();

            if ("my.test.route".equals(route)) {
            	// 返回消息给客户端
                return Mono.just(ByteBufPayload.create("Hello From My Test Route"));
            }

            return Mono.error(new IllegalArgumentException("Route " + route + " not found"));
        }))
.bindNow(TcpServerTransport.create("localhost", 7000));

client:

java 复制代码
RSocket socket =
     RSocketConnector.create()
         // here we specify that route will be encoded using
         // Routing&Tagging Metadata layout specified at this
         // subspec https://github.com/rsocket/rsocket/blob/master/Extensions/Routing.md
         .metadataMimeType(WellKnownMimeType.MESSAGE_RSOCKET_ROUTING.getString())
         .connect(TcpClientTransport.create("localhost", 7000))
         .block();

 final ByteBuf routeMetadata =
     TaggingMetadataCodec.createTaggingContent(
         ByteBufAllocator.DEFAULT, Collections.singletonList("my.test.route"));
 socket
     .requestResponse(ByteBufPayload.create(ByteBufUtil.writeUtf8(ByteBufAllocator.DEFAULT, "HelloWorld"), routeMetadata))
     .map(Payload::getDataUtf8)
     .onErrorReturn("error")
     .doOnNext(p -> System.out.println("服务器返回消息: " + p))
     .log()
     .block();
相关推荐
不才不才不不才7 分钟前
Spring 源码系列(14): JDK 动态代理 vs CGLIB,以及拦截器责任链
java·开发语言·spring
mifengxing8 分钟前
计算机组成原理——存储器系统
开发语言·考研·计算机组成原理·复习笔记·计算机408
流云鹤20 分钟前
05Java学习day(5)
java·学习
用户31268748772030 分钟前
Spring 事件机制到底怎么传播的?ApplicationEvent 源码拆解
java·spring
默辨41 分钟前
Spring AI Alibaba 核心知识点
java·ai·spring ai·spring alibaba
乐观的Terry1 小时前
10、发布系统-路由管理与灰度发布
java
唐青枫1 小时前
Java WebLogic 实战指南:从 Domain、数据源到 WAR 部署和集群管理
java
Yolanda_20221 小时前
Python学习-第九部分-错误处理与异常处理
开发语言·python·学习
郝学胜-神的一滴1 小时前
Qt 高级编程 037:QSS按钮样式封神指南
开发语言·c++·qt·软件工程·用户界面
DFT计算杂谈1 小时前
SCIENTIFIC REPORTS 非 van der Waals可调二维磁性材料设计平台
开发语言·php