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();
相关推荐
咩咩觉主2 分钟前
en造数据结构与算法C# 群组行为优化 和 头鸟控制
开发语言·c#
是梦终空6 分钟前
JAVA毕业设计176—基于Java+Springboot+vue3的交通旅游订票管理系统(源代码+数据库)
java·spring boot·vue·毕业设计·课程设计·源代码·交通订票
CVer儿9 分钟前
条件编译代码记录
开发语言·c++
凌不了云14 分钟前
windows环境下安装python第三方包
开发语言·python
落落落sss16 分钟前
sharding-jdbc分库分表
android·java·开发语言·数据库·servlet·oracle
码爸20 分钟前
flink doris批量sink
java·前端·flink
鸽芷咕20 分钟前
【Python报错已解决】python setup.py bdist_wheel did not run successfully.
开发语言·python·机器学习·bug
星迹日34 分钟前
C语言:联合和枚举
c语言·开发语言·经验分享·笔记
知识分享小能手37 分钟前
mysql学习教程,从入门到精通,SQL DISTINCT 子句 (16)
大数据·开发语言·sql·学习·mysql·数据分析·数据库开发
Huazzi.39 分钟前
算法题解:斐波那契数列(C语言)
c语言·开发语言·算法