4. OPC UA 与工业通信:架构、模型与安全机制
OPC UA(OPC Unified Architecture,统一架构)是工业 4.0 时代最核心的通信标准,它解决了传统 OPC Classic(如 OPC DA、OPC HDA)对 Windows 平台和 DCOM 协议的强依赖问题。本章将深入剖析 OPC UA 的层次化架构、信息模型、客户端/服务器交互模式以及纵深安全机制,为后续的厂务数据采集实战打下坚实的理论基础。
4.1 OPC UA 架构分层与核心组件
OPC UA 采用面向服务的架构(SOA),将通信栈、信息模型与应用层解耦。其核心架构分为传输层、通信层、服务接口层和信息模型层。
架构设计要点: OPC UA 不绑定任何特定的传输协议,支持二进制 TCP(UA Binary)和 Web 服务(SOAP/HTTP)两种传输映射,兼顾了实时性与跨平台互操作性。
4.2 数据模型与地址空间
OPC UA 的核心创新在于其面向对象的信息模型。地址空间(AddressSpace)是 OPC UA 服务器的“数据字典”,所有可访问的数据和结构都以节点(Node)的形式组织在地址空间中。
4.2.1 节点与引用
- 节点(Node): 地址空间的基本单元。每个节点有唯一的 NodeId 和属性集合。
- 引用(Reference): 节点之间的有向连接,用于构建层次结构(如对象包含变量)或非层次关系(如类型继承)。
4.2.2 核心节点类型
| 节点类型 | 描述 | 典型用途 |
|---|---|---|
| Object | 代表物理或逻辑实体 | 电机、传感器、控制器 |
| Variable | 存储数值或状态 | 温度值、转速、开关状态 |
| Method | 可调用的函数 | 启动设备、复位报警 |
| ObjectType | 对象的模板/类定义 | 定义“水泵”类型应包含哪些变量和方法 |
| DataType | 定义数据结构 | 模拟量类型、结构体类型 |
实战提示: 在厂务数据采集中,我们通常通过浏览地址空间来发现设备。例如,一个“空调机组”对象下会包含“送风温度”、“回风湿度”等变量节点,以及“启动/停止”方法节点。
4.3 客户端/服务器模式
OPC UA 采用经典的 C/S 架构。服务器负责维护地址空间并提供数据;客户端负责发起连接、浏览节点、读写数据或订阅事件。
4.3.1 会话建立流程
- 发现(Discovery): 客户端通过 Discovery Endpoint 获取服务器支持的协议列表。
- 创建安全通道(Secure Channel): 基于 TLS 或 UA Binary 协议协商加密算法和密钥。
- 创建会话(Session): 客户端提供身份认证信息(如用户名/密码、证书),服务器验证后建立会话。
- 数据交互: 客户端通过服务接口(Read/Write/Subscribe)与服务器交互。
- 关闭会话: 客户端主动关闭或超时断开。
4.3.2 订阅机制
订阅(Subscription)是 OPC UA 实现高效数据采集的关键。客户端创建订阅后,服务器按设定的采样间隔(Sampling Interval)检测变量变化,并在发布间隔(Publishing Interval)内将变化的数据打包发送给客户端,极大减少了网络开销。
常见误区: 不要将 OPC UA 的订阅与 MQTT 的发布/订阅混淆。OPC UA 订阅是服务器主动推送变化数据给客户端,而 MQTT 是 Broker 模式。在厂务数据采集中,OPC UA 更适合实时性要求高的 PLC 数据采集。
4.4 安全机制
OPC UA 将安全内建于协议栈,而非依赖外部网络环境。其安全模型涵盖三个核心层面:
| 安全层面 | 机制 | 说明 |
|---|---|---|
| 传输安全 | TLS 1.2/1.3、UA Secure Conversation | 加密通信通道,防止窃听和中间人攻击 |
| 身份认证 | X.509 证书、用户名/密码、 | 验证客户端和服务器的身份合法性 |
| 授权与审计 | 角色权限、访问控制列表(ACL) | 控制用户对特定节点(如写操作、方法调用)的访问权限 |
4.4.1 安全策略(Security Policy)
OPC UA 定义了多种安全策略,用于协商加密算法和密钥长度。常见策略包括:
- None: 无加密,仅用于测试或隔离网络。
- Basic128Rsa15: 使用 128 位 AES 加密,RSA 密钥长度为 1024 位。
- Basic256: 使用 256 位 AES 加密,安全性更高。
- Aes128_Sha256_RsaOaep: 现代推荐策略,结合 AES-128 和 SHA-256 签名。
生产环境建议: 在厂务数据采集项目中,务必启用至少 Basic128Rsa15 以上的安全策略,并配置有效的 X.509 证书。避免在生产网络中使用“None”策略,否则数据将以明文传输,存在严重安全隐患。
4.4.2 证书管理
OPC UA 使用证书进行双向认证。服务器和客户端各自持有证书,并在建立安全通道时交换。常见的证书管理流程包括:
- 生成自签名证书或由企业 CA 签发证书。
- 将服务器证书导入客户端的信任列表(Trust List)。
- 将客户端证书导入服务器的信任列表。
- 配置证书吊销列表(CRL)以管理过期或泄露的证书。
4.5 实战代码示例:使用 Python 连接 OPC UA 服务器
以下示例使用 opcua-asyncio 库(推荐用于异步编程)连接一个本地 OPC UA 服务器,并读取一个变量的值。
import asyncio
from opcua import Client, ua
async def read_opcua_variable():
# 1. 创建客户端实例,指定服务器端点URL
# 安全模式选择 SignAndEncrypt,策略 Basic256
client = Client(
url="opc.tcp://localhost:4840/freeopcua/server/",
security_mode=ua.SecurityMode.SignAndEncrypt,
security_policy=ua.SecurityPolicy.Basic256
)
# 2. 加载客户端证书(用于安全连接)
client.load_client_certificate("client_cert.der")
client.load_private_key("client_key.pem")
try:
# 3. 连接到服务器
await client.connect()
print("连接成功!")
# 4. 获取根节点并浏览地址空间
root = client.get_root_node()
print(f"根节点: {root}")
# 5. 读取指定变量(NodeId 为 "ns=2;i=1234")
var_node = client.get_node("ns=2;i=1234")
data_value = await var_node.read_value()
print(f"变量值: {data_value}")
# 6. 创建订阅,每100ms采样一次
subscription = await client.create_subscription(100, handler)
handle = await subscription.subscribe_data_change(var_node)
# 保持连接一段时间以接收数据
await asyncio.sleep(10)
# 7. 清理
await subscription.delete()
await client.disconnect()
print("断开连接。")
except Exception as e:
print(f"发生错误: {e}")
# 定义数据变化回调处理器
class SubHandler:
async def datachange_notification(self, node, val, data):
print(f"数据变化: {node} -> {val}")
handler = SubHandler()
# 运行异步主函数
asyncio.run(read_opcua_variable())
代码说明: 上述代码展示了完整的 OPC UA 客户端生命周期:连接、浏览、读取、订阅和断开。在实际厂务项目中,建议将连接参数(URL、证书路径、安全策略)配置在外部配置文件中,便于维护和切换环境。