Partager via


Résoudre les erreurs d’application cliente dans les comptes de stockage Azure

Cet article vous aide à examiner les erreurs d’application cliente à l’aide de métriques, de journaux côté client et de journaux de ressources dans Azure Monitor.

Erreurs de diagnostic

Les utilisateurs de votre application peuvent vous signaler des erreurs identifiées par l'application cliente. Azure Monitor enregistre également le nombre de différents types de réponse (dimensions ResponseType ) de vos services de stockage, tels que NetworkError, ClientTimeoutError ou AuthorizationError. Azure Monitor enregistre uniquement les décomptes des différents types d’erreurs, mais vous pouvez obtenir des informations plus détaillées concernant les demandes individuelles en examinant les journaux d’activité côté serveur, côté client et réseau. Le code d'état HTTP renvoyé par le service de stockage peut généralement servir d'indication pour expliquer l'échec de la demande.

Note

N’oubliez pas que vous devez vous attendre à voir certaines erreurs intermittentes. Par exemple, des erreurs en raison de conditions réseau temporaires ou d’erreurs d’application.

Les ressources suivantes sont utiles pour comprendre les codes d’état et d’erreur liés au stockage :

Le client reçoit des messages HTTP 403 (Forbidden)

Si votre application client génère des erreurs HTTP403 (Forbidden), l'une des causes probables est l'utilisation par le client d'une signature d'accès partagé (SAS) arrivée à expiration lors de l'envoi d'une demande de stockage (d'autres causes possibles incluent les variations d'horloges, les clés non valides et les en-têtes vides).

La bibliothèque cliente de stockage pour .NET vous permet de collecter les données de journalisation côté client, liées aux opérations de stockage réalisées par votre application. Pour plus d’informations, consultez Journalisation côté client avec la bibliothèque cliente de stockage .NET.

Le tableau suivant inclut un exemple de journal côté client généré par la bibliothèque cliente de stockage, qui illustre ce type de problème :

Source Commentaires Commentaires ID de la demande client Operation Text
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 Avertissement 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 Avertissement 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 Error 1 85d077ab-… Retry policy did not allow for a retry. Failing with The remote server returned an error: (403) Forbidden.

Dans ce scénario, vous devez rechercher pourquoi le jeton SAS expire avant que le client n'envoie le jeton au serveur :

  • En règle générale, vous ne devez pas définir une heure de début lorsque vous créez une SAP pour qu’un client utilise immédiatement. S'il existe de faibles variations d'horloges entre l'hôte qui génère la SAS sur base de l'heure actuelle et le service de stockage, il est possible que le service de stockage reçoive une SAS qui n'est pas encore valide.

  • Ne définissez pas une durée d’expiration très courte sur une SAP. À nouveau, de petites variations d’horloges entre l’hôte qui génère le jeton SAS et le service de stockage peuvent entraîner l’expiration du jeton SAS plus tôt que prévu.

  • Le paramètre de version de la clé SAP (par exemple, sv=2015-04-05) correspond-il à la version de la bibliothèque cliente de stockage que vous utilisez ? Nous vous recommandons de toujours utiliser la dernière version de la bibliothèque cliente de stockage.

  • Si vous régénérez vos clés d’accès de stockage, les jetons SAS existants risquent d’être invalidés. Ce problème peut survenir si vous générez des jetons SAS avec une durée d’expiration longue pour les applications clientes dans le cache.

Si vous utilisez la bibliothèque de client de stockage pour générer des jetons SAS, il est facile de créer un jeton valide. Néanmoins si vous utilisez l’API REST de Stockage et que vous créez les jetons SAS manuellement, consultez Délégation de l’accès avec une signature d’accès partagé.

Le client reçoit des messages HTTP 404 (Not found)

Si l’application client reçoit un message HTTP 404 (Non trouvé) du serveur, cela signifie que l’objet que le client tentait d’utiliser (tel qu’une entité, une table, un objet blob, un conteneur ou une file d’attente) n’existe pas dans le service de stockage. Il existe un certain nombre de raisons possibles à ce problème, dont :

  • Le client ou un autre processus a précédemment supprimé l’objet.

  • Problème d’autorisation signature d’accès partagé (SAP).

  • Le code JavaScript côté client n’est pas autorisé à accéder à l’objet.

  • Échec réseau.

Le client ou un autre processus a précédemment supprimé l’objet

Dans les scénarios où le client tente de lire, de mettre à jour ou de supprimer des données dans un service de stockage, il est facile d’identifier dans les journaux des ressources de stockage une opération précédente qui a supprimé l’objet en question du service de stockage. Souvent, les données de journalisation indiquent qu’un autre utilisateur ou processus a supprimé l’objet. Les journaux Azure Monitor (côté serveur) s’affichent lorsqu’un client a supprimé un objet.

Dans le scénario où un client tente d’insérer un objet, il peut ne pas être immédiatement évident pourquoi cela entraîne une réponse HTTP 404 (introuvable), étant donné que le client crée un objet. Toutefois, si le client crée un objet blob, il doit être en mesure de trouver le conteneur d’objets blob. Si le client crée un message, il doit être en mesure de trouver une file d’attente. Et si le client ajoute une ligne, il doit être en mesure de trouver la table.

Vous pouvez utiliser le journal côté client à partir de la bibliothèque cliente de stockage pour mieux comprendre quand le client envoie des demandes spécifiques au service de stockage.

Le journal côté client suivant généré par la bibliothèque cliente de stockage illustre le problème lorsque le client ne trouve pas le conteneur pour l’objet blob qu’il crée. Ce journal inclut les détails des opérations de stockage suivantes :

ID de la demande Opération
07b26a5d-... DeleteIfExists méthode pour supprimer le conteneur d’objets blob. Cette opération inclut une requête HEAD pour vérifier l’existence du conteneur.
e2d06d78… CreateIfNotExists méthode pour créer le conteneur d’objets blob. Cette opération inclut une HEAD demande qui vérifie l’existence du conteneur. Retourne HEAD un message 404, mais continue.
de8b1c3c-... UploadFromStream méthode pour créer l’objet blob. La PUT demande échoue avec un message 404

Entrées du journal :

ID de la demande Operation Text
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..

Dans cet exemple, le journal indique que le client interlace les requêtes de la CreateIfNotExists méthode (ID de requête e2d06d78...) avec les requêtes de la UploadFromStream méthode (de8b1c3c-...). Cet entrelacement se produit parce que l’application cliente appelle ces méthodes de façon asynchrone. Modifiez le code asynchrone dans le client de façon à ce qu’il crée le conteneur avant de tenter de charger des données dans un objet blob de ce conteneur. Idéalement, vous devriez créer tous vos conteneurs à l’avance.

Problème d’autorisation de signature d’accès partagé (SAP)

Si l’application cliente tente d’utiliser une clé SAS qui n’inclut pas les autorisations requises pour l’opération, le service de stockage renvoie un message HTTP 404 (Non trouvé) au client. En même temps, dans les métriques Azure Monitor, vous verrez également une autorisationError pour la dimension ResponseType.

Examinez pourquoi votre application cliente tente d’effectuer une opération pour laquelle elle n’a pas reçu d’autorisations.

Le code JavaScript côté client n’est pas autorisé à accéder à l’objet

Si vous utilisez un client JavaScript et que le service de stockage retourne des messages HTTP 404, recherchez les erreurs JavaScript suivantes dans le navigateur :

SEC7120 : Origine http://localhost:56309 introuvable dans l’en-tête Access-Control-Allow-Origin.
SCRIPT7002 : XMLHttpRequest : Erreur réseau 0x80070005, Access est refusé.

Note

Vous pouvez utiliser les Outils de développement F12 dans Internet Explorer pour procéder au suivi des messages échangés entre le navigateur et le service de stockage lors de la résolution des problèmes JavaScript côté client.

Ces erreurs sont dues au fait que le navigateur implémente la restriction de sécurité same origin policy , qui empêche une page web d’appeler une API dans un domaine différent de celui dont la page provient.

Pour contourner le problème JavaScript, vous pouvez configurer le partage de ressources cross-origin (CORS) pour le service de stockage auquel le client accède. Pour plus d’informations, voir Prise en charge du service Partage des ressources cross-origine (CORS) pour les services Azure Storage.

L'exemple de code suivant montre comment configurer votre service d'objet blob afin de permettre l'exécution de JavaScript dans le domaine Contoso pour accéder à un objet blob dans votre service de stockage d'objets 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);

Panne réseau

Dans certaines circonstances, la perte de paquets réseau peut amener le service de stockage à renvoyer des messages HTTP 404 au client. Par exemple, lorsque votre application cliente supprime une entité du service de table, vous voyez que le client lève une exception de stockage signalant un message d’état « HTTP 404 (introuvable) » du service de table. Lorsque vous recherchez la table dans le service de stockage de table, vous constatez que le service a supprimé l'entité comme prévu.

Les détails de l’exception dans le client incluent l’ID de requête (7e84f12d...) attribué par le service de Table pour la requête : vous pouvez utiliser ces informations pour rechercher les détails de la requête dans les journaux de la ressource de stockage dans Azure Monitor en effectuant une recherche dans les entrées du journal intitulées Champs décrivant comment l’opération a été authentifiée. Vous pouvez également utiliser les métriques pour savoir quand ce type d’erreurs se produit, puis effectuer une recherche dans les fichiers journaux sur base de l’heure à laquelle les métriques ont enregistré cette erreur. L’entrée du journal indique que la suppression a échoué avec un message d’état « HTTP (404) Client Other Error ». La même entrée de journal inclut également l’ID de requête généré par le client dans la client-request-id colonne (813ea74f...).

Le journal côté serveur inclut également une autre entrée avec la même client-request-id valeur (813ea74f...) pour une opération de suppression réussie pour la même entité et du même client. Cette opération de suppression réussie a eu lieu peu avant l’échec de la demande de suppression.

La cause la plus probable de ce scénario est que le client a envoyé une demande de suppression pour l’entité au service de table, qui a réussi, mais n’a pas reçu d’accusé de réception du serveur (peut-être en raison d’un problème réseau temporaire). Le client a ensuite retenté automatiquement l’opération (en utilisant le même client-request-id), et cette nouvelle tentative a échoué, car l’entité avait déjà été supprimée.

Si ce problème se produit fréquemment, vous devez rechercher pourquoi le client ne reçoit pas les accusés de réception du service de table. Si le problème est intermittent, vous devez capturer l’erreur « HTTP (404) Not Found » et la journaliser dans le client, mais permettre au client de continuer.

Le client reçoit des messages HTTP 409 (Conflict)

Lorsqu’un client supprime des conteneurs d’objets blob, des tables ou des files d’attente, il y a un bref point avant que le nom ne soit à nouveau disponible. Si le code de votre application cliente supprime et recrée immédiatement un conteneur d’objets blob à l’aide du même nom, la CreateIfNotExists méthode échoue finalement avec l’erreur HTTP 409 (conflit).

Chaque fois qu'elle crée des conteneurs, l'application cliente utilise des noms de conteneur uniques si le modèle de suppression/recréation est commun.

Les métriques indiquent une valeur PercentSuccess faible ou les entrées du journal d’analyse incluent des opérations avec un statut de transaction ClientOtherErrors

Une dimension ResponseType égale à une valeur Success capture le pourcentage d’opérations qui ont réussi en fonction de leur code d’état HTTP. Les opérations avec des codes d’état de 2XX comptent comme ayant réussi, tandis que les opérations avec des codes d’état dans les plages 3XX, 4XX et 5XX sont comptabilisées comme ayant échoué et réduisent la valeur de la métrique Réussite. Dans les fichiers journaux de la ressource de stockage, ces opérations sont enregistrées avec un statut de transaction ClientOtherError.

Ces opérations ont réussi et n’affectent donc pas d’autres métriques, telles que la disponibilité. Voici quelques exemples d'opérations qui s'exécutent avec succès, mais qui génèrent des codes d'état HTTP d'échec :

  • ResourceNotFound (introuvable 404), par exemple, d’une requête GET vers un objet blob qui n’existe pas.
  • ResourceAlreadyExists (Conflit 409), par exemple à partir d’une CreateIfNotExist opération où la ressource existe déjà.
  • ConditionNotMet (Non modifié 304), par exemple, à partir d’une opération conditionnelle telle qu’un client envoie une ETag valeur et un en-tête HTTP If-None-Match pour demander une image uniquement si elle a été mise à jour depuis la dernière opération.

Vous trouverez une liste des codes d’erreur API REST communs renvoyés par les services de stockage à la page Codes d’erreur API REST communs.

Voir aussi

Contactez-nous pour obtenir de l’aide

Pour toute demande ou assistance, créez une demande de support ou posez une question au support de la communauté Azure. Vous pouvez également soumettre des commentaires sur les produits à la communauté de commentaires Azure.