排解中介軟體 API 失敗問題

大多數中介軟體 API 都會傳回 SdvResult 物件。成功時,這個物件會包含預期的結果物件。如果失敗,這個物件會包含 SdvStatus 物件,指出非預期的行為或錯誤情況,通常會以錯誤代碼 (例如 InternalUnavailableDataLoss) 識別。

本頁面可協助您排解這些錯誤代碼。

排解註冊和建立失敗問題

嘗試建立或註冊無效服務時,通常會發生註冊和建立失敗的情況。

無法建立第二項服務

錯誤:

發生 Internal 個錯誤。

原因:

您嘗試註冊完全相同的服務套裝組合執行個體 (名稱和執行個體 ID) 兩次。

修正:

請勿嘗試註冊完全相同的服務套裝組合執行個體 (名稱和執行個體 ID) 兩次。

無法刪除重複的服務套裝組合

錯誤:

Status(-3, EX_ILLEGAL_ARGUMENT)

原因:

您嘗試刪除不存在的重複服務套裝組合。

修正:

請勿嘗試刪除不存在的重複服務套裝組合。

無法擷取發布者執行個體來傳送訊息

錯誤:

呼叫 take_publisher() 會傳回 none

原因:

您從同一個服務套件例項,針對同一個變體呼叫 take_publisher() 兩次。

修正:

請勿從同一個服務套件執行個體,為相同變體呼叫 take_publisher() 兩次。

無法建立 Subscriber、Observer、History 或 InstantReader

錯誤:

發生 Unavailable 個錯誤。

原因:

您嘗試為不存在或已取消註冊的發布商建立 SubscriberObserverHistoryInstantReader

修正:

請先確認發布者存在或已註冊,再嘗試為發布者建立 SubscriberObserverHistoryInstantReader

無法建立 RPC 用戶端

錯誤:

Unavailable 個錯誤

原因:

您嘗試為不存在或未註冊的伺服器單元名稱建立 RPC 用戶端。

修正:

建立 RPC 用戶端前,請先確認伺服器存在且已註冊。

排解通訊失敗問題

服務執行完畢並開始與其他服務通訊後,可能會發生通訊失敗的情況。

排解發布商取消註冊問題

如果發布者在讀取者仍處於活動狀態時取消註冊,就可能發生錯誤。

訂閱者的 read_next_messages() 會傳回空白清單

錯誤:

read_next_messages() 成功,但傳回空白清單。

原因:

發布者取消註冊,但讀者仍處於有效狀態。

修正:

使用訂閱者或記錄,並搭配可用性串流。如果可用性串流的最後一則訊息無法使用,發布者就會取消註冊,且不會有新訊息。

觀察者的 next() 會傳回內部錯誤

錯誤:

next() 會傳回 Internal 錯誤。

原因:

發布者取消註冊,但讀者仍處於有效狀態。

修正:

使用訂閱者或具有可用性串流的記錄。如果無法取得可用性串流的最後一則訊息,表示發布者已離開,且沒有新訊息。

History 的 read_from_history() 不會傳回新訊息

錯誤:

read_from_history() 不會傳回任何新訊息,只會傳回舊訊息。

原因:

發布者取消註冊,但讀者仍處於有效狀態。

修正:

使用訂閱者或具有可用性串流的記錄。如果無法取得可用性串流的最後一則訊息,表示發布者已離開,且沒有新訊息。

InstantReader read_latest_message() 傳回內部錯誤

錯誤:

read_latest_message() 會傳回 Internal 錯誤。

原因:

發布者取消註冊,但讀者仍處於有效狀態。

修正:

使用訂閱者或具有可用性串流的記錄。如果無法取得可用性串流的最後一則訊息,表示發布者已離開,且沒有新訊息。

排解訊息佇列空白問題

嘗試從空白訊息佇列讀取資料時,可能會發生錯誤。

訂閱者的 read_next_messages() 傳回空白清單

錯誤:

read_next_messages() 成功傳回空白清單。

原因:

發布者處於啟用狀態,但尚未傳送訊息。

修正:

使用訂閱者或記錄檔 (附有供應情形串流)。如果供應情形串流的最後一則訊息可用,表示發布者處於活動狀態,且沒有新訊息。

觀察者的 next() 會傳回內部錯誤

錯誤:

next() 會傳回 Internal 錯誤。

原因:

發布者處於啟用狀態,但尚未傳送訊息。

修正:

使用訂閱者或記錄檔 (附有供應情形串流)。如果供應情形串流的最後一則訊息可用,表示發布者處於活動狀態,且沒有新訊息。

History 的 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 毫秒只能讀取一則訊息,並捨棄其餘九則訊息。如要解決差異問題,請按照下列步驟建立解決方案:

    1. P1 會將訊息發布至 O2。
    2. O2 讀取一則訊息,並捨棄九則訊息。
    3. O2 會將讀取訊息傳送給 P2。
    4. P2 將一則已讀訊息傳送給 O1。
    5. O1 每十秒讀取一則訊息。

    下列程式碼範例說明如何實作這個取樣情境:

    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 錯誤的 SdvResult,例如 SdvStatusCode::NotFound。錯誤會傳播回呼叫端用戶端。

原因:

SDV 和用戶端與伺服器之間的通訊系統運作正常,但用戶端發出的要求在伺服器中觸發錯誤。

修正:

請使用用戶端提出有效要求,或修正伺服器,確保能成功回應這些要求。