请求-回复消息

https://docs.nats.io/nats-concepts/core-nats/reqreply

请求-回复

在分布式系统中,请求-回复是一种常见的模式。发送请求之后,应用程序或者基于特定的超时等待回复,或者 同步 收到响应内容

现代系统不断增长的复杂性需要诸如 位置透明性 的特性,扩展与收缩,可发现性等等。为了支持该特性,多种其他的技术需要与其他组件协作,sidecar 和代理。NATS 从使用另外一种途径,实现的请求-回复模式更加简单。

NATS 使得请求-回复更为简单和强大

  • NATS 使用核心通讯机制来支持请求-回复模式 - 发布和订阅。请求使用一个回复主题发布到特定的主题上,响应者监听在该主题上,然后将回复发送回回复主题。回复主题被称为 Inbox 收件箱。这些唯一的主题被动态直接返回给请求者,而不受彼此位置的影响。
  • 多个NATS 响应者可以构成动态的 queue 组。进而,不需要手动将订阅者添加进入或者从组中删除来启动或者停止分布式消息。这是自动完成的,该特性支持响应者根据需要扩展或者收缩。
  • NATS 应用程序 退出前抽干 (在关闭连接之前处理缓冲的消息))。该特性支持应用程序可以收缩而不会丢失请求消息。
  • 因为 NATS 基于发布订阅,可观察性如同执行其他应用一样简单,可以观察请求和响应来测量延迟,注意异常情况、直接可扩展性等。
  • NATS 的强大甚至可以支持多响应,使用首个响应并高效丢弃其他的消息。该特性优美支持多个响应者,减少响应的延迟和抖动。

模式

使用 请求-回复 演练 来实验该功能

没有响应者

当请求发送到没有订阅者的主题上时,可以方便地知道这种问题。

对于该场景,NATS 客户端可以 可选没有响应者消息 。这要求服务器和客户端支持 Headers。在启用之后,发送到没有订阅者的主题后,将立即收到一个 503 的状态,没有主体的回复响应。

多数的客户端对于此种场景将抛出或者返回一个错误,例如

m, err := nc.Request("foo", nil, time.Second);
# err == nats.ErrNoResponders

https://natsbyexample.com/examples/messaging/request-reply/dotnet2

请求-响应 模式支持客户端在发送一个消息之后,期待得到某种响应返回。在实践中,请求消息或者是一个命令,期望请求的服务处理某种工作并返回状态的变化,或者是一个查询,用来请求信息。

与诸如 HTTP 的请求响应约束不同,NATS 并不严格限制在客户端和服务端的点对点的约束。请求-响应模式是构建在核心的发布订阅模型之上的。

在默认情况下,这意味着任何对请求消息的订阅者都可以作为响应者并回复客户端。这是因为 NATS 并不限制点对点的交互,客户端可以向 NATS 指示应允许多个回复。

下面的示例展示了基本的请求-响应模式,包括标准的在没有订阅者存在的情况下的 没有响应者 错误处理,以及响应请求的消息。

代码说明

首先需要安装 NATS.Net NuGet 包。

创建 NATS 连接

代码中使用常用的命名空间和创建 NATS 链接

连接到 NATS 服务器,因为连接是 Disposable 的,我们应该 flush 使用的缓冲区并关闭连接。

using System;
using System.Diagnostics;
using System.Threading.Tasks;
using NATS.Client.Core; var stopwatch = Stopwatch.StartNew(); var url = Environment.GetEnvironmentVariable("NATS_URL") ?? "127.0.0.1:4222";
Log($"[CON] Connecting to {url}..."); var opts = NatsOpts.Default with { Url = url };
await using var nats = new NatsConnection(opts);

创建消息处理器,订阅到目标主题上

创建消息的事件处理器,然后借助于通配符 greet.* 订阅到目标主题上。

当客户端准备请求的时候,客户端填充 reply-to 字段,然后开始将它作为主题监听 ()订阅) 它,对于响应者来说,只是简单的发布消息到 reply-to 上。

