分享方式:


針對 Azure 記憶體帳戶中的用戶端應用程式錯誤進行疑難解答

本文可協助您在 Azure 監視器中使用計量、 用戶端記錄和資源記錄來調查用戶端應用程式錯誤。

診斷錯誤

應用程式的使用者可能會通知您用戶端應用程式所報告的錯誤。 Azure 監視器也會記錄不同回應類型的計數 (從記憶體服務) 的 ResponseType 維度,例如 NetworkErrorClientTimeoutErrorAuthorizationError。 雖然 Azure 監視器只會記錄不同錯誤類型的計數,但您可以檢查伺服器端、用戶端和網路記錄,以取得個別要求的詳細數據。 通常,記憶體服務所傳回的 HTTP 狀態代碼會指出要求失敗的原因。

注意事項

請記住,您應該會看到一些間歇性錯誤。 例如,由於暫時性網路狀況或應用程式錯誤所造成的錯誤。

下列資源有助於瞭解記憶體相關的狀態和錯誤碼:

用戶端收到 HTTP 403 (禁止) 訊息

如果您的用戶端應用程式擲回 HTTP 403 (禁止) 錯誤,可能是因為用戶端在傳送記憶體要求 (時使用過期的共用存取簽章 (SAS) ,但其他可能的原因包括時鐘誤差、密鑰無效,以及) 空白標頭。

適用於 .NET 的記憶體用戶端連結庫可讓您收集與應用程式所執行之記憶體作業相關的客戶端記錄數據。 如需詳細資訊,請參閱使用 .NET 記憶體客戶端連結庫進行客戶端記錄

下表顯示記憶體用戶端連結庫所產生之客戶端記錄檔的範例,說明發生此問題:

來源 冗長 冗長 用戶端要求標識碼 作業文字
Microsoft.Azure.Storage Information 3 85d077ab-... Starting operation with location Primary per location mode PrimaryOnly.
Microsoft.Azure.Storage Information 3 85d077ab -... Starting synchronous request to <https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests#Synchronous_request>
Microsoft.Azure.Storage Information 3 85d077ab -... Waiting for response.
Microsoft.Azure.Storage 警告 2 85d077ab -... Exception thrown while waiting for response: The remote server returned an error: (403) Forbidden.
Microsoft.Azure.Storage Information 3 85d077ab -... Response received. Status code = 403, Request ID = <Request ID>, Content-MD5 = , ETag = .
Microsoft.Azure.Storage 警告 2 85d077ab -... Exception thrown during the operation: The remote server returned an error: (403) Forbidden..
Microsoft.Azure.Storage Information 3 85d077ab -... Checking if the operation should be retried. Retry count = 0, HTTP status code = 403, Exception = The remote server returned an error: (403) Forbidden..
Microsoft.Azure.Storage Information 3 85d077ab -... The next location has been set to Primary, based on the location mode.
Microsoft.Azure.Storage 錯誤 1 85d077ab -... Retry policy did not allow for a retry. Failing with The remote server returned an error: (403) Forbidden.

在此案例中,您應該在用戶端將令牌傳送至伺服器之前,調查 SAS 令牌到期的原因:

  • 一般而言,您不應該在建立 SAS 以讓用戶端立即使用時設定開始時間。 如果使用目前時間產生SAS的主機與記憶體服務之間有小的時鐘差異,則記憶體服務可能會收到尚未有效的SAS。

  • 請勿在 SAS 上設定非常短的到期時間。 同樣地,產生SAS的主機與記憶體服務之間的小時鐘差異,可能會導致SAS比預期的更早到期。

  • 例如 sv,SAS 金鑰中的版本參數 (=2015-04-05) 符合您使用的記憶體用戶端連結庫版本嗎? 建議您一律使用最新版的記憶體用戶端連結庫。

  • 如果您重新產生記憶體存取金鑰,任何現有的 SAS 令牌可能會失效。 如果您產生 SAS 令牌,且用戶端應用程式快取的到期時間很長,就可能會發生此問題。

如果您使用記憶體用戶端連結庫來產生SAS令牌,則可以輕鬆地建置有效的令牌。 不過,如果您使用記憶體 REST API 並手動建構 SAS 令牌,請參閱使用共用存 取簽章委派存取權。

用戶端收到 HTTP 404 (找不到) 訊息

如果用戶端應用程式從伺服器收到 HTTP 404 (找不到) 訊息,這表示客戶端嘗試使用 (的物件,例如實體、數據表、Blob、容器或佇列) 不存在於記憶體服務中。 有一些可能的原因,例如:

  • 用戶端或其他進程先前已刪除物件。

  • 共用存取簽章 (SAS) 授權問題。

  • 用戶端 JavaScript 程式代碼沒有存取物件的許可權。

  • 網路失敗。

用戶端或其他進程先前已刪除物件

在客戶端嘗試讀取、更新或刪除記憶體服務中數據的案例中,很容易在記憶體資源記錄中識別先前從記憶體服務刪除有問題的對象的作業。 記錄數據通常會顯示另一個用戶或進程已刪除物件。 伺服器端 (Azure 監視器記錄) 顯示用戶端刪除對象的時機。

在用戶端嘗試插入物件的案例中,如果用戶端正在建立新物件,可能無法立即看出這會導致 HTTP 404 (找不到) 回應的原因。 不過,如果用戶端正在建立 Blob,它必須能夠找到 Blob 容器。 如果用戶端正在建立訊息,它必須能夠找到佇列。 如果用戶端正在新增數據列,它必須能夠找到數據表。

您可以使用記憶體用戶端連結庫的用戶端記錄,進一步瞭解用戶端何時將特定要求傳送至記憶體服務。

記憶體客戶端連結庫所產生的下列用戶端記錄說明用戶端找不到所建立 Blob 的容器時發生的問題。 此記錄檔包含下列記憶體作業的詳細資料:

要求識別碼 作業
07b26a5d-... DeleteIfExists 刪除 Blob 容器的方法。 這項作業包含 HEAD 要求,以檢查容器是否存在。
e2d06d78... CreateIfNotExists 方法來建立 Blob 容器。 此作業包含 HEAD 檢查容器是否存在的要求。 會 HEAD 傳回 404 訊息,但會繼續。
de8b1c3c-... UploadFromStream 方法來建立 Blob。 要求 PUT 失敗,並顯示 404 訊息

記錄專案:

要求識別碼 作業文字
07b26a5d-... Starting synchronous request to https://domemaildist.blob.core.windows.net/azuremmblobcontainer.
07b26a5d-... StringToSign = HEAD............x-ms-client-request-id:07b26a5d-....x-ms-date:Tue, 03 Jun 2014 10:33:11 GMT.x-ms-version:2014-02-14./domemaildist/azuremmblobcontainer.restype:container.
07b26a5d-... Waiting for response.
07b26a5d-... Response received. Status code = 200, Request ID = eeead849-...Content-MD5 = , ETag = &quot;0x8D14D2DC63D059B&quot;.
07b26a5d-... Response headers were processed successfully, proceeding with the rest of the operation.
07b26a5d-... Downloading response body.
07b26a5d-... Operation completed successfully.
07b26a5d-... Starting synchronous request to https://domemaildist.blob.core.windows.net/azuremmblobcontainer.
07b26a5d-... StringToSign = DELETE............x-ms-client-request-id:07b26a5d-....x-ms-date:Tue, 03 Jun 2014 10:33:12 GMT.x-ms-version:2014-02-14./domemaildist/azuremmblobcontainer.restype:container.
07b26a5d-... Waiting for response.
07b26a5d-... Response received. Status code = 202, Request ID = 6ab2a4cf-..., Content-MD5 = , ETag = .
07b26a5d-... Response headers were processed successfully, proceeding with the rest of the operation.
07b26a5d-... Downloading response body.
07b26a5d-... Operation completed successfully.
e2d06d78-... Starting asynchronous request to https://domemaildist.blob.core.windows.net/azuremmblobcontainer.
e2d06d78-... StringToSign = HEAD............x-ms-client-request-id:e2d06d78-....x-ms-date:Tue, 03 Jun 2014 10:33:12 GMT.x-ms-version:2014-02-14./domemaildist/azuremmblobcontainer.restype:container.
e2d06d78-... Waiting for response.
de8b1c3c-... Starting synchronous request to https://domemaildist.blob.core.windows.net/azuremmblobcontainer/blobCreated.txt.
de8b1c3c-... StringToSign = PUT...64.qCmF+TQLPhq/YYK50mP9ZQ==........x-ms-blob-type:BlockBlob.x-ms-client-request-id:de8b1c3c-....x-ms-date:Tue, 03 Jun 2014 10:33:12 GMT.x-ms-version:2014-02-14./domemaildist/azuremmblobcontainer/blobCreated.txt.
de8b1c3c-... Preparing to write request data.
e2d06d78-... Exception thrown while waiting for response: The remote server returned an error: (404) Not Found..
e2d06d78-... Response received. Status code = 404, Request ID = 353ae3bc-..., Content-MD5 = , ETag = .
e2d06d78-... Response headers were processed successfully, proceeding with the rest of the operation.
e2d06d78-... Downloading response body.
e2d06d78-... Operation completed successfully.
e2d06d78-... Starting asynchronous request to https://domemaildist.blob.core.windows.net/azuremmblobcontainer.
e2d06d78-... StringToSign = PUT...0.........x-ms-client-request-id:e2d06d78-....x-ms-date:Tue, 03 Jun 2014 10:33:12 GMT.x-ms-version:2014-02-14./domemaildist/azuremmblobcontainer.restype:container.
e2d06d78-... Waiting for response.
de8b1c3c-... Writing request data.
de8b1c3c-... Waiting for response.
e2d06d78-... Exception thrown while waiting for response: The remote server returned an error: (409) Conflict..
e2d06d78-... Response received. Status code = 409, Request ID = c27da20e-..., Content-MD5 = , ETag = .
e2d06d78-... Downloading error response body.
de8b1c3c-... Exception thrown while waiting for response: The remote server returned an error: (404) Not Found..
de8b1c3c-... Response received. Status code = 404, Request ID = 0eaeab3e-..., Content-MD5 = , ETag = .
de8b1c3c-... Exception thrown during the operation: The remote server returned an error: (404) Not Found..
de8b1c3c-... Retry policy did not allow for a retry. Failing with The remote server returned an error: (404) Not Found..
e2d06d78-... Retry policy did not allow for a retry. Failing with The remote server returned an error: (409) Conflict..

在此範例中,記錄顯示用戶端正在交錯來自 CreateIfNotExists 方法的要求, (要求標識碼 e2d06d78...) 與來自 UploadFromStream de8b1c3c (方法的要求-...) 。之所以發生這種交錯,是因為用戶端應用程式會以異步方式叫用這些方法。 修改用戶端中的異步程序代碼,以確保在嘗試將任何數據上傳至該容器中的 Blob 之前,先建立容器。 在理想情況下,您應該事先建立所有容器。

共用存取簽章 (SAS) 授權問題

如果用戶端應用程式嘗試使用未包含作業必要許可權的 SAS 金鑰,記憶體服務會傳回 HTTP 404 (找不到) 訊息給用戶端。 同時,在 Azure 監視器計量中,您也會看到 ResponseType 維度的 AuthorizationError

調查用戶端應用程式為何嘗試執行未獲授與許可權的作業。

用戶端 JavaScript 程式代碼沒有存取物件的許可權

如果您使用 JavaScript 用戶端,且記憶體服務正在傳回 HTTP 404 訊息,請在瀏覽器中檢查下列 JavaScript 錯誤:

SEC7120:在 Access-Control-Allow-Origin 標頭中找不到原始 http://localhost:56309 來源。
SCRIPT7002:XMLHttpRequest:網路錯誤0x80070005,存取遭到拒絕。

注意事項

您可以使用 Internet Explorer 中的 F12 開發人員工具,在針對用戶端 JavaScript 問題進行疑難解答時,追蹤瀏覽器與記憶體服務之間交換的訊息。

之所以會發生這些錯誤,是因為網頁瀏覽器會實作 相同的原始 原則安全性限制,以防止網頁從頁面來源的網域呼叫不同網域中的 API。

若要解決 JavaScript 問題,您可以為用戶端所存取的記憶體服務設定跨原始來源資源分享 (CORS) 。 如需詳細資訊,請 參閱跨原始來源資源分享 (CORS) Azure 記憶體服務的支援

下列程式代碼範例示範如何設定 Blob 服務,以允許在 Contoso 網域中執行的 JavaScript 存取 Blob 記憶體服務中的 Blob:

var connectionString = Constants.connectionString;

 BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);

 BlobServiceProperties sp = blobServiceClient.GetProperties();

 // Set the service properties.
 sp.DefaultServiceVersion = "2013-08-15";
 BlobCorsRule bcr = new BlobCorsRule();
 bcr.AllowedHeaders = "*";

 bcr.AllowedMethods = "GET,POST";
 bcr.AllowedOrigins = "http://www.contoso.com";
 bcr.ExposedHeaders = "x-ms-*";
 bcr.MaxAgeInSeconds = 5;
 sp.Cors.Clear();
 sp.Cors.Add(bcr);
 blobServiceClient.SetProperties(sp);

網路失敗

在某些情況下,遺失的網路封包可能會導致記憶體服務將 HTTP 404 訊息傳回給用戶端。 例如,當您的用戶端應用程式從資料表服務刪除實體時,您會看到用戶端擲回記憶體例外狀況,其中報告來自數據表服務的「HTTP 404 (找不到) 」狀態消息。 當您調查資料表記憶體服務中的數據表時,您會看到服務已依照要求刪除實體。

用戶端中的例外狀況詳細數據包括數據表服務為要求指派的要求標識符 (7e84f12d...) :您可以使用此資訊,在 描述如何驗證記錄專案的字段 中搜尋,以在 Azure 監視器的記憶體資源記錄中找出要求詳細數據。 您也可以使用計量來識別發生這類失敗的時間,然後根據度量記錄此錯誤的時間來搜尋記錄檔。 此記錄項目顯示刪除失敗,並出現「HTTP (404) 用戶端其他錯誤」狀態消息。 相同的記錄專案也包含客戶端在 client-request-id 數據行 813ea74f...) (產生的要求識別碼。

伺服器端記錄檔也包含另一個具有相同 client-request-id 值的專案, (813ea74f...) ,以成功刪除相同實體和來自相同客戶端的作業。 此成功的刪除作業會在失敗的刪除要求發生不久之前發生。

此案例最可能的原因是用戶端已將實體的刪除要求傳送至數據表服務,該要求成功,但未收到來自伺服器 (可能因為暫時的網路問題) 。 用戶端接著會使用相同的 client-request-id) 自動重試作業 (,而此重試失敗,因為實體已刪除。

如果這個問題經常發生,您應該調查客戶端為何無法從數據表服務收到通知。 如果問題是間歇性的,您應該捕捉「HTTP (404) 找不到」錯誤,並將其記錄在用戶端中,但允許客戶端繼續。

用戶端收到 HTTP 409 (衝突) 訊息

當用戶端刪除 Blob 容器、數據表或佇列時,在名稱再次變成可用之前會有一小段時間。 如果用戶端應用程式中的程式代碼刪除,然後使用相同的名稱立即重新建立 Blob 容器, CreateIfNotExists 此方法最終會失敗,並出現 HTTP 409 (衝突) 錯誤。

如果刪除/重新建立模式很常見,用戶端應用程式應該在每次建立新容器時使用唯一的容器名稱。

度量顯示低 PercentSuccess 或分析記錄專案具有交易狀態為 ClientOtherErrors 的作業

等於 Success 值的 ResponseType 維度會根據其 HTTP 狀態代碼擷取成功的作業百分比。 狀態代碼為 2XX 的作業會計算為成功,而狀態代碼為 3XX、4XX 和 5XX 範圍的作業則會計算為不成功,並降低成功計量值。 在記憶體資源記錄中,這些作業會以 ClientOtherError 的交易狀態記錄。

這些作業已順利完成,因此不會影響其他計量,例如可用性。 一些成功執行但可能會導致 HTTP 狀態代碼失敗的作業範例包括:

  • ResourceNotFound (找不到 404) ,例如,從 GET 要求到不存在的 Blob。
  • ResourceAlreadyExists (衝突 409) ,例如,來自 CreateIfNotExist 已存在資源的作業。
  • ConditionNotMet (未修改 304) ,例如,從條件式作業,例如當用戶端傳送 ETag 值和 HTTP If-None-Match 標頭來要求映像自上次作業以來已更新時。

您可以在常見 REST API 錯誤碼頁面上找到記憶體服務傳回的常見 REST API 錯誤碼清單。

另請參閱

與我們連絡,以取得說明

如果您有問題或需要相關協助,請建立支援要求,或詢問 Azure community 支援。 您也可以將產品意見反應提交給 Azure 意應見反社群