針對 Azure 記憶體帳戶中的用戶端應用程式錯誤進行疑難解答
本文可協助您使用 Azure 監視器中的計量、用戶端記錄和資源記錄來調查用戶端應用程式錯誤。
診斷錯誤
您的應用程式使用者可能會通知您用戶端應用程式所回報的一些錯誤。 Azure 監視器也會記錄記憶體服務的不同回應類型(ResponseType 維度)計數,例如 NetworkError、ClientTimeoutError 或 AuthorizationError。 雖然 Azure 監視器只會記錄不同的錯誤類型計數,不過您還是可以藉由檢視伺服器端、用戶端與網路記錄來取得個別要求的詳細資料。 一般來說,儲存體服務所傳回的 HTTP 狀態碼會指示要求失敗的原因。
注意
請記住,您應該會看到一些間歇性錯誤。 例如,暫時性網路狀況或應用程式錯誤所造成的錯誤。
以下資源有助您了解儲存體相關狀態與錯誤碼:
用戶端收到 HTTP 403 (禁止) 訊息
如果您的用戶端應用程式擲回 HTTP 403 (禁止) 錯誤,則可能是因為用戶端在傳送儲存體要求時使用過期的共用存取簽章 (SAS) (但也可能是時鐘誤差、無效的金鑰與空白標頭引起)。
Storage Client Library for .NET 能讓您針對應用程式所執行的儲存體操作,收集與其相關的用戶端記錄資料。 如需詳細資訊,請參閱 使用 .NET 儲存體用戶端程式庫在用戶端記錄。
下列資料表以儲存體用戶端程式庫所產生的用戶端記錄為例,說明此問題的原因:
來源 | 詳細資訊 | 詳細資訊 | 用戶端要求 ID | 作業內容 |
---|---|---|---|---|
Microsoft Azure 儲存體 | 資訊 | 3 | 85d077ab-… | Starting operation with location Primary per location mode PrimaryOnly. |
Microsoft Azure 儲存體 | 資訊 | 3 | 85d077ab -… | Starting synchronous request to <https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests#Synchronous_request> |
Microsoft Azure 儲存體 | 資訊 | 3 | 85d077ab -… | Waiting for response. |
Microsoft Azure 儲存體 | 警告 | 2 | 85d077ab -… | Exception thrown while waiting for response: The remote server returned an error: (403) Forbidden. |
Microsoft Azure 儲存體 | 資訊 | 3 | 85d077ab -… | Response received. Status code = 403, Request ID = <Request ID>, Content-MD5 = , ETag = . |
Microsoft Azure 儲存體 | 警告 | 2 | 85d077ab -… | Exception thrown during the operation: The remote server returned an error: (403) Forbidden.. |
Microsoft Azure 儲存體 | 資訊 | 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 儲存體 | 資訊 | 3 | 85d077ab -… | The next location has been set to Primary, based on the location mode. |
Microsoft Azure 儲存體 | 錯誤 | 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早於預期到期。
SAS 金鑰中的版本參數 (例如
sv
=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 = "0x8D14D2DC63D059B". |
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,拒絕存取。
注意
當您需要為用戶端的 JavaScript 問題進行疑難排解時,可以使用 Internet Explorer 中的 F12 開發人員工具,追蹤瀏覽器與儲存體服務之間所交換的訊息。
之所以發生這些錯誤,是因為網頁瀏覽器實作了 同源原則 安全性限制,這會防止網頁呼叫與其來源網域不同之網域中的 API。
若要解決 JavaScript 問題,您可以為用戶端正在存取的記憶體服務設定跨原始來源資源分享 (CORS)。 如需詳細資訊,請參閱 Azure 儲存體服務的跨原始資源共用 (CORS) 支援。
下例程式碼範例顯示如何設定您的 Blob 服務,以讓 JavaScript 在 Contoso 網域中執行,進而存取位於您的 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 (Conflict 409),例如,來自
CreateIfNotExist
資源已經存在的作業。 - ConditionNotMet (Not Modified 304),例如,來自條件式作業,例如當用戶端傳送
ETag
值和 HTTPIf-None-Match
標頭時,只有在上次作業之後已更新映射時,才要求影像。
您可以在常見的 REST API 錯誤碼頁面找到儲存體服務傳回的常見 REST API 錯誤碼清單。
另請參閱
- 監視 Azure Blob 儲存體
- 監視 Azure 檔案
- 監視 Azure 佇列儲存體
- 監視 Azure 資料表儲存體
- 針對效能問題進行疑難排解
- 針對可用性問題進行疑難排解
- 監視、診斷及疑難排解 Azure 儲存體的問題
與我們連絡,以取得說明
如果您有問題或需要相關協助,請建立支援要求,或詢問 Azure community 支援。 您也可以向 Azure 意見反應社群提交產品意見反應。