请求-回复消息

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. PHP面试,Redis

    1. 什么是Redis? Redis(Remote Dictionary Server)是一个开源的内存数据存储系统,它可以用作数据库.缓存和消息中间件.它支持多种数据结构,如字符串.哈希.列表.集合 ...

  2. bpftool使用方法简介

    1.安装bpftool工具 看起来,在不同的linux发行版里,bpftool在不同的软件包里,ubuntu 22上,bpftool是linux-tools-generic的一部分,而树莓派里bpft ...

  3. 使用Swagger的好处

    是一个规范和完整的框架 用于生成.描述.调用和可视化RESTful风格的Web服务 接口的文档在线自动生成 功能测试

  4. MYSQL存储过程-练习2 while 循环

    MYSQL存储过程-练习2 while 循环 1 #WHILE循环 2 DELIMITER $$ 3 4 CREATE PROCEDURE `sp_while`() 5 BEGIN 6 DECLARE ...

  5. 4:Exchange安装后的任务

    4:Exchange安装后的任务 安装后的任务: 第一:证书的申请安装,分配服务略 注意项:如果是通配符证书,不能直接分配pop的服务              第二:虚拟目录的配置  Exchang ...

  6. 你为什么不应该过度关注go语言的逃逸分析

    逃逸分析算是go语言的特色之一,编译器自动分析变量/内存应该分配在栈上还是堆上,程序员不需要主动关心这些事情,保证了内存安全的同时也减轻了程序员的负担. 然而这个"减轻负担"的特性 ...

  7. 不用PLC和板卡,一台电脑就可以控制伺服

    1.前言 大家好!我是付工. EtherCAT是运动控制领域使用最广泛的总线通信协议之一. 如果我们只有一台电脑,能不能直接控制EtherCAT总线伺服呢? 这个是完全可以的. 我们可以在电脑上安装实 ...

  8. Python实现回数

    题目:回数是指从左向右读和从右向左读都是一样的数,例如 12321,909.请利用 filter()滤掉非回数: 思路:要实现回数判断,主要是将输入的数找到其各个位置的值,然后判断前后相对应的位置是否 ...

  9. docker的使用-01配置国内镜像仓库提高加快拉取镜像的速度

    docker的使用-01配置国内镜像仓库提高加快拉取镜像的速度 我的docker版本:(win10专业版,安装的当前最新版docker desktop) docker --version Docker ...

  10. ansible开局配置-openEuler

    ansible干啥用的就不多介绍了,这篇文章主要在说ansible的安装.开局配置.免密登录. ansible安装 查看系统版本 cat /etc/openEuler-latest 输出内容如下: o ...