SOME/IP-SD 服务发现故障
一、工程背景
SOME/IP 服务发现看起来只是 UDP 30490 上的 Offer 和 Find,但现场联调中经常出现"服务端已经启动,客户端就是找不到""抓到 Offer 但应用不上线""订阅一会儿后断掉"等问题。SOME/IP-SD 既依赖应用配置,也依赖 VLAN、组播、路由、TTL、实例 ID 和版本匹配。
服务发现排查要有层次:
text
二层链路
|
IP/VLAN/组播
|
UDP 30490
|
SD Entry
|
服务实例和版本
|
应用状态机
二、SOME/IP-SD 报文结构
SOME/IP-SD 是 SOME/IP 的特殊服务,常用:
text
Service ID: 0xFFFF
Method ID: 0x8100
UDP Port: 30490
SD payload 中主要有 Entry 和 Option:
| 结构 | 作用 |
|---|---|
| Entry | 描述 Offer、Find、Subscribe 等动作 |
| Option | 描述 IPv4/IPv6 Endpoint、Multicast、配置字符串 |
| TTL | 服务有效时间 |
| Service ID | 被发现的服务 |
| Instance ID | 服务实例 |
| Major/Minor Version | 接口版本 |
三、OfferService 和 FindService
服务端启动后周期发送 OfferService:
text
OfferService(service=0x1234, instance=0x0001, ttl=3s)
客户端可以主动发送 FindService:
text
FindService(service=0x1234, instance=0xffff)
如果服务端收到匹配 Find,会回复 Offer。客户端收到 Offer 后再建立 proxy 或订阅事件。
四、TTL 机制
TTL 表示服务声明有效时间。客户端如果在 TTL 到期前没有收到新的 Offer,就应该认为服务下线。
常见配置:
| 参数 | 示例 |
|---|---|
| Initial Offer Delay | 10-100ms |
| Repetition Base Delay | 100ms |
| Repetition Max | 3 |
| Main Offer Cycle | 1s |
| TTL | 3s |
如果 Offer 周期大于 TTL,就会出现服务周期性掉线。
五、抓包命令
bash
tcpdump -i eth0 -nn -vv -s 0 udp port 30490 -w sd.pcap
Wireshark 过滤:
text
someipsd
someipsd.entry.serviceid == 0x1234
someipsd.entry.ttl == 0
TTL 为 0 通常表示 StopOffer 或 StopSubscribe。
六、典型故障:服务找不到
现象 :客户端日志打印 service unavailable。
排查流程:
- 服务端本机抓包,确认是否发 Offer。
- 交换机镜像口抓包,确认 Offer 是否出端口。
- 客户端端口抓包,确认是否收到 Offer。
- 检查 VLAN ID、组播 MAC、IP 组播地址。
- 检查 Service ID/Instance ID/Major Version。
如果服务端发了,交换机没转发,优先查 VLAN/组播;如果客户端收到了但应用不上线,优先查实例和版本匹配。
七、典型故障:订阅后收不到事件
订阅链路:
text
Client -> SubscribeEventGroup
Server -> SubscribeAck / SubscribeNack
Server -> Event Notification
排查:
- 有没有 SubscribeEventGroup。
- 服务器是否返回 Ack。
- EventGroup ID 是否正确。
- Multicast endpoint 是否正确。
- 事件是否发到客户端加入的组播地址。
常见错误是客户端订阅了错误 EventGroup,服务端返回 Nack,但应用日志只显示"订阅失败"。
八、配置示例
示意配置:
json
{
"service": "VehicleState",
"service_id": "0x1234",
"instance_id": "0x0001",
"major_version": 1,
"minor_version": 0,
"sd_port": 30490,
"offer_cycle_ms": 1000,
"ttl_s": 3,
"eventgroups": [
{"id": "0x0001", "multicast": "239.10.0.1", "port": 30501}
]
}
配置评审时要确保客户端和服务端使用同一份接口定义。
九、排查表
| 现象 | 可能原因 | 验证 | 处理 |
|---|---|---|---|
| 完全无 SD 报文 | 服务未启动或接口绑定错 | tcpdump 30490 | 检查应用和接口 |
| 服务端有 Offer,客户端没有 | VLAN/组播/交换机过滤 | 多点抓包 | 修网络配置 |
| 客户端收到 Offer 但不上线 | Instance/Version 不匹配 | Wireshark Entry | 修接口配置 |
| 服务周期性掉线 | Offer 周期大于 TTL | 抓 Offer 间隔 | 调整 TTL/周期 |
| Subscribe Nack | EventGroup 错或权限拒绝 | 看 Ack/Nack | 修订阅配置 |
十、上线检查
- Offer/Find/Subscribe 抓包归档。
- TTL 和 Offer 周期经过长时间验证。
- 服务端重启后客户端能重新发现。
- 客户端断网恢复后能重新订阅。
- 多实例场景 Instance ID 不冲突。
- SD 组播地址在交换机端口正确转发。
十一、常见坑
- 只抓服务端,不抓客户端入口。
- TTL 配得太短,轻微丢包就服务下线。
- 服务端 StopOffer 没发,客户端保留旧状态。
- 客户端绑定错网卡,收到 Offer 的不是应用监听接口。
- 多 VLAN 下组播没有跨 VLAN 转发。
- 接口版本升级后 Major Version 不兼容。
十二、总结
SOME/IP-SD 故障排查的核心是"多点抓包 + 配置对齐 + 状态机理解"。看到 Offer 不等于服务可用,订阅成功也不等于事件一定能到。把 SD、订阅、事件和网络链路拆开看,定位会清晰很多。