用 SonnetDB 观测消息队列:积压、延迟、死信与消费审计

先把边界说清楚:SonnetDB 当前没有提供 Kafka、RabbitMQ 或 MQTT broker 兼容的消息队列 API。它更适合做消息队列的“观测与审计底座”:记录积压、消费延迟、失败原因、死信摘要和处理结果,然后用 SQL、全文搜索、向量检索和 SSE 事件把这些数据用起来。

这在工业平台里很常见。真正传消息的可能是 MQTT、RabbitMQ、Kafka、Azure Service Bus 或本地 channel;SonnetDB 负责把关键运行状态长期保存下来。

记录队列指标

using SonnetDB.Engine;
using SonnetDB.Sql;

using var db = Tsdb.Open(new TsdbOptions
{
    RootDirectory = "data/queue-observability"
});

SqlExecutor.Execute(db, """
    CREATE MEASUREMENT queue_metrics (
        queue TAG,
        consumer TAG,
        backlog FIELD INT,
        lag_ms FIELD INT,
        dead_letters FIELD INT
    )
    """);

SqlExecutor.Execute(db, """
    INSERT INTO queue_metrics (time, queue, consumer, backlog, lag_ms, dead_letters)
    VALUES
      (1713676800000, 'telemetry-ingest', 'worker-a', 120, 350, 0),
      (1713676860000, 'telemetry-ingest', 'worker-a', 180, 720, 1),
      (1713676920000, 'telemetry-ingest', 'worker-a', 90,  260, 1)
    """);

查询一分钟窗口内的平均延迟:

var lag = SqlExecutor.Execute(db, """
    SELECT avg(lag_ms), max(backlog), sum(dead_letters)
    FROM queue_metrics
    WHERE queue = 'telemetry-ingest'
      AND time >= 1713676800000
      AND time < 1713677000000
    GROUP BY time(1m)
    """);

记录死信摘要

死信通常是半结构化 JSON,更适合放 document collection:

SqlExecutor.Execute(db, "CREATE DOCUMENT COLLECTION dead_letters");

SqlExecutor.Execute(db, """
    INSERT INTO dead_letters (id, document)
    VALUES
      ('dlq-1', '{"queue":"telemetry-ingest","device":"pump-1","reason":"payload schema mismatch","payloadType":"telemetry","created":1713676860000}'),
      ('dlq-2', '{"queue":"command-reply","device":"fan-2","reason":"timeout waiting for reply","payloadType":"rpc","created":1713676870000}')
    """);

SqlExecutor.Execute(db, """
    CREATE FULLTEXT INDEX ft_dead_letters_reason
    ON dead_letters ('$.reason')
    USING unicode
    """);

现在可以按原因搜索:

var failures = SqlExecutor.Execute(db, """
    SELECT id, json_value(document, '$.device') AS device, bm25_score() AS score
    FROM dead_letters
    WHERE match(ft_dead_letters_reason, '$.reason', 'schema mismatch', 20)
    ORDER BY score DESC
    """);

用 SSE 看实时状态

SonnetDB 服务端提供 /v1/events SSE 事件流,当前事件类型包括 metricsslow_querydb。它不是业务消息队列,但非常适合管理台订阅数据库运行状态:

using var http = new HttpClient();
var url = " http://127.0.0.1:5080/v1/events?access_token=your-token&stream=metrics ,slow_query";

await using var stream = await http.GetStreamAsync(url);
using var reader = new StreamReader(stream);

while (!reader.EndOfStream)
{
    var line = await reader.ReadLineAsync();
    if (!string.IsNullOrWhiteSpace(line))
    {
        Console.WriteLine(line);
    }
}

这套组合的定位很清楚:broker 负责传递,SonnetDB 负责沉淀、检索、分析和审计。这样的边界比“数据库假装自己是消息队列”更稳。


官网地址:https://sonnetdb.com

技术文章站:https://iotpaper.net

开源仓库:https://github.com/IoTSharp/SonnetDB

posted @ 2026-06-14 23:04  IoTSharp  阅读(2)  评论(0)    收藏  举报