主题与通配符
2026/1/15大约 3 分钟
主题与通配符
主题(Subject)
NATS 使用主题(Subject)来路由消息。主题是一个简单的字符串,用于标识消息的目的地。
主题命名规则
- 由字母、数字和特殊字符组成
- 使用
.分隔层级 - 区分大小写
- 不能以
.开头或结尾 - 不能包含空格
# 有效的主题名
time.us
time.us.east
time.us.east.atlanta
orders.new
orders.processed
sensor.temperature.room1主题层级设计
良好的主题设计有助于消息的组织和过滤:
推荐的命名模式:
# 按业务域划分
{domain}.{action}.{region}
# 示例
orders.created.us
orders.created.eu
users.registered.asia
payments.completed.global通配符
NATS 支持两种通配符,用于订阅多个主题。
单级通配符(*)
* 匹配单个层级中的任意字符。
# 主题
time.us.east
time.us.west
time.eu.london
# 订阅 time.*.east 匹配
time.us.east ✓
time.eu.east ✓
time.us.west ✗
# 订阅 time.us.* 匹配
time.us.east ✓
time.us.west ✓
time.eu.london ✗// Go 示例
nc.Subscribe("time.*.east", func(m *nats.Msg) {
// 接收 time.us.east, time.eu.east 等
})
nc.Subscribe("orders.*.created", func(m *nats.Msg) {
// 接收 orders.us.created, orders.eu.created 等
})多级通配符(>)
> 匹配一个或多个层级,必须放在主题末尾。
# 主题
time.us
time.us.east
time.us.east.atlanta
time.eu.london
# 订阅 time.us.> 匹配
time.us.east ✓
time.us.east.atlanta ✓
time.us.west ✓
time.eu.london ✗
# 订阅 time.> 匹配所有
time.us ✓
time.us.east ✓
time.us.east.atlanta ✓
time.eu.london ✓// Go 示例
nc.Subscribe("orders.>", func(m *nats.Msg) {
// 接收所有 orders 开头的消息
})
nc.Subscribe(">", func(m *nats.Msg) {
// 接收所有消息(谨慎使用)
})通配符对比
| 通配符 | 说明 | 位置 | 示例 |
|---|---|---|---|
* | 匹配单个层级 | 任意位置 | orders.*.new |
> | 匹配多个层级 | 仅末尾 | orders.> |
实际应用场景
1. 日志收集
# 主题设计
logs.{service}.{level}
# 示例
logs.api.info
logs.api.error
logs.worker.warn
logs.db.error// 订阅所有错误日志
nc.Subscribe("logs.*.error", func(m *nats.Msg) {
alertTeam(m.Data)
})
// 订阅特定服务的所有日志
nc.Subscribe("logs.api.>", func(m *nats.Msg) {
storeLog(m.Data)
})2. 传感器数据
# 主题设计
sensor.{type}.{location}.{device_id}
# 示例
sensor.temperature.building1.floor1.device001
sensor.humidity.building1.floor2.device002
sensor.pressure.building2.floor1.device003// 订阅某栋楼的所有温度传感器
nc.Subscribe("sensor.temperature.building1.>", func(m *nats.Msg) {
processTemperature(m.Data)
})
// 订阅所有传感器数据
nc.Subscribe("sensor.>", func(m *nats.Msg) {
storeMetrics(m.Data)
})3. 订单系统
# 主题设计
orders.{region}.{status}
# 示例
orders.us.created
orders.us.paid
orders.eu.shipped
orders.asia.delivered// 订阅美国区域所有订单状态
nc.Subscribe("orders.us.*", func(m *nats.Msg) {
updateUSOrders(m.Data)
})
// 订阅所有已支付订单
nc.Subscribe("orders.*.paid", func(m *nats.Msg) {
processPayment(m.Data)
})4. 微服务事件
# 主题设计
events.{service}.{entity}.{action}
# 示例
events.user.account.created
events.user.profile.updated
events.order.item.added
events.payment.transaction.completed// 订阅用户服务所有事件
nc.Subscribe("events.user.>", func(m *nats.Msg) {
handleUserEvent(m.Data)
})
// 订阅所有创建事件
nc.Subscribe("events.*.*.created", func(m *nats.Msg) {
auditCreation(m.Data)
})主题设计最佳实践
1. 层级清晰
# 好的设计
{domain}.{subdomain}.{action}.{qualifier}
# 示例
ecommerce.orders.created.priority
ecommerce.inventory.updated.warehouse12. 避免过深层级
# 不推荐(层级过深)
a.b.c.d.e.f.g.h
# 推荐(3-4 层)
domain.entity.action3. 使用有意义的名称
# 不推荐
msg.1.a
# 推荐
orders.new.us4. 考虑通配符订阅
设计主题时考虑未来的通配符订阅需求:
# 便于按区域订阅
orders.{region}.{status}
# 可以订阅 orders.us.* 或 orders.*.created
# 便于按服务订阅
{service}.{entity}.{action}
# 可以订阅 user.> 或 *.account.created小结
主题是 NATS 消息路由的核心,合理的主题设计和通配符使用可以大大简化消息的组织和订阅。单级通配符 * 匹配单个层级,多级通配符 > 匹配多个层级。
面试题预览
常见面试题
- NATS 的两种通配符有什么区别?
- 如何设计一个好的主题层级结构?
- 通配符
>为什么只能放在主题末尾?
