用 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 事件流,当前事件类型包括 metrics、slow_query 和 db。它不是业务消息队列,但非常适合管理台订阅数据库运行状态:
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

浙公网安备 33010602011771号