传输配置
transports 段定义北向(northbound)传输通道。每个传输实例将采集到的数据点发布到云端或上游系统,并可选地接收反向写命令。
字段位置
batch-size、flush-interval、retry-count、buffer-size、fallback 是传输的顶层字段(与 settings 平级),不能写进 settings 内部。配置校验会对这种错位快速失败,报错并提示把字段上移一层,指出正确的缩进位置。
transports:
- name: cloud-mqtt
type: mqtt
settings:
broker: tcp://broker.emqx.io:1883
client-id: factory-edge-01
qos: 1
topic-template: "factory/{{.Driver}}/{{.Group}}/{{.Tag}}"
# command-topic: "factory/commands/#" # 订阅命令主题必须同时配置 command-secret(见下文)
batch-size: 50 # ← 顶层字段,与 settings 平级
flush-interval: 1s # ← 顶层字段传输通用字段
所有传输实例共享以下字段,settings 内容随 type 不同而变化。
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
name | string | 是 | — | 传输实例名称,全局唯一,用于规则 target 引用 |
type | string | 是 | — | 传输类型:mqtt、http 或 notify |
settings | object | 是 | — | 协议专属连接参数 |
batch-size | int | 否 | 100 | 单次批量发送的最大数据点数。顶层字段(与 settings 平级) |
flush-interval | duration | 否 | — | 触发刷新的时间间隔,未设置则不启用定时刷新。顶层字段 |
retry-count | int | 否 | 0(不重试) | 发送失败后的重试次数。顶层字段 |
buffer-size | int | 否 | 100 | 命令/数据通道容量,超出后丢弃。顶层字段 |
fallback | string | 否 | — | 备用传输名称,本传输发布失败时自动切换到该传输。顶层字段 |
支持的传输类型:
type | 协议 | 典型目标 |
|---|---|---|
mqtt | MQTT 3.1.1 | IoT 平台、边缘网关、命令回写 |
http | HTTP/REST | MES、数据湖 API、Webhook |
notify | 告警通知 | Slack、Microsoft Teams、邮件、自定义 Webhook(见下文 Notify 传输 小节) |
INFO
batch-size 与 flush-interval 共同决定发送时机:任一条件先满足即触发发送。例如 batch-size: 50 且 flush-interval: 1s,则 1 秒内攒满 50 点立即发送,否则满 1 秒发送当前已攒的点。
通用参数详解
batch-size
单次批量发送的数据点上限。较大的值提升吞吐但增加单次延迟,较小的值降低延迟但增加请求次数。
| 场景 | 推荐值 |
|---|---|
| 高频传感器、云端聚合 | 100–500 |
| 低频关键数据、需低延迟 | 1–10 |
| MQTT 受限于单包大小 | 50–100 |
flush-interval
定时刷新间隔,保证数据点不会因 batch-size 未凑满而无限滞留。采用 Go duration 字符串(1s、500ms 等)。未设置时不启用定时刷新,仅按 batch-size 触发发送。
TIP
若数据稀疏且未设置 flush-interval,点会长期滞留队列,不建议用于实时场景。建议显式设置一个合理的刷新间隔。
尾批滞留(tail-batch retention)
仅配置 batch-size(或 retry-count)而未设置 flush-interval、且未启用全局 buffer 时,不足一批的尾部数据会无限期滞留——直到攒满一批或 CoreC 退出才发送。低速 tag + 大 batch-size 下,单点延迟可达 batch-size × 采集间隔(如 1 点/分钟 + batch-size: 100 ≈ 100 分钟)。配置校验(POST /configs/validate 响应的 warnings 字段)与启动/重载日志都会对此给出非阻塞 warning。启用全局 buffer 时批量器会自动补默认 5s 定时刷新,不受此影响;无法解析为正 duration 的 flush-interval 会被批量器静默忽略,同样触发该 warning。
retry-count
发送失败后的重试次数。每次重试间隔采用指数退避(100ms × 2^n,上限 5s)。默认 0 表示不重试。重试耗尽后,若启用了全局 buffer,数据批次写入本地磁盘缓冲待后续回放;否则数据批次丢弃并累加 failed 计数。
离线缓冲
全局 buffer 配置启用后,传输重试耗尽时数据会写入本地磁盘,待传输恢复后自动回放,防止数据丢失。详见全局配置 - buffer。
fallback
配置备用传输名称。当本传输发布失败(重试耗尽后)时,引擎自动将数据点转发到 fallback 指定的传输。适用于双链路冗余场景(如 MQTT 主链路 + HTTP 备用链路)。fallback 仅尝试一次,不递归(即备用传输的 fallback 不会被跟随)。
transports:
- name: primary-mqtt
type: mqtt
settings: { ... }
fallback: backup-http # 主链路失败时切换到 HTTP 备用
- name: backup-http
type: http
settings: { ... }buffer-size
命令/数据通道容量(内部 command/data channel)。当入站速率超过引擎消费速率、通道已满时执行非阻塞丢弃:
- MQTT 命令:转入传输本地的死信存储(有界,可通过
GET /write/failed?source=ingress查询重放),并累加dropped_commands计数; - MQTT 数据点 / HTTP webhook 数据点:直接丢弃并记录
warn日志(webhook 场景计入响应体的queue_dropped)。
默认 100。
MQTT (mqtt)
通过 MQTT 协议发布数据点,并可选订阅命令主题接收反向写命令(下行控制)。
- name: cloud-mqtt
type: mqtt
settings:
broker: tcp://broker.emqx.io:1883
client-id: factory-edge-01
qos: 1
topic-template: "factory/{{.Driver}}/{{.Group}}/{{.Tag}}"
batch-size: 50
flush-interval: 1ssettings 字段
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
broker | string | 是 | — | Broker 地址,格式 scheme://host:port |
client-id | string | 否 | 自动生成(corec-<传输名>-<毫秒时间戳>) | 客户端 ID,需在 Broker 范围内唯一 |
username | string | 否 | — | 用户名认证 |
password | string | 否 | — | 密码认证 |
qos | int | 否 | 1 | 服务质量等级,取值 0、1、2 |
retained | bool | 否 | false | 是否发布保留消息 |
topic-template | string | 否 | corec/{{.Driver}}/{{.Tag}} ¹ | 发布主题模板,支持 Go 模板变量 |
command-topic | string | 否 | — ¹ | 订阅的命令主题,支持通配符 + / #;设置时必须同时设置 command-secret,否则传输拒绝启动 |
command-secret | string | 条件必填 | — | 命令 HMAC-SHA256 认证密钥;配置了 command-topic 时必填(缺省时启动失败,fail-closed),见命令认证与防重放 |
command-max-skew | duration | 否 | 5m | 命令时间戳允许偏移;0 关闭防重放窗口与新鲜度校验 |
command-strict-replay | bool | 否 | false | true 时拒绝无 timestamp 的签名命令(生产环境推荐) |
command-forward-topic | string | 否 | — | 链式核心命令透传:中继节点收到目标为本节点无对应驱动的命令时,转发到此下游主题 |
command-forward-secret | string | 否 | — | 转发命令的 HMAC-SHA256 签名密钥并附带新时间戳;空则转发时不签名 |
data-topic | string | 否 | — ¹ | 订阅的数据主题(链式核心入站),需配合 parser |
keep-alive | duration | 否 | 60s | 心跳保活间隔 |
connect-timeout | duration | 否 | 10s | 连接超时时间 |
auto-reconnect | bool | 否 | true | 是否自动重连 |
clean-session | bool | 否 | true | 是否使用干净会话 |
connect-retry | bool | 否 | true | 是否在连接失败后自动重试 |
connect-retry-interval | duration | 否 | 5s | 连接重试间隔(Init 时施加 ±20% 抖动防止重连风暴) |
subscribe-timeout | duration | 否 | 5s | 订阅操作超时 |
publish-timeout | duration | 否 | 5s | 发布操作超时 |
disconnect-quiesce | duration | 否 | 1s | 断开连接时的静默等待时长 |
tls-ca-file | string | 否 | — | CA 证书 PEM 文件路径(校验服务端);省略时使用系统根证书 |
tls-cert-file | string | 否 | — | 客户端证书 PEM 文件路径(启用 mTLS),需与 tls-key-file 成对设置 |
tls-key-file | string | 否 | — | 客户端私钥 PEM 文件路径 |
will-topic | string | 否 | — | **遗嘱消息(LWT)**主题:CoreC 异常掉线(崩溃/断网/断电,无 DISCONNECT 包)时由 Broker 代发的主题。下游系统据此获得 Broker 侧的网关存活信号,无需依赖指标抓取间隔。与 will-payload 同时设置才生效 |
will-payload | string | 否 | — | 遗嘱消息内容(如 offline) |
will-qos | int | 否 | 0 | 遗嘱消息 QoS |
will-retain | bool | 否 | true | 遗嘱消息是否保留——保留后迟到的订阅者也能立即看到离线状态 |
parser | object | 否 | — | 入站数据解析器配置,见解析器配置 |
遗嘱与重连的关系
LWT 只在异常掉线时触发;CoreC 优雅退出(SIGINT/SIGTERM)会正常发送 DISCONNECT,遗嘱不触发。断网后 paho 自动重连成功则 Broker 清除遗嘱状态——因此上游应订阅 will-topic 并结合 $SYS 或重连日志判断网关当前是否可达。
¹ 自动发现
当配置了 node.id(拓扑自动发现)时:MQTT 传输省略的 topic-template、command-topic 会按 {prefix}/{node-id}/... 自动生成;显式设置 data-topic 时省略的 parser 自动补 { type: default };上游节点的数据主题由发现机制自动订阅(以 auto-<上游ID> 为名新增传输)。显式配置的字段始终优先,不会被覆盖。详见 链式核心 → 拓扑自动发现。
broker
| scheme | 含义 | 示例 |
|---|---|---|
tcp:// | 明文 MQTT | tcp://broker.emqx.io:1883 |
ssl:// tls:// mqtts:// mqtt+ssl:// tcps:// | TLS 加密 MQTT | mqtts://broker.emqx.io:8883 |
ws:// | WebSocket | ws://broker.emqx.io:8083/mqtt |
wss:// | WebSocket over TLS | wss://broker.emqx.io:8084/mqtt |
TLS
TLS 实际由 broker URL 的 scheme 决定:使用 mqtts://、ssl:// 等 TLS scheme 才会在链路上加密,tls-ca-file/tls-cert-file/tls-key-file 只提供证书材料。配置了任一 tls-* 证书文件但 broker 使用明文 scheme(如 tcp://)时,传输初始化直接报错——拒绝"以为加密实则明文"的配置。两者都不设置时连接保持明文。
qos
| 取值 | 含义 | 适用场景 |
|---|---|---|
0 | 至多一次,不保证送达 | 高频低价值遥测 |
1 | 至少一次,保证送达但可能重复 | 推荐,工业数据常用 |
2 | 恰好一次,开销最大 | 命令回写、计费数据 |
WARNING
client-id 必须唯一。重复 ID 会导致后连接的客户端踢掉先前的会话,造成数据中断。多实例部署时建议附加主机名或 Pod 名后缀。
topic-template
发布主题使用 Go template 语法,可引用数据点字段:
| 变量 | 来源 | 示例值 |
|---|---|---|
{{.Driver}} | 驱动实例名 | plc-modbus |
{{.Group}} | 标签分组 | sensors |
{{.Tag}} | 标签名 | temperature |
{{.Device}} | 设备名 | plc-01 |
topic-template: "factory/{{.Driver}}/{{.Group}}/{{.Tag}}"
# 渲染结果:factory/plc-modbus/sensors/temperatureTIP
主题层级设计建议遵循 组织/产线/设备/测点 的从宽到窄结构,便于下游按层级订阅与权限控制。
command-topic
订阅该主题以接收反向写命令。消息体为 JSON 格式的 WriteCommand:
{
"driver": "plc-modbus",
"device": "plc-01",
"tag": "pump_status",
"value": true,
"type": "bool"
}支持 MQTT 通配符:
| 通配符 | 含义 |
|---|---|
+ | 单层通配,匹配一个主题层级 |
# | 多层通配,匹配剩余所有层级(只能放末尾) |
command-topic: "factory/commands/#" # 接收所有命令
command-topic: "factory/commands/plc-modbus/+" # 仅该驱动的命令命令认证与防重放
配置了 command-topic 后,任何能向该主题发布消息的客户端都可注入控制命令,因此 command-secret 为必填项:不设置时传输拒绝启动(fail-closed)。命令消息需携带 hex(HMAC-SHA256(secret, 规范化签名载荷)),放在 X-Signature 或 signature JSON 字段(签名载荷为移除签名字段、按键名递归排序后的 JSON)。
防重放依赖消息中的 timestamp 字段(Unix 毫秒):
- 带
timestamp的签名命令:时间戳参与签名(不可伪造),且必须落在±command-max-skew内;有界重放缓存(10,000 条,TTL 为 2× skew 窗口)记录每条已认证命令的哈希,同一消息在窗口内不可二次接受。 - 无
timestamp的签名命令(遗留发送方):command-strict-replay: false(默认)时首次接受并告警,重放缓存同样生效——同一载荷在窗口内的重发会被当作重放拒绝;command-strict-replay: true时直接拒绝。 command-max-skew: 0显式关闭新鲜度校验与重放缓存(不推荐)。
生产环境强制
无 timestamp 的签名没有时效边界,重放缓存只在窗口内拦截重复。生产环境应设置 command-strict-replay: true,要求所有发送方携带时间戳,使重放在窗口外也无法得逞。
data-topic(链式核心入站)
订阅数据主题以接收上游 CoreC 实例或第三方 MQTT 发布者的数据(链式核心 / chained-core 入站)。设置 data-topic 后需配合 parser 配置将消息体解析为 DataPoint。解析后的数据点进入引擎 DataBus,流经规则并可被重新发布到下游传输,实现多跳中继拓扑(边缘 → 网关 → 云端)。
settings:
data-topic: "upstream/factory/#"
parser:
type: default # json.Unmarshal(DataPoint),CoreC→CoreC 零成本路径HTTP (http)
通过 HTTP/REST 将数据点批量推送到上游 API,适用于 MES、数据湖、Webhook 等场景。HTTP 传输也可通过 webhook 接收入站数据(链式核心入站)。
WARNING
HTTP Push 的反向控制指令通道(OnCommand())存在但当前不投递。反向下发请使用 MQTT command-topic。
- name: mes-http-push
type: http
settings:
url: "http://localhost:8080/api/v1/telemetry"
method: POST
headers:
Authorization: "Bearer mes-secret-key"
Content-Type: "application/json"
timeout: 3s
batch-size: 100
flush-interval: 5ssettings 字段
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
url | string | 条件必填 | — | 上游 API 地址;未设置 webhook-addr 时必填,仅作 webhook 入站时可省略 |
method | string | 否 | POST | HTTP 方法,通常 POST 或 PUT |
headers | map[string]string | 否 | — | 自定义请求头 |
timeout | duration | 否 | 5s | HTTP 请求超时时间 |
max-idle-conns | int | 否 | 100 | 连接池最大空闲连接数 |
max-idle-conns-per-host | int | 否 | 20 | 每主机最大空闲连接数 |
idle-conn-timeout | duration | 否 | 90s | 空闲连接超时时间 |
webhook-addr | string | 否 | — | Webhook 监听地址(链式核心入站),如 0.0.0.0:9091;设置时必须同时设置 webhook-secret,否则传输拒绝启动 |
webhook-path | string | 否 | /data | Webhook URL 路径 |
webhook-secret | string | 条件必填 | — | Webhook 认证密钥;配置了 webhook-addr 时必填(缺省时启动失败,fail-closed)。请求须携带 Authorization: Bearer <secret> 或 X-Webhook-Secret: <secret> 头,否则返回 401 |
tls-cert-file | string | 否 | — | Webhook 服务端证书 PEM 文件路径;与 tls-key-file 同时设置时 webhook 以 HTTPS 监听 |
tls-key-file | string | 否 | — | Webhook 服务端私钥 PEM 文件路径 |
parser | object | 否 | — | 入站数据解析器配置,见解析器配置 |
url
完整 URL,包含 scheme 与路径。支持 http:// 与 https://,使用 https:// 时核心自动校验服务端证书。当传输仅用于 webhook 入站(已设置 webhook-addr)时,url 可省略。
url: "https://mes.example.com/api/v1/telemetry"method
| 取值 | 含义 |
|---|---|
POST | 创建新记录,最常用 |
PUT | 整体替换资源 |
PATCH | 部分更新 |
headers
键值对形式的自定义请求头,常用于鉴权与内容类型声明:
headers:
Authorization: "Bearer mes-secret-key"
Content-Type: "application/json"
X-Tenant-Id: "factory-01"INFO
核心默认以 JSON 数组形式发送批量数据点,即 []DataPoint,且自动附加 Content-Type: application/json。若上游要求不同结构,可在网关层做转换。
timeout
单次 HTTP 请求(含重试中的每次尝试)的超时时间,默认 5s。超时后视为本次发送失败,进入重试流程。HTTP 传输内置的发布重试仅针对网络错误与 5xx 响应(500ms 起指数退避);4xx 等其他非 2xx 响应立即失败不重试——重试无法改变客户端错误的结果。
连接池
以下字段控制底层 HTTP 客户端的连接池行为,均为可选:
| 字段 | 默认值 | 说明 |
|---|---|---|
max-idle-conns | 100 | 连接池最大空闲连接数 |
max-idle-conns-per-host | 20 | 每主机最大空闲连接数 |
idle-conn-timeout | 90s | 空闲连接超时时间 |
webhook-addr / webhook-path(链式核心入站)
设置 webhook-addr 后,传输会启动一个 HTTP 服务接收上游 CoreC 实例或第三方 POST 请求中的数据(链式核心入站)。请求体可以是单个 DataPoint JSON 对象或 []DataPoint 数组,经 parser 解析后进入引擎 DataBus。仅接受 POST,单请求体上限 10 MiB;认证方式见上表 webhook-secret。
响应(202 Accepted,JSON 体):批量请求的逐项结果计数——部分失败对发送方可见:
{ "received": 4, "accepted": 2, "parse_failed": 2, "queue_dropped": 0 }parse_failed 是无法解析为数组元素的条目数;queue_dropped 是已解析但引擎入站队列满被丢弃的条目数。
settings:
webhook-addr: "0.0.0.0:9091"
webhook-path: "/ingest"
webhook-secret: "your-webhook-secret"
parser:
type: default # json.Unmarshal(DataPoint)解析器配置(parser)
当传输配置了入站通道(MQTT data-topic 或 HTTP webhook-addr)时,需通过 parser 配置将消息体解析为 DataPoint。parser 是 settings 下的一个子对象。
parser.type
| 取值 | 说明 |
|---|---|
default | 直接 json.Unmarshal 为 DataPoint,CoreC→CoreC 零成本路径(默认) |
jsonpath | 通过 Go template 将任意 JSON 字段映射到 DataPoint |
raw | 将整个 payload 视为标量值,tag 可从 MQTT topic 提取 |
default 解析器
无需额外配置,消息体须为 DataPoint 的 JSON 表示。数值按数据点的 type 字段精确反序列化——上游 CoreC 发布的 64 位整数(int64/uint64)逐位保留,超过 ±2^53 的值不会因浮点转换失真。
jsonpath 解析器
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
parser.driver | string | 否 | — | 静态 driver 字段值 |
parser.tag | string | 否 | — | tag 字段的模板或静态字符串 |
parser.value | string | 否 | — | value 字段的模板路径 |
parser.data-type | string | 否 | — | 数据类型名,如 float32、int64。设为整数类型时,数字载荷按声明的位宽从原文精确解析(不经浮点),超过 ±2^53 的 64 位值不失真 |
parser.group | string | 否 | — | 静态 group 字段值 |
parser.device | string | 否 | — | 静态 device 字段值 |
parser.timestamp | string | 否 | — | timestamp 字段的模板路径 |
parser.timestamp-format | string | 否 | rfc3339 | 时间戳格式:rfc3339、unix、unixmilli |
parser:
type: jsonpath
driver: "lora-gateway"
tag: "{{ .payload.dev_id }}"
value: "{{ .payload.temp }}"
data-type: "float32"
group: "sensors"
timestamp: "{{ .payload.ts }}"
timestamp-format: "unix"raw 解析器
将整个 payload 视为标量值,tag 可从 MQTT topic 的指定层级提取。
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
parser.driver | string | 否 | — | 静态 driver 字段值 |
parser.tag | string | 否 | — | 静态 tag 字段值 |
parser.tag-from-topic | int | 否 | 0 | 取 MQTT topic 第 N 段作为 tag,0 表示使用静态 tag |
parser.data-type | string | 否 | float64 | 数据类型名 |
parser.group | string | 否 | — | 静态 group 字段值 |
parser.device | string | 否 | — | 静态 device 字段值 |
parser.timestamp-format | string | 否 | rfc3339 | 时间戳格式 |
parser:
type: raw
driver: "factory"
tag-from-topic: 2 # 使用 MQTT topic 第 2 段作为 tag
data-type: "float32"完整示例
transports:
# MQTT 云端传输:发布 + 链式入站
- name: cloud-mqtt
type: mqtt
settings:
broker: ssl://broker.emqx.io:8883
client-id: factory-edge-01
qos: 1
topic-template: "factory/{{.Driver}}/{{.Group}}/{{.Tag}}"
# 命令回写需成对配置(缺 command-secret 时传输拒绝启动):
# command-topic: "factory/commands/#"
# command-secret: ${COREC_COMMAND_SECRET}
data-topic: "upstream/factory/#"
parser:
type: default
batch-size: 50
flush-interval: 1s
retry-count: 5
buffer-size: 100
# HTTP 推送:MES 数据接入 + Webhook 入站
- name: mes-http-push
type: http
settings:
url: "https://mes.example.com/api/v1/telemetry"
method: POST
headers:
Authorization: "Bearer mes-secret-key"
timeout: 5s
webhook-addr: "0.0.0.0:9091"
webhook-path: "/ingest"
webhook-secret: ${COREC_WEBHOOK_SECRET} # webhook-addr 必配,否则传输拒绝启动
parser:
type: default
batch-size: 100
flush-interval: 5s
retry-count: 3
buffer-size: 100TIP
对关键数据建议同时配置 MQTT 与 HTTP 两个传输,并通过规则 mirror 动作双发,实现传输层冗余。
Notify 传输(告警通知)
type: notify 将规则触发的事件通过 Slack、Microsoft Teams、邮件或自定义 Webhook 发送通知。通常与规则引擎的 forward 或 alert 动作配合使用。
transports:
- name: alert-slack
type: notify
settings:
channel: slack # slack | teams | email | webhook
webhook-url: "https://hooks.slack.com/services/T.../B.../..."
cooldown: 5m # 同一规则在冷却窗口内抑制重复通知
template: "[{{.Rule}}] {{.Tag}} = {{.Value}} ({{.Driver}})"通道配置
channel 本身为必填。各通道的其余字段:
| 通道 | 必需字段 | 可选字段 |
|---|---|---|
slack | webhook-url | template, cooldown |
teams | webhook-url | template, cooldown |
email | smtp-host, smtp-port, from, to | smtp-user, smtp-pass, subject, body, cooldown |
webhook | url | method, headers, body-template, cooldown |
无法识别的 channel 取值或缺失必需字段会导致传输初始化失败。cooldown 的抑制键为规则名(数据点 metadata.rule;无规则上下文时回退到标签名)——同一规则在窗口内的重复触发只发送一次通知。
模板变量
template(Slack/Teams)和 body/body-template(email/webhook)使用 Go text/template 语法,可用变量:
| 变量 | 说明 |
|---|---|
.Rule | 触发通知的规则名 |
.Tag | 数据点标签名 |
.Value | 数据点值 |
.Driver | 驱动名 |
.Device | 设备名 |
.Group | 标签组 |
.Quality | 数据质量 |
.Timestamp | 时间戳 |
邮件示例
transports:
- name: alert-email
type: notify
settings:
channel: email
smtp-host: smtp.example.com
smtp-port: 587
smtp-user: corec
smtp-pass: ${SMTP_PASS}
from: [email protected]
to:
- [email protected]
- [email protected]
subject: "[CoreC] {{.Rule}}"
body: "Tag {{.Tag}} on {{.Driver}}/{{.Device}} = {{.Value}}"
cooldown: 10mTIP
to 字段支持 YAML 列表或逗号分隔字符串两种形式。headers 支持 YAML map 或 JSON 字符串。