大多数中间件 API 都会返回 SdvResult 对象。如果成功,此对象会包含预期的结果对象。如果失败,此对象会包含一个 SdvStatus 对象,表明出现了意外行为或错误情况,通常由错误代码(例如 Internal、Unavailable 或 DataLoss)标识。
本页可帮助您排查这些错误代码。
排查注册和创建失败问题
当您尝试创建或注册无效服务时,通常会出现注册和创建失败问题。
无法创建第二个服务
错误:
Internal 错误。
原因:
您尝试两次注册完全相同的服务软件包实例(名称和实例 ID)。
修复:
请勿尝试两次注册完全相同的服务软件包实例(名称和实例 ID)。
无法删除重复的服务软件包
错误:
Status(-3, EX_ILLEGAL_ARGUMENT)
原因:
您尝试删除不存在的重复服务软件包。
修复:
请勿尝试删除不存在的重复服务软件包。
无法检索用于发送消息的发布者实例
错误:
对 take_publisher() 的调用返回 none。
原因:
您从同一服务软件包实例中为同一变体调用了两次 take_publisher()。
修复:
请勿从同一服务软件包实例中为同一变体调用两次 take_publisher()。
无法创建订阅者、观察者、历史记录或 InstantReader
错误:
Unavailable 错误。
原因:
您尝试为不存在或已取消注册的发布者创建 Subscriber、Observer、History 或 InstantReader。
修复:
在尝试为发布者创建 Subscriber、Observer、History 或 InstantReader 之前,请验证发布者是否存在或已注册。
无法创建 RPC 客户端
错误:
Unavailable 错误
原因:
您尝试为不存在或未注册的服务器单元名称创建 RPC 客户端。
修复:
在创建 RPC 客户端之前,请验证服务器是否存在且已注册。
排查通信失败问题
服务执行完毕并开始与其他服务通信后,可能会发生通信失败。
排查发布者取消注册问题
当发布者取消注册时,如果其读取器仍处于活跃状态,则可能会发生错误。
订阅者的 read_next_messages() 返回空列表
错误:
read_next_messages() 成功,但返回空列表。
原因:
发布者取消注册时,其读取器处于活跃状态。
修复:
使用具有可用性流的订阅者或历史记录。如果可用性流的最后一条消息不可用,则发布者已取消注册,并且没有新消息。
观察者的 next() 返回内部错误
错误:
next() 返回 Internal 错误。
原因:
发布者取消注册时,其读取器处于活跃状态。
修复:
使用具有可用性流的订阅者或历史记录。如果可用性流的最后一条消息不可用,则发布者已消失,并且没有新消息。
历史记录的 read_from_history() 不返回新消息
错误:
read_from_history() 不返回任何新消息,仅返回旧消息。
原因:
发布者取消注册时,其读取器处于活跃状态。
修复:
使用具有可用性流的订阅者或历史记录。如果可用性流的最后一条消息不可用,则发布者已消失,并且没有新消息。
InstantReader read_latest_message() 返回内部错误
错误:
read_latest_message() 返回 Internal 错误。
原因:
发布者取消注册时,其读取器处于活跃状态。
修复:
使用具有可用性流的订阅者或历史记录。如果可用性流的最后一条消息不可用,则发布者已消失,并且没有新消息。
排查消息队列为空的问题
尝试从空消息队列中读取内容时,可能会发生错误。
订阅者的 read_next_messages() 返回空列表
错误:
read_next_messages() 成功返回空列表。
原因:
发布者处于活跃状态,但尚未发送消息。
修复:
使用具有可用性流的订阅者或历史记录。如果可用性流的最后一条消息可用,则发布者处于活跃状态,并且没有新消息。
观察者的 next() 返回内部错误
错误:
next() 返回 Internal 错误。
原因:
发布者处于活跃状态,但尚未发送消息。
修复:
使用具有可用性流的订阅者或历史记录。如果可用性流的最后一条消息可用,则发布者处于活跃状态,并且没有新消息。
历史记录的 read_from_history() 不返回新消息
错误:
read_from_history() 成功返回空列表。
原因:
发布者处于活跃状态,但尚未发送消息。
修复:
使用具有可用性流的订阅者或历史记录。如果可用性流的最后一条消息可用,则发布者处于活跃状态,并且没有新消息。
InstantReader read_latest_message() 返回内部错误
错误:
read_latest_message() 返回 Internal 错误。
原因:
发布者处于活跃状态,但尚未发送消息。
修复:
使用具有可用性流的订阅者或历史记录。如果可用性流的最后一条消息可用,则发布者处于活跃状态,并且没有新消息。
排查缓冲区溢出或数据丢失问题
当发布者发送消息的速度快于读取器使用消息的速度时,可能会发生错误。
溢出后订阅者的首次读取返回 DataLoss 错误
错误:
read_next_message() 返回 DataLoss 错误。
原因:
发布者发送消息的速度快于读取器使用消息的速度。
修复:
溢出后观察者的首次 next() 返回 DataLoss 错误
错误:
next() 返回 DataLoss 错误。
原因:
发布者发送消息的速度快于读取器使用消息的速度。
修复: 可能的修复方法包括:
发布者以较慢的速度发布。例如,您可能有一个变量,其中包含最新消息的时间戳。如果当前时间小于最新发布时间加上增量,则您无法发布消息。使用此机制,每个增量最多发布一条消息。
使用者使用
InstantRead对象,而不是观察者。InstantRead对象不会返回溢出错误,并且始终返回最后一条消息。如果您只关心最后一条消息,则可以使用InstantRead对象而不是观察者。使用者实现抽样。如果您的解决方案有一个发布者 (P1),其发布消息的速度快于观察者 (01) 读取消息的速度,您可以创建一个新的发布者 (P2) 和观察者 (02),以适应发布和读取速度的差异。
例如,假设 P1 每 10 毫秒发布一条消息,但 O1 每 100 毫秒只能读取一条消息,并丢弃其余九条消息。如需解决此差异,请创建一个解决方案,按照以下步骤操作:
- P1 将消息发布到 O2。
- O2 读取一条消息并丢弃九条消息。
- O2 将已读的一条消息发送给 P2。
- P2 将已读的一条消息发送给 O1。
- O1 每 10 秒读取一条消息。
以下示例代码展示了如何实现此抽样场景:
int discarded_message = 10; while (true) { message m = O2.read_message(); if discarded_message == 10 { discarded_message = 0; P2.publish(m); } else { discarded_message ++; } }
历史记录的读取不完整
错误:
消息在历史记录复制之前丢失。读取时没有直接错误通知。
原因:
发布者发送消息的速度快于读取器使用消息的速度。
修复:
InstantReader 仅读取最后一条消息
错误:
消息在历史记录复制之前丢失。读取时没有直接错误通知。
原因:
发布者发送消息的速度快于读取器使用消息的速度。
修复:
不适用
RPC 客户端调用方法,但该方法不可用
错误:
方法调用失败,并显示 Unavailable 错误。
原因:
SDV 不知道服务器名称,并返回 Unavailable。如果服务发现未返回有效的服务器名称,中间件会返回此错误。
修复:
启动一个服务软件包,该软件包为客户端要使用的给定接口定义了一个 server。
服务器端实现返回 SdvStatus 错误
错误:
服务器端实现返回一个包含 SdvStatus
错误(例如 SdvStatusCode::NotFound)的 SdvResult。该错误会传播回调用客户端。
原因:
SDV 以及客户端和服务器之间的通信系统按预期运行,但客户端发出的请求触发了服务器中的错误。
修复:
使用客户端发出有效请求,或修复服务器以成功响应这些请求。