2.1 EdgeX Foundry整体架构
EdgeX Foundry 是一个高度灵活、可扩展的开源边缘计算框架,专为工业物联网设计。让我们深入解析其架构设计。
2.1.1 分层架构设计
EdgeX Foundry 采用清晰的四层架构:
┌─────────────────────────────────────────────────────────────┐
│ 应用服务层 (Export Services) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Rules │ │ eKuiper │ │ Custom │ │
│ │ Engine │ │ (Stream) │ │ Exporter │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└────────────────────────────┬────────────────────────────────┘
│
┌────────────────────────────▼────────────────────────────────┐
│ 核心服务层 (Core Services) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Core Data │ │Core Metadata │ │ Core Command │ │
│ │ (数据存储) │ │ (元数据) │ │ (命令控制) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└────────────────────────────┬────────────────────────────────┘
│
┌────────────────────────────▼────────────────────────────────┐
│ 设备服务层 (Device Services) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Modbus TCP │ │ OPC-UA │ │ BACnet │ │
│ │ Service │ │ Service │ │ Service │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
2.1.2 各层职责详解
应用服务层(Export Services)
- 数据转换和过滤
- 云端数据导出
- 规则引擎集成
- 流式数据分析
核心服务层(Core Services)
- Core Data:设备数据存储和管理
- Core Metadata:设备配置文件和元数据管理
- Core Command:设备命令控制
设备服务层(Device Services)
- 协议转换
- 设备连接管理
- 数据采集
- 命令下发
2.2 消息格式与数据模型
EdgeX Foundry 使用标准化的消息格式,让我们深入分析:
2.2.1 MessageEnvelope结构
go
// edgex/models.go - EdgeX消息模型
package edgex
import (
"encoding/json"
"time"
)
// EdgeXMessage EdgeX消息信封结构
type EdgeXMessage struct {
CorrelationID string `json:"correlationId"`
MessageType string `json:"messageType"`
Origin int64 `json:"origin"`
Payload json.RawMessage `json:"payload"`
}
// Event EdgeX事件结构
type Event struct {
ID string `json:"id"`
DeviceName string `json:"deviceName"`
ProfileName string `json:"profileName"`
SourceName string `json:"sourceName"`
Origin int64 `json:"origin"`
Readings []Reading `json:"readings"`
}
// Reading 传感器读数结构
type Reading struct {
ID string `json:"id"`
DeviceName string `json:"deviceName"`
ResourceName string `json:"resourceName"`
Value string `json:"value"`
ValueType string `json:"valueType"`
BaseType string `json:"baseType"`
Origin int64 `json:"origin"`
Metadata json.RawMessage `json:"metadata,omitempty"`
}
2.2.2 消息处理流程
go
// edgex/processor.go - 消息处理器实现
package edgex
import (
"encoding/json"
"fmt"
"log"
"sfsEdgeStore/common"
)
// ProcessMessage 处理EdgeX消息
func ProcessMessage(payload []byte) (*Event, error) {
var msg EdgeXMessage
if err := json.Unmarshal(payload, &msg); err != nil {
return nil, fmt.Errorf("failed to unmarshal message: %v", err)
}
// 验证消息类型
if msg.MessageType != "event" {
log.Printf("Ignoring non-event message type: %s", msg.MessageType)
return nil, nil
}
// 解析事件payload
var event Event
if err := json.Unmarshal(msg.Payload, &event); err != nil {
return nil, fmt.Errorf("failed to unmarshal event: %v", err)
}
// 格式化设备名称(确保64字符)
event.DeviceName = common.FormatDeviceName(event.DeviceName)
// 验证并处理每个读数
for i := range event.Readings {
reading := &event.Readings[i]
// 确保读数的设备名称与事件一致
reading.DeviceName = event.DeviceName
}
return &event, nil
}
技术解析:
- 两层解析:先解析MessageEnvelope,再解析Event Payload
- 类型验证:只处理"event"类型的消息
- 数据标准化:设备名称格式化确保一致性
- 错误处理:完善的错误传播和日志记录
2.3 数据流向分析
2.3.1 数据采集流程
设备 → Device Service → Core Data → Application Service → 云端
↓ ↓
协议解析 数据存储
↓ ↓
数据转换 元数据管理
2.3.2 sfsEdgeStore集成点
sfsEdgeStore 通过 MQTT 订阅 EdgeX Foundry 的事件:
go
// mqtt/client.go 中的订阅配置
opts := mqtt.NewClientOptions()
opts.AddBroker(cfg.MQTTBroker)
opts.SetClientID(cfg.ClientID)
opts.SetCleanSession(false) // 持久会话
opts.SetAutoReconnect(true) // 自动重连
opts.SetMaxReconnectInterval(time.Minute * 5)
// 订阅主题
token := c.client.Subscribe(c.config.MQTTTopic, 1, c.messageHandler())
2.4 扩展开发指南
2.4.1 自定义Application Service
go
// 示例:自定义EdgeX Application Service
package main
import (
"github.com/edgexfoundry/app-functions-sdk-go/v2/pkg"
"github.com/edgexfoundry/app-functions-sdk-go/v2/pkg/interfaces"
)
func main() {
service := pkg.NewAppService("sfsedgestore-export")
// 设置函数管道
service.SetFunctionsPipeline(
convertToReading,
filterByDevice,
sendToSfsEdgeStore,
)
if err := service.MakeItRun(); err != nil {
service.LoggingClient().Errorf("MakeItRun returned error: %s", err.Error())
}
}
func convertToReading(ctx interfaces.AppFunctionContext, data interface{}) (bool, interface{}) {
// 转换数据格式
return true, data
}
func filterByDevice(ctx interfaces.AppFunctionContext, data interface{}) (bool, interface{}) {
// 按设备过滤
return true, data
}
func sendToSfsEdgeStore(ctx interfaces.AppFunctionContext, data interface{}) (bool, interface{}) {
// 发送到sfsEdgeStore
return true, nil
}
2.4.2 Device Service开发
go
// 示例:简单的Device Service框架
package main
import (
"github.com/edgexfoundry/device-sdk-go/v2/pkg/service"
"github.com/edgexfoundry/device-sdk-go/v2/pkg/models"
)
type SimpleDriver struct {
// 驱动状态
}
func (d *SimpleDriver) Initialize(lc models.LoggingClient) error {
// 初始化驱动
return nil
}
func (d *SimpleDriver) HandleReadCommands(deviceName string, protocols map[string]models.ProtocolProperties, reqs []models.CommandRequest) ([]*models.CommandValue, error) {
// 处理读命令
return nil, nil
}
func (d *SimpleDriver) HandleWriteCommands(deviceName string, protocols map[string]models.ProtocolProperties, reqs []models.CommandRequest, params []*models.CommandValue) error {
// 处理写命令
return nil
}
func (d *SimpleDriver) Stop(force bool) error {
// 停止驱动
return nil
}
func (d *SimpleDriver) AddDevice(deviceName string, protocols map[string]models.ProtocolProperties, adminState models.AdminState) error {
// 添加设备
return nil
}
func (d *SimpleDriver) UpdateDevice(deviceName string, protocols map[string]models.ProtocolProperties, adminState models.AdminState) error {
// 更新设备
return nil
}
func (d *SimpleDriver) RemoveDevice(deviceName string, protocols map[string]models.ProtocolProperties) error {
// 移除设备
return nil
}
func main() {
driver := &SimpleDriver{}
service.Startup("device-simple", driver)
}
2.5 最佳实践
2.5.1 消息队列配置
对于高吞吐量场景,建议:
go
// MQTT配置优化
opts.SetOrderMatters(false) // 不保证顺序,提高吞吐量
opts.SetWriteTimeout(30 * time.Second) // 写超时
opts.SetConnectTimeout(10 * time.Second) // 连接超时
opts.SetKeepAlive(60) // 心跳间隔
opts.SetPingTimeout(10 * time.Second) // Ping超时
2.5.2 错误处理策略
go
// 完整的错误处理示例
func (c *Client) messageHandler() mqtt.MessageHandler {
return func(client mqtt.Client, msg mqtt.Message) {
defer func() {
if r := recover(); r != nil {
log.Printf("Panic in message handler: %v", r)
// 记录堆栈
debug.PrintStack()
}
}()
// 处理消息
event, err := edgex.ProcessMessage(msg.Payload())
if err != nil {
log.Printf("Failed to process message: %v", err)
// 可以考虑将失败的消息存入死信队列
c.deadLetterQueue.Add(msg)
return
}
// 处理event...
}
}
2.6 本章小结
本章我们深入学习了:
- EdgeX Foundry 的四层架构设计
- MessageEnvelope 和 Event 的数据结构
- 消息处理流程和集成点
- 自定义 Application Service 和 Device Service 的开发
- 生产环境的最佳实践
下一章,我们将探讨 LevelDB 和 sfsDb 的底层原理。
本书版本 :1.0.0
最后更新 :2026-03-08
sfsEdgeStore - 让边缘数据存储更简单!🚀
技术栈 - Go语言、sfsDb与EdgeX Foundry。纯golang工业物联网边缘计算技术栈
项目地址 :GitHub
GitCode 镜像 :GitCode