Skip to content

OPC UA 故障处理案例

案例一:证书验证失败,连接被拒绝

故障现象

客户端连接 OPC UA 服务器时报错:BadCertificateUntrusted,无法建立安全连接。

排查过程

python
# 错误日志
# asyncua.ua.uaerrors._auto.BadCertificateUntrusted

# 原因:服务器未信任客户端证书
# OPC UA 使用双向证书认证,服务器需要显式信任客户端证书

解决方案

bash
# 1. 将客户端证书复制到服务器的信任列表
cp client_cert.pem /etc/opcua/server/pki/trusted/certs/

# 2. 或在服务器代码中自动信任(仅测试环境)
server.set_security_IDs(["Anonymous", "Basic256Sha256"])

# 3. 生产环境:使用 CA 签发的证书,服务器信任 CA
# 将 CA 证书添加到服务器信任的 CA 列表
cp ca_cert.pem /etc/opcua/server/pki/trusted/issuers/

案例二:订阅数据延迟高

故障现象

OPC UA 订阅的数据更新延迟达到 5-10 秒,而配置的发布间隔为 1 秒。

排查过程

python
# 检查订阅状态
subscription_status = await client.get_subscription_status(sub_id)
print(f"Publishing interval: {subscription_status.RevisedPublishingInterval}")
print(f"Lifetime count: {subscription_status.RevisedLifetimeCount}")
print(f"Max keepalive: {subscription_status.RevisedMaxKeepAliveCount}")

# 发现 RevisedPublishingInterval = 5000ms
# 服务器将 1000ms 修订为 5000ms(服务器最小间隔限制)

# 检查服务器配置
server_caps = await client.get_server_capabilities()
print(f"Min publishing interval: {server_caps.MinSupportedSampleRate}")

解决方案

python
# 服务器端:降低最小发布间隔
server.iserver.aspace.set_attribute_value(
    ua.NodeId(ua.ObjectIds.Server_ServerCapabilities_MinSupportedSampleRate),
    ua.DataValue(ua.Variant(100.0, ua.VariantType.Double))  # 100ms
)

# 客户端:检查修订后的实际间隔
sub = await client.create_subscription(period=1000, handler=handler)
print(f"Requested: 1000ms, Revised: {sub.parameters.RevisedPublishingInterval}ms")

案例三:大量节点读取超时

故障现象

读取 5000 个节点时,请求超时,服务器返回 BadTimeout

解决方案

python
# 分批读取,每批不超过 500 个节点
async def read_nodes_in_batches(client, node_ids, batch_size=500):
    all_values = []
    for i in range(0, len(node_ids), batch_size):
        batch = node_ids[i:i+batch_size]
        nodes = [client.get_node(nid) for nid in batch]
        values = await client.read_values(nodes)
        all_values.extend(values)
        await asyncio.sleep(0.1)  # 避免服务器过载
    return all_values

常见错误码

错误码含义处理方法
BadNodeIdUnknown节点 ID 不存在检查节点 ID 是否正确
BadAttributeIdInvalid属性不支持检查节点类型和属性
BadNotReadable节点不可读检查访问权限
BadNotWritable节点不可写检查节点 Writable 属性
BadUserAccessDenied用户无权限检查用户角色配置
BadCertificateUntrusted证书不受信任添加证书到信任列表
BadSecureChannelClosed安全通道关闭重新连接
BadSessionClosed会话已关闭重新建立会话
BadTooManySubscriptions订阅数超限减少订阅数或增加服务器限制
BadTimeout请求超时增大超时时间或减小批次大小

调试工具

bash
# 使用 UaExpert 连接并浏览地址空间
# 1. 下载 UaExpert(免费)
# 2. 添加服务器:opc.tcp://server:4840
# 3. 浏览节点树,查看值和属性

# 命令行测试
python3 -c "
import asyncio
from asyncua import Client

async def test():
    async with Client('opc.tcp://server:4840') as client:
        root = client.get_root_node()
        print('Root node:', root)
        children = await root.get_children()
        for child in children:
            print(' -', await child.read_browse_name())

asyncio.run(test())
"

褚成志的IoT笔记