await using var sub = await nats.SubscribeCoreAsync<int>("greet.*");

 var reader = sub.Msgs;
var responder = Task.Run(async () =>
{
await foreach (var msg in reader.ReadAllAsync())
{
var name = msg.Subject.Split('.')[1];
Log($"[REP] Received {msg.Subject}");
await Task.Delay(500);
await msg.ReplyAsync($"Hello {name}!");
}
});

客户端发送请求,等待响应最多 1s

var replyOpts = new NatsSubOpts { Timeout = TimeSpan.FromSeconds(2) };

Log("[REQ] From joe");
var reply = await nats.RequestAsync<int, string>("greet.joe", 0, replyOpts: replyOpts);
Log($"[REQ] {reply.Data}"); Log("[REQ] From sue");
reply = await nats.RequestAsync<int, string>("greet.sue", 0, replyOpts: replyOpts);
Log($"[REQ] {reply.Data}"); Log("[REQ] From bob");
reply = await nats.RequestAsync<int, string>("greet.bob", 0, replyOpts: replyOpts);
Log($"[REQ] {reply.Data}");

服务端取消订阅

取消订阅。

等待原有的处理队列完成

await sub.UnsubscribeAsync();

await responder;

服务端取消订阅之后,后继请求将会超时

try
{
reply = await nats.RequestAsync<int, string>("greet.joe", 0, replyOpts: replyOpts);
Log($"[REQ] {reply.Data} - This will timeout. We should not see this message.");
}
catch (NatsNoReplyException)
{
Log("[REQ] timed out!");
}

完成

Log("Bye!");

return;

void Log(string log) => Console.WriteLine($"{stopwatch.Elapsed} {log}");

NATS: 请求-响应消息的更多相关文章

  1. BizTalk开发系列(三十)单向端口实现请求-响应

    BizTalk本质上是异步的消息处理引擎.BizTalk的请求与响应模式是基于异步之上的同步消息交换.消息引擎通过消息的扩展架构链接许 多异步消息,消息的相关集关联请求与响应消息.例如,客户端发送一个 ...

  2. Katalon Studio之请求响应中文乱码解决方法

    最近在用Katalon做接口测试过程中发现请求响应消息中返回的中文均为乱码,这是因为我们使用的系统环境在初始安装时选择的中文简体,导致windows系统默认编码格式为GBK,但是KS的编码格式是UTF ...

  3. 第三篇 :微信公众平台开发实战Java版之请求消息,响应消息以及事件消息类的封装

    微信服务器和第三方服务器之间究竟是通过什么方式进行对话的? 下面,我们先看下图: 其实我们可以简单的理解: (1)首先,用户向微信服务器发送消息: (2)微信服务器接收到用户的消息处理之后,通过开发者 ...

  4. Axis2(10):使用soapmonitor模块监视soap请求与响应消息

    在Axis2中提供了一个Axis2模块(soapmonitor),该模块实现了与<WebService大讲堂之Axis2(9):编写Axis2模块(Module)>中实现的logging模 ...

  5. “一切都是消息”--MSF(消息服务框架)之【请求-响应】模式

    在前一篇, “一切都是消息”--MSF(消息服务框架)入门简介, 我们介绍了MSF基于异步通信,支持请求-响应通信模式和发布-订阅通信模式,并且介绍了如何获取MSF.今天,我们来看看如何使用MSF来做 ...

  6. WCF消息交换模式之请求-响应模式

    WCF的消息交换模式(MEP)有三种:请求/响应.单向模式和双工模式.WCF的默认MEP是请求/响应模式. 请求/响应模式操作签名代码如下,无需指定模式,默认就是. [OperationContrac ...

  7. Eclipse 查看 WebService 服务请求和响应消息

    每个WebService 对入参和返参都是有自己的要求的:别人调用我的WebService,需要按照我的要求进行传参.当我返回数据时,我也得告诉别人,我的返回数据是怎样组织的,方便别人读取. 那怎样查 ...

  8. “一切都是消息”--iMSF(即时消息服务框架)之【请求-响应】模式(点对点)

    MSF的名字是 Message Service Framework 的简称,由于目前框架主要功能在于处理即时(immediately)消息,所以iMSF就是 immediately Message S ...

  9. Java开发微信公众号(三)---微信服务器请求消息,响应消息,事件消息以及工具处理类的封装

    在前面几篇文章我们讲了微信公众号环境的配置 和微信公众号服务的接入,接下来我们来说一下微信服务器请求消息,响应消息以及事件消息的相关内容,首先我们来分析一下消息类型和返回xml格式及实体类的封装. ( ...

  10. HTTP协议请求响应过程和HTTPS工作原理

    HTTP协议 HTTP协议主要应用是在服务器和客户端之间,客户端接受超文本. 服务器按照一定规则,发送到客户端(一般是浏览器)的传送通信协议.与之类似的还有文件传送协议(file transfer p ...

随机推荐

  1. [Tkey] CodeForces 1267G Game Relics

    太神了这题,膜拜出题人 orz. 思考一 首先是大家都提到的一点,先抽卡再买.这里来做个数学分析. 假设我们还剩 \(k\) 种没有买,其实我们是有式子来算出它的花费期望的.WIKI 上提到,假设一个 ...

  2. 全网最适合入门的面向对象编程教程:53 Python 字符串与序列化-字符串与字符编码

    全网最适合入门的面向对象编程教程:53 Python 字符串与序列化-字符串与字符编码 摘要: 在 Python 中,字符串是文本的表示,默认使用 Unicode 编码,这允许你处理各种字符集,字符编 ...

  3. MQ核心作用异步&削峰&解耦使用场景详解

    说在前面 在如今的高并发互联网应用中,如何确保系统在巨大的流量冲击下还能稳稳当当运转,是每个技术团队都会遇到的挑战.说到这,消息队列(MQ) 就是背后的"大功臣"了. 无论是异步处 ...

  4. 前端 export default 和 export const name 的区别?

    export default 是默认导出export const 是命名导出 在一个vue文件中export const可以有多个,但是export default只有且仅有一个,{}表示导入非默认变 ...

  5. url 统一资源定位符的组成

    协议 protocol :http 或者 https = http + ssl  或者 file 文件(本地): 域名 host 或 ip 地址: 端口 port 省略默认 80  : 路径 path ...

  6. vue本地项目启动时遇到coreJs相关报错问题处理

    启动项目的时候报错 : 是因为core.js这个包丢失,需要大家重新下载即可 : yarn add core-js

  7. 怎么封装一个vue的自定义指令

    自定义指令分为 全局和局部的指令 : 1. 自定义全局指令: 在 mian.js 中 ,使用 Vue.directive('指令名' ,  配置对象 ) 2. 局部自定义指令 在组件中使用 direc ...

  8. Canvas简历编辑器-层级渲染与事件管理能力设计

    Canvas简历编辑器-选中绘制与拖拽多选交互设计 在之前我们聊了聊如何基于Canvas与基本事件组合实现了轻量级DOM,并且在此基础上实现了如何进行管理事件以及多层级渲染的能力设计.那么此时我们就依 ...

  9. 设计卷积神经网络CNN为什么不是编程?

    上一篇:<搞清楚这个老六的真面目!逐层'剥开'人工智能中的卷积神经网络(CNN)> 序言:现在让我们开始走进卷积神经网络(CNN)的世界里.和传统编程完全不同,在人工智能的程序代码里,您看 ...

  10. 深入解析C#异步编程:await 关键字背后的实现原理

    C# 异步编程中 await 实现原理详解 在C#中,async 和 await 关键字用于编写异步代码.本文将详细介绍 await 的实现原理,包括状态机的生成.回调函数的注册和触发等关键步骤. 1 ...