Udostępnij za pośrednictwem


Rozwiązywanie problemów z błędami aplikacji klienckiej na kontach usługi Azure Storage

Ten artykuł ułatwia badanie błędów aplikacji klienckich przy użyciu metryk, dzienników po stronie klienta i dzienników zasobów w usłudze Azure Monitor.

Diagnozowanie błędów

Użytkownicy aplikacji mogą powiadamiać o błędach zgłaszanych przez aplikację kliencka. Usługa Azure Monitor rejestruje również liczbę różnych typów odpowiedzi (wymiary ResponseType) z usług magazynu, takich jak NetworkError, ClientTimeoutError lub AuthorizationError. Usługa Azure Monitor rejestruje tylko liczby różnych typów błędów, ale można uzyskać więcej szczegółowych informacji na temat poszczególnych żądań, sprawdzając dzienniki po stronie serwera, po stronie klienta i sieci. Zazwyczaj kod stanu HTTP zwrócony przez usługę magazynu daje wskazanie, dlaczego żądanie nie powiodło się.

Uwaga 16.

Należy pamiętać, że powinny pojawić się sporadyczne błędy. Na przykład błędy spowodowane przejściowymi warunkami sieci lub błędami aplikacji.

Przydatne dla zrozumienia kodów stanu i błędów związanych z magazynem są następujące zasoby:

Klient odbiera komunikaty HTTP 403 (zabronione)

Jeśli aplikacja kliencka zgłasza błędy HTTP 403 (zabronione), prawdopodobną przyczyną jest to, że klient używa wygasłej sygnatury dostępu współdzielonego podczas wysyłania żądania magazynu (chociaż inne możliwe przyczyny to niedokładność zegara, nieprawidłowe klucze i puste nagłówki).

Biblioteka klienta magazynu dla platformy .NET umożliwia zbieranie danych dziennika po stronie klienta związanych z operacjami magazynu wykonywanymi przez aplikację. Aby uzyskać więcej informacji, zobacz Client-side Logging with the .NET Storage Client Library (Logowanie po stronie klienta przy użyciu biblioteki klienckiej usługi .NET Storage).

W poniższej tabeli przedstawiono przykład z dziennika po stronie klienta wygenerowanego przez bibliotekę klienta usługi Storage, która ilustruje ten problem:

Źródło Poziom szczegółowości Poziom szczegółowości Identyfikator żądania klienta Tekst operacji
Microsoft.Azure.Storage Informacja 3 85d077ab-... Starting operation with location Primary per location mode PrimaryOnly.
Microsoft.Azure.Storage Informacja 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 Informacja 3 85d077ab -... Waiting for response.
Microsoft.Azure.Storage Ostrzeżenie 2 85d077ab -... Exception thrown while waiting for response: The remote server returned an error: (403) Forbidden.
Microsoft.Azure.Storage Informacja 3 85d077ab -... Response received. Status code = 403, Request ID = <Request ID>, Content-MD5 = , ETag = .
Microsoft.Azure.Storage Ostrzeżenie 2 85d077ab -... Exception thrown during the operation: The remote server returned an error: (403) Forbidden..
Microsoft.Azure.Storage Informacja 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 Informacja 3 85d077ab -... The next location has been set to Primary, based on the location mode.
Microsoft.Azure.Storage Błąd 1 85d077ab -... Retry policy did not allow for a retry. Failing with The remote server returned an error: (403) Forbidden.

W tym scenariuszu należy zbadać, dlaczego token SAS wygasa, zanim klient wyśle token do serwera:

  • Zazwyczaj nie należy ustawiać czasu rozpoczęcia podczas tworzenia sygnatury dostępu współdzielonego dla klienta do natychmiastowego użycia. Jeśli istnieją niewielkie różnice zegara między hostem generującym sygnaturę dostępu współdzielonego przy użyciu bieżącego czasu a usługą magazynu, usługa magazynu może odbierać sygnaturę dostępu współdzielonego, która nie jest jeszcze prawidłowa.

  • Nie ustawiaj bardzo krótkiego czasu wygaśnięcia sygnatury dostępu współdzielonego. W tym przypadku niewielkie różnice zegara między hostem generującym sygnaturę dostępu współdzielonego a usługą magazynu mogą prowadzić do tego, że sygnatura dostępu współdzielonego wygasa wcześniej, niż zakładano.

  • Czy parametr wersji w kluczu sygnatury dostępu współdzielonego (na przykład sv=2015-04-05) jest zgodny z wersją używanej biblioteki klienta usługi Storage? Zalecamy, aby zawsze używać najnowszej wersji biblioteki klienta magazynu.

  • Jeśli ponownie wygenerujesz klucze dostępu do magazynu, wszelkie istniejące tokeny SAS mogą zostać unieważnione. Ten problem może wystąpić, jeśli generujesz tokeny SAS z długim czasem wygaśnięcia dla aplikacji klienckich do przechowywania w pamięci podręcznej.

Jeśli używasz biblioteki klienta usługi Storage do generowania tokenów SAS, możesz łatwo utworzyć prawidłowy token. Jeśli jednak używasz interfejsu API REST usługi Storage i konstruujesz tokeny SAS ręcznie, zobacz Delegowanie dostępu za pomocą sygnatury dostępu współdzielonego.

Klient odbiera komunikaty HTTP 404 (nie znaleziono)

Jeśli aplikacja kliencka otrzyma komunikat HTTP 404 (nie znaleziono) z serwera, oznacza to, że obiekt, którego klient próbował użyć (na przykład jednostki, tabeli, obiektu blob, kontenera lub kolejki) nie istnieje w usłudze magazynu. Istnieje kilka możliwych przyczyn tej sytuacji, takich jak:

  • Klient lub inny proces wcześniej usunął obiekt.

  • Problem z autoryzacją sygnatury dostępu współdzielonego (SAS).

  • Kod JavaScript po stronie klienta nie ma uprawnień dostępu do obiektu.

  • Awaria sieci.

Klient lub inny proces wcześniej usunął obiekt

W scenariuszach, w których klient próbuje odczytywać, aktualizować lub usuwać dane w usłudze magazynu, łatwo jest zidentyfikować w dzienniku zasobów magazynu poprzednią operację, która usunęła dany obiekt z usługi magazynu. Często dane dziennika pokazują, że inny użytkownik lub proces usunął obiekt. Dzienniki usługi Azure Monitor (po stronie serwera) pokazują, kiedy klient usunął obiekt.

W scenariuszu, w którym klient próbuje wstawić obiekt, może nie być od razu oczywiste, dlaczego powoduje to odpowiedź HTTP 404 (nie znaleziono), biorąc pod uwagę, że klient tworzy nowy obiekt. Jeśli jednak klient tworzy obiekt blob, musi mieć możliwość znalezienia kontenera obiektów blob. Jeśli klient tworzy komunikat, musi mieć możliwość znalezienia kolejki. A jeśli klient dodaje wiersz, musi być w stanie znaleźć tabelę.

Możesz użyć dziennika po stronie klienta z biblioteki klienta magazynu, aby lepiej zrozumieć, kiedy klient wysyła określone żądania do usługi magazynu.

Poniższy dziennik po stronie klienta wygenerowany przez bibliotekę klienta magazynu ilustruje problem, gdy klient nie może odnaleźć kontenera dla tworzonego obiektu blob. Ten dziennik zawiera szczegółowe informacje o następujących operacjach magazynowania:

Identyfikator żądania Operacja
07b26a5d-... DeleteIfExists metoda usuwania kontenera obiektów blob. Ta operacja obejmuje żądanie HEAD w celu sprawdzenia istnienia kontenera.
e2d06d78... CreateIfNotExists metoda tworzenia kontenera obiektów blob. Ta operacja obejmuje HEAD żądanie sprawdzające istnienie kontenera. Funkcja HEAD zwraca komunikat 404, ale kontynuuje.
de8b1c3c-... UploadFromStream metoda tworzenia obiektu blob. Żądanie PUT kończy się niepowodzeniem z komunikatem 404

Wpisy dziennika:

Identyfikator żądania Tekst operacji
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..

W tym przykładzie dziennik pokazuje, że klient przeplata żądania z CreateIfNotExists metody (identyfikator żądania e2d06d78...) z żądaniami metody UploadFromStream (de8b1c3c-...). To przeplatanie występuje, ponieważ aplikacja kliencka wywoła te metody asynchronicznie. Zmodyfikuj kod asynchroniczny w kliencie, aby upewnić się, że tworzy kontener przed podjęciem próby przekazania danych do obiektu blob w tym kontenerze. Najlepiej jest utworzyć wszystkie kontenery z wyprzedzeniem.

Problem z autoryzacją sygnatury dostępu współdzielonego

Jeśli aplikacja kliencka próbuje użyć klucza sygnatury dostępu współdzielonego, który nie zawiera niezbędnych uprawnień do operacji, usługa magazynu zwróci klientowi komunikat HTTP 404 (nie znaleziono). Jednocześnie w metrykach usługi Azure Monitor zobaczysz również błąd AuthorizationError dla wymiaru ResponseType .

Sprawdź, dlaczego aplikacja kliencka próbuje wykonać operację, dla której nie udzielono uprawnień.

Kod JavaScript po stronie klienta nie ma uprawnień dostępu do obiektu

Jeśli używasz klienta JavaScript, a usługa magazynu zwraca komunikaty HTTP 404, sprawdź następujące błędy języka JavaScript w przeglądarce:

SEC7120: Nie można odnaleźć źródła http://localhost:56309 w nagłówku Access-Control-Allow-Origin.
SCRIPT7002: XMLHttpRequest: błąd sieci 0x80070005, odmowa dostępu.

Uwaga 16.

Narzędzia deweloperskie F12 w programie Internet Explorer umożliwiają śledzenie komunikatów wymienianych między przeglądarką a usługą magazynu podczas rozwiązywania problemów z językiem JavaScript po stronie klienta.

Te błędy występują, ponieważ przeglądarka internetowa implementuje to samo ograniczenie zabezpieczeń zasad pochodzenia, które uniemożliwia stronie internetowej wywoływanie interfejsu API w innej domenie niż domena, z którą pochodzi strona.

Aby obejść problem z językiem JavaScript, możesz skonfigurować współużytkowanie zasobów między źródłami (CORS) dla usługi magazynu, do której uzyskuje dostęp klient. Aby uzyskać więcej informacji, zobacz Obsługa współużytkowania zasobów między źródłami (CORS) dla usług Azure Storage.

Poniższy przykładowy kod pokazuje, jak skonfigurować usługę obiektów blob, aby umożliwić uruchamianie kodu JavaScript w domenie firmy Contoso w celu uzyskania dostępu do obiektu blob w usłudze blob Storage:

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

Błąd sieci

W niektórych okolicznościach utracone pakiety sieciowe mogą prowadzić do zwracania komunikatów HTTP 404 do klienta przez usługę magazynu. Na przykład gdy aplikacja kliencka usuwa jednostkę z usługi tabel, zobaczysz, że klient zgłasza wyjątek magazynu zgłaszający komunikat o stanie "HTTP 404 (Nie znaleziono)" z usługi tabeli. Podczas badania tabeli w usłudze table storage zobaczysz, że usługa usunęła jednostkę zgodnie z żądaniem.

Szczegóły wyjątku w kliencie obejmują identyfikator żądania (7e84f12d...) przypisany przez usługę tabel dla żądania: te informacje umożliwiają zlokalizowanie szczegółów żądania w dziennikach zasobów magazynu w usłudze Azure Monitor przez wyszukiwanie w polach opisujących sposób uwierzytelniania operacji wpisów dziennika. Możesz również użyć metryk, aby określić, kiedy wystąpią błędy, a następnie przeszukać pliki dziennika na podstawie czasu zarejestrowania tego błędu przez metryki. Ten wpis dziennika pokazuje, że usunięcie nie powiodło się z komunikatem o stanie "HTTP (404) Client Other Error". Ten sam wpis dziennika zawiera również identyfikator żądania wygenerowany przez klienta w client-request-id kolumnie (813ea74f...).

Dziennik po stronie serwera zawiera również inny wpis o tej samej client-request-id wartości (813ea74f...) dla pomyślnej operacji usuwania dla tej samej jednostki i z tego samego klienta. Ta pomyślna operacja usuwania miała miejsce wkrótce przed niepowodzeniem żądania usunięcia.

Najbardziej prawdopodobną przyczyną tego scenariusza jest to, że klient wysłał żądanie usunięcia jednostki do usługi tabeli, która zakończyła się pomyślnie, ale nie otrzymała potwierdzenia z serwera (być może z powodu tymczasowego problemu z siecią). Następnie klient automatycznie ponowił operację (przy użyciu tej samej client-request-idmetody ), a ta ponowna próba nie powiodła się, ponieważ jednostka została już usunięta.

Jeśli ten problem występuje często, należy zbadać, dlaczego klient nie odbiera potwierdzenia z usługi tabel. Jeśli problem występuje sporadycznie, należy wychwycić błąd "HTTP (404) Nie znaleziono" i zalogować go w kliencie, ale zezwolić klientowi na kontynuowanie.

Klient odbiera komunikaty HTTP 409 (konflikt)

Gdy klient usuwa kontenery obiektów blob, tabele lub kolejki, przed ponownym udostępnieniem nazwy następuje krótki okres. Jeśli kod w aplikacji klienckiej zostanie usunięty, a następnie natychmiast ponownie utworzy kontener obiektów blob przy użyciu tej samej nazwy, CreateIfNotExists metoda ostatecznie zakończy się niepowodzeniem z powodu błędu HTTP 409 (konflikt).

Aplikacja kliencka powinna używać unikatowych nazw kontenerów za każdym razem, gdy tworzy nowe kontenery, jeśli wzorzec usuń/utwórz ponownie jest typowy.

Metryki pokazują niską wartość PercentSuccess lub wpisy dziennika analizy mają operacje ze stanem transakcji ClientOtherErrors

Wymiar ResponseType równy wartości Powodzenie przechwytuje procent operacji zakończonych powodzeniem na podstawie kodu stanu HTTP. Operacje z kodami stanu 2XX zliczają się jako pomyślne, podczas gdy operacje z kodami stanu w zakresie 3XX, 4XX i 5XX są liczone jako nieudane i obniżają wartość metryki Powodzenie. W dziennikach zasobów magazynu te operacje są rejestrowane ze stanem transakcji ClientOtherError.

Te operacje zostały ukończone pomyślnie i dlatego nie mają wpływu na inne metryki, takie jak dostępność. Niektóre przykłady operacji, które są wykonywane pomyślnie, ale mogą spowodować niepowodzenie kodów stanu HTTP, to:

  • ResourceNotFound (nie znaleziono 404), na przykład z żądania GET do obiektu blob, który nie istnieje.
  • ResourceAlreadyExists (konflikt 409), na przykład z CreateIfNotExist operacji, w której zasób już istnieje.
  • ConditionNotMet (niezmodyfikowany 304), na przykład z operacji warunkowej, takiej jak gdy klient wysyła ETag wartość i nagłówek HTTP If-None-Match , aby zażądać obrazu tylko wtedy, gdy został zaktualizowany od ostatniej operacji.

Listę typowych kodów błędów interfejsu API REST zwracanych przez usługi magazynu można znaleźć na stronie Typowe kody błędów interfejsu API REST.

Zobacz też

Skontaktuj się z nami, aby uzyskać pomoc

Jeśli masz pytania lub potrzebujesz pomocy, utwórz wniosek o pomoc techniczną lub zadaj pytanie w społeczności wsparcia dla platformy Azure. Możesz również przesłać opinię o produkcie do społeczności opinii na temat platformy Azure.