Felsöka klientprogramfel i Azure Storage-konton

Den här artikeln hjälper dig att undersöka klientprogramfel med hjälp av mått, loggar på klientsidan och resursloggar i Azure Monitor.

Diagnostisera fel

Användare av ditt program kan meddela dig om fel som rapporterats av klientprogrammet. Azure Monitor registrerar även antalet olika svarstyper (ResponseType-dimensioner ) från dina lagringstjänster, till exempel NetworkError, ClientTimeoutError eller AuthorizationError. Även om Azure Monitor endast registrerar antal olika feltyper kan du få mer information om enskilda begäranden genom att undersöka loggar på serversidan, klientsidan och nätverket. Vanligtvis ger HTTP-statuskoden som returneras av lagringstjänsten en indikation på varför begäran misslyckades.

Obs!

Kom ihåg att du bör förvänta dig att se några tillfälliga fel. Till exempel fel på grund av tillfälliga nätverksvillkor eller programfel.

Följande resurser är användbara för att förstå lagringsrelaterad status och felkoder:

Klienten tar emot HTTP 403-meddelanden (förbjudet)

Om klientprogrammet genererar HTTP 403-fel (förbjudet) är en trolig orsak att klienten använder en sas (signatur för delad åtkomst) som upphört att gälla när den skickar en lagringsbegäran (även om andra möjliga orsaker är klocksnedställning, ogiltiga nycklar och tomma rubriker).

Med lagringsklientbiblioteket för .NET kan du samla in loggdata på klientsidan som relaterar till lagringsåtgärder som utförs av ditt program. Mer information finns i Loggning på klientsidan med .NET Storage-klientbiblioteket.

I följande tabell visas ett exempel från loggen på klientsidan som genereras av lagringsklientbiblioteket som illustrerar det här problemet:

Source Informationsnivån Informationsnivån Klientbegärans-ID Åtgärdstext
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 Varning 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 Varning 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 Fel 1 85d077ab -... Retry policy did not allow for a retry. Failing with The remote server returned an error: (403) Forbidden.

I det här scenariot bör du undersöka varför SAS-token upphör att gälla innan klienten skickar token till servern:

  • Normalt bör du inte ange en starttid när du skapar en SAS för en klient som ska användas omedelbart. Om det finns små klockskillnader mellan värden som genererar SAS med den aktuella tiden och lagringstjänsten är det möjligt för lagringstjänsten att ta emot en SAS som ännu inte är giltig.

  • Ange inte en mycket kort förfallotid för en SAS. Återigen kan små klockskillnader mellan värden som genererar SAS och lagringstjänsten leda till att en SAS upphör att gälla tidigare än förväntat.

  • Matchar versionsparametern i SAS-nyckeln (till exempel sv=2015-04-05) den version av lagringsklientbiblioteket som du använder? Vi rekommenderar att du alltid använder den senaste versionen av lagringsklientbiblioteket.

  • Om du återskapar dina lagringsåtkomstnycklar kan eventuella befintliga SAS-token ogiltigförklaras. Det här problemet kan uppstå om du genererar SAS-token med lång förfallotid för klientprogram att cachelagras.

Om du använder Storage-klientbiblioteket för att generera SAS-token är det enkelt att skapa en giltig token. Men om du använder REST-API:et för lagring och skapar SAS-token för hand kan du läsa Delegera åtkomst med en signatur för delad åtkomst.

Klienten tar emot HTTP 404-meddelanden (hittades inte)

Om klientprogrammet tar emot ett HTTP 404-meddelande (hittades inte) från servern innebär det att objektet som klienten försökte använda (till exempel en entitet, tabell, blob, container eller kö) inte finns i lagringstjänsten. Det finns ett antal möjliga orsaker till detta, till exempel:

  • Klienten eller en annan process har tidigare tagit bort objektet.

  • Ett auktoriseringsproblem med signatur för delad åtkomst (SAS).

  • JavaScript-kod på klientsidan har inte behörighet att komma åt objektet.

  • Nätverksfel.

Klienten eller en annan process har tidigare tagit bort objektet

I scenarier där klienten försöker läsa, uppdatera eller ta bort data i en lagringstjänst är det enkelt att i lagringsresursloggarna identifiera en tidigare åtgärd som tog bort objektet i fråga från lagringstjänsten. Loggdata visar ofta att en annan användare eller process har tagit bort objektet. Azure Monitor-loggarna (på serversidan) visas när en klient har tagit bort ett objekt.

I scenariot där en klient försöker infoga ett objekt är det kanske inte omedelbart uppenbart varför detta resulterar i ett HTTP 404-svar (hittades inte), eftersom klienten skapar ett nytt objekt. Men om klienten skapar en blob måste den kunna hitta blobcontainern. Om klienten skapar ett meddelande måste den kunna hitta en kö. Och om klienten lägger till en rad måste den kunna hitta tabellen.

Du kan använda loggen på klientsidan från Storage-klientbiblioteket för att bättre förstå när klienten skickar specifika begäranden till lagringstjänsten.

Följande logg på klientsidan som genereras av storage-klientbiblioteket illustrerar problemet när klienten inte kan hitta containern för den blob som den skapar. Den här loggen innehåller information om följande lagringsåtgärder:

Förfrågnings-ID Åtgärd
07b26a5d-... DeleteIfExists -metod för att ta bort blobcontainern. Den här åtgärden innehåller en HEAD-begäran för att kontrollera om containern finns.
e2d06d78... CreateIfNotExists -metod för att skapa blobcontainern. Den här åtgärden innehåller en HEAD begäran som kontrollerar om containern finns. HEAD Returnerar ett 404-meddelande men fortsätter.
de8b1c3c-... UploadFromStream -metod för att skapa bloben. Begäran PUT misslyckas med ett 404-meddelande

Loggposter:

Förfrågnings-ID Åtgärdstext
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..

I det här exemplet visar loggen att klienten mellanlagrar begäranden från CreateIfNotExists metoden (begärande-ID e2d06d78...) med begäranden från UploadFromStream metoden (de8b1c3c-...). Den här interfolieringen sker eftersom klientprogrammet anropar dessa metoder asynkront. Ändra den asynkrona koden i klienten så att den skapar containern innan du försöker ladda upp data till en blob i containern. Vi rekommenderar att du skapar alla containrar i förväg.

Auktoriseringsproblem med signatur för delad åtkomst (SAS)

Om klientprogrammet försöker använda en SAS-nyckel som inte innehåller nödvändiga behörigheter för åtgärden returnerar lagringstjänsten ett HTTP 404-meddelande (hittades inte) till klienten. I Azure Monitor-mått ser du samtidigt även en AuthorizationError för ResponseType-dimensionen .

Undersök varför klientprogrammet försöker utföra en åtgärd som det inte har beviljats behörighet för.

JavaScript-kod på klientsidan har inte behörighet att komma åt objektet

Om du använder en JavaScript-klient och lagringstjänsten returnerar HTTP 404-meddelanden kontrollerar du följande JavaScript-fel i webbläsaren:

SEC7120: Ursprunget http://localhost:56309 hittades inte i rubriken Access-Control-Allow-Origin.
SCRIPT7002: XMLHttpRequest: Nätverksfel 0x80070005, åtkomst nekas.

Obs!

Du kan använda F12 Developer Tools i Internet Explorer för att spåra meddelanden som utbyts mellan webbläsaren och lagringstjänsten när du felsöker JavaScript-problem på klientsidan.

Dessa fel uppstår eftersom webbläsaren implementerar samma säkerhetsbegränsning för ursprungsprincipen som förhindrar att en webbsida anropar ett API i en annan domän än den domän som sidan kommer från.

Om du vill kringgå JavaScript-problemet kan du konfigurera resursdelning för korsande ursprung (CORS) för den lagringstjänst som klienten har åtkomst till. Mer information finns i Stöd för resursdelning för korsande ursprung (CORS) för Azure Storage-tjänster.

Följande kodexempel visar hur du konfigurerar blobtjänsten så att JavaScript körs i Contoso-domänen för åtkomst till en blob i bloblagringstjänsten:

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);

Nätverksfel

I vissa fall kan förlorade nätverkspaket leda till att lagringstjänsten returnerar HTTP 404-meddelanden till klienten. När klientprogrammet till exempel tar bort en entitet från tabelltjänsten ser du att klienten genererar ett lagringsfel som rapporterar statusmeddelandet "HTTP 404 (hittades inte)" från tabelltjänsten. När du undersöker tabellen i tabelllagringstjänsten ser du att tjänsten har tagit bort entiteten på begäran.

Undantagsinformationen i klienten inkluderar det begärande-ID (7e84f12d...) som tilldelats av tabelltjänsten för begäran: du kan använda den här informationen för att hitta information om begäran i lagringsresursloggarna i Azure Monitor genom att söka i Fält som beskriver hur åtgärden autentiserades för loggposter. Du kan också använda måtten för att identifiera när sådana här fel inträffar och sedan söka i loggfilerna baserat på den tid då måtten registrerade det här felet. Den här loggposten visar att borttagningen misslyckades med statusmeddelandet "HTTP (404) Client Other Error". Samma loggpost innehåller även det begärande-ID som genereras av klienten i client-request-id kolumnen (813ea74f...).

Loggen på serversidan innehåller också en annan post med samma client-request-id värde (813ea74f...) för en lyckad borttagningsåtgärd för samma entitet och från samma klient. Den här lyckade borttagningsåtgärden ägde rum strax före den misslyckade borttagningsbegäran.

Den troligaste orsaken till det här scenariot är att klienten skickade en borttagningsbegäran för entiteten till tabelltjänsten, som lyckades men inte fick någon bekräftelse från servern (kanske på grund av ett tillfälligt nätverksproblem). Klienten har sedan automatiskt gjort ett nytt försök med åtgärden (med samma client-request-id) och det här återförsöket misslyckades eftersom entiteten redan hade tagits bort.

Om det här problemet uppstår ofta bör du undersöka varför klienten inte kan ta emot bekräftelser från tabelltjänsten. Om problemet är tillfälligt bör du fånga felet "HTTP (404) Hittades inte" och logga det i klienten, men tillåta att klienten fortsätter.

Klienten tar emot HTTP 409-meddelanden (konflikt)

När en klient tar bort blobcontainrar, tabeller eller köer finns det en kort period innan namnet blir tillgängligt igen. Om koden i klientprogrammet tas bort och sedan omedelbart återskapar en blobcontainer med samma namn misslyckas CreateIfNotExists metoden till slut med FELET HTTP 409 (konflikt).

Klientprogrammet bör använda unika containernamn när det skapar nya containrar om mönstret för borttagning/återskapande är vanligt.

Mått visar att låga PercentSuccess- eller analysloggposter har åtgärder med transaktionsstatusen ClientOtherErrors

En ResponseType-dimension som är lika med värdet Lyckades samlar in procentandelen åtgärder som lyckades baserat på deras HTTP-statuskod. Åtgärder med statuskoderna 2XX räknas som lyckade, medan åtgärder med statuskoder i intervallen 3XX, 4XX och 5XX räknas som misslyckade och sänker måttvärdet Lyckades. I lagringsresursloggar registreras dessa åtgärder med transaktionsstatusen ClientOtherError.

Dessa åtgärder har slutförts och påverkar därför inte andra mått, till exempel tillgänglighet. Några exempel på åtgärder som körs men som kan resultera i misslyckade HTTP-statuskoder är:

  • ResourceNotFound (hittades inte 404), till exempel från en GET-begäran till en blob som inte finns.
  • ResourceAlreadyExists (konflikt 409), till exempel från en CreateIfNotExist åtgärd där resursen redan finns.
  • ConditionNotMet (inte ändrad 304), till exempel från en villkorsstyrd åtgärd, till exempel när en klient skickar ett ETag värde och ett HTTP-huvud If-None-Match för att begära en avbildning endast om den har uppdaterats sedan den senaste åtgärden.

Du hittar en lista över vanliga REST API-felkoder som lagringstjänsterna returnerar på sidan Vanliga REST API-felkoder.

Se även

Kontakta oss för att få hjälp

Om du har frågor eller behöver hjälp skapar du en supportförfrågan eller frågar Azure community support. Du kan också skicka produktfeedback till Azure-feedbackcommunityn.