冠军

导航

NATS: 自定义服务 (Service)

使用 NATS 服务框架来创建服务会变得非常简单,基于 NATS 的服务框架,NAST 的客户端库可以更简单的构建、服务发现和监控服务。服务框架自动将所有的订阅归类到一个队列组中,提供构建基于层次化的主题功能和对应的处理器。

不需要其它的负担,库提供自动化的服务发现和状态报告,通过 NATS CLI 提供的 micro 命令,可以简单地查询和报告所有使用该框架的服务。

NATS 本身提供了同步访问的 Request 模式,这里的服务与它类似,发送请求还是 Request,不过这里是通过提供一个处理器来对收到的数据直接进行加工,并返回结果。

1. 项目准备

示例项目的使用了 .NET 的日志支持,它直接将日志输出到 Console 控制台中。所以需要在项目创建之后,添加相应的 NuGet 包。

> dotnet add package NATS.Net
> dotnet add package NATS.Client.Serializers.Json
> dotnet add package Microsoft.Extensions.Logging.Console

创建日志器实例

using System;
using Microsoft.Extensions.Logging;
using NATS.Client.Core;
using NATS.Client.Serializers.Json;
using NATS.Client.Services;


using var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
var logger = loggerFactory.CreateLogger("NATS-by-Example");

创建 NATS 服务管理

var url = Environment.GetEnvironmentVariable("NATS_URL") ?? "127.0.0.1:4222";

var opts = new NatsOpts
{
    Url = url,
    LoggerFactory = loggerFactory,
    SerializerRegistry = NatsJsonSerializerRegistry.Default,
    Name = "NATS-by-Example",
};
await using var nats = new NatsConnection(opts);
var svc = new NatsSvcContext(nats);

2. 创建服务

实现创建服务对象,它用来管理具体的服务。

首先需要创建服务定义,每个服务需要

  1. 服务名称,不能包含空格
  2. 版本
  3. 描述

这里首先创建名为 minmax 的服务,

var service = await svc.AddServiceAsync(new NatsSvcConfig("minmax", "0.0.1")
{
    Description = "Returns the min/max number in a request"
});

NatsSvcConfig 定义

虽然此时还没有运行中的服务端点,这个服务已经可以通过 micro 协议可以被发现出来,比如通过 nats micro 命令查询。所有后台的支持,比如服务发现,PING 和状态此时都已经开始。

每当创建一个服务实例的时候,它会赋予一个唯一的标识。如果有同样名称的 minmax 运行在 NATS 的主题空间中,那么像 nats micro 这样的工具会将它们视为服务的同一个实例,而背后对该端点的订阅被作为一个队列订阅。因此,对服务的每个请求将只会发给一个端点进行处理。

3. 添加服务端点

到此为止,其实还没有对外的服务访问端点。此时的服务还是一个内部的概念。这一节开始这个问题。

当端点不支持固定的主题的时候,服务可以被加入到一个组中,这个组的名称被视为命名空间,当作主题的前缀。在下面的示例中,所有的端点都将会监听以 minmax 开始的主题。

var root = await service.AddGroupAsync("minmax");

现在为服务创建 2 个访问端点。一个用于 min 操作,另一个用于 max 操作。每个端点表示为一个订阅。参数中提供的处理器将负责实际的响应处理,分别对应 minmax.minminmax.max

await root.AddEndpointAsync(HandleMin, "min", serializer: NatsJsonSerializer<int[]>.Default);
await root.AddEndpointAsync(HandleMax, "max", serializer: NatsJsonSerializer<int[]>.Default);

ValueTask HandleMin(NatsSvcMsg<int[]> msg)
{
    var min = msg.Data.Min();
    return msg.ReplyAsync(min);
}

ValueTask HandleMax(NatsSvcMsg<int[]> msg)
{
    var min = msg.Data.Max();
    return msg.ReplyAsync(min);
}

4. 访问服务

访问服务通过向服务端点发出请求来实现。

下面的示例中,分别向 minmax.minminmax.max 发出请求,它们的前缀是服务组 minmax

注意对于请求没有什么特别的,就是常规的 NATS 请求。是同步访问,等待返回结果的形式。

var min = await nats.RequestAsync<int[], int>("minmax.min", new[]
{
    -1, 2, 100, -2000
}, requestSerializer: NatsJsonSerializer<int[]>.Default);
logger.LogInformation("Requested min value, got {Min}", min.Data);


var max = await nats.RequestAsync<int[], int>("minmax.max", new[]
{
    -1, 2, 100, -2000
}, requestSerializer: NatsJsonSerializer<int[]>.Default);
logger.LogInformation("Requested max value, got {Max}", max.Data);

logger.LogInformation("Bye!");

现在,通过 micro 管理的处理可以对请求进行处理,我们自己不需要其它额外的代码来管理它们。

就是这样啦!

Reference:

posted on 2024-07-18 14:05  冠军  阅读(60)  评论(0编辑  收藏  举报