Solución de problemas de errores de aplicación cliente en cuentas de Almacenamiento de Azure

Este artículo le ayuda a investigar los errores de la aplicación cliente mediante métricas, registros del lado cliente y registros de recursos en Azure Monitor.

Diagnóstico de errores

Los usuarios de la aplicación pueden notificarle los errores notificados por la aplicación cliente. Azure Monitor también registra recuentos de diferentes tipos de respuesta (dimensiones ResponseType ) de los servicios de almacenamiento, como NetworkError, ClientTimeoutError o AuthorizationError. Aunque Azure Monitor solo registra recuentos de tipos de error diferentes, puede obtener más detalles sobre las solicitudes individuales mediante el examen de los registros del lado servidor, del lado cliente y de red. Normalmente, el código de estado HTTP devuelto por el servicio de almacenamiento proporcionará una indicación de por qué se produjo un error en la solicitud.

Nota:

Recuerde que debe esperar ver algunos errores intermitentes. Por ejemplo, errores debidos a condiciones de red transitorias o errores de aplicación.

Los siguientes recursos son útiles para comprender el estado relacionado con el almacenamiento y los códigos de error:

El cliente recibe mensajes HTTP 403 (prohibidos)

Si la aplicación cliente produce errores HTTP 403 (prohibido), una causa probable es que el cliente esté usando una firma de acceso compartido (SAS) expirada cuando envía una solicitud de almacenamiento (aunque otras causas posibles incluyen sesgo de reloj, claves no válidas y encabezados vacíos).

La biblioteca cliente de Almacenamiento para .NET permite recopilar datos de registro del lado cliente relacionados con las operaciones de almacenamiento realizadas por la aplicación. Para obtener más información, consulte Registro del lado cliente con la biblioteca cliente de almacenamiento de .NET.

En la tabla siguiente se muestra un ejemplo del registro del lado cliente generado por la biblioteca cliente de Storage que muestra este problema que se produce:

Origen Detalles Detalles Identificador de solicitud de cliente Texto de la operación
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 Advertencia 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 Advertencia 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.

En este escenario, debe investigar por qué el token de SAS expira antes de que el cliente envíe el token al servidor:

  • Normalmente, no debe establecer una hora de inicio al crear una SAS para que un cliente la use inmediatamente. Si hay pequeñas diferencias de reloj entre el host que genera la SAS con la hora actual y el servicio de almacenamiento, es posible que el servicio de almacenamiento reciba una SAS que aún no es válida.

  • No establezca un tiempo de expiración muy corto en una SAS. De nuevo, las pequeñas diferencias de reloj entre el host que genera la SAS y el servicio de almacenamiento pueden dar lugar a que una SAS expire antes de lo previsto.

  • ¿El parámetro version de la clave SAS (por ejemplo, sv=2015-04-05) coincide con la versión de la biblioteca cliente de Storage que usa? Se recomienda usar siempre la versión más reciente de la biblioteca cliente de almacenamiento.

  • Si vuelve a generar las claves de acceso de almacenamiento, es posible que se invalide cualquier token de SAS existente. Este problema puede surgir si genera tokens de SAS con un tiempo de expiración largo para que las aplicaciones cliente almacenen en caché.

Si usa la biblioteca cliente de Storage para generar tokens de SAS, es fácil crear un token válido. Sin embargo, si usa la API REST de Almacenamiento y construye los tokens de SAS a mano, consulte Delegación del acceso con una firma de acceso compartido.

El cliente recibe mensajes HTTP 404 (no encontrados)

Si la aplicación cliente recibe un mensaje HTTP 404 (no encontrado) del servidor, esto implica que el objeto que el cliente estaba intentando usar (por ejemplo, una entidad, una tabla, un blob, un contenedor o una cola) no existe en el servicio de almacenamiento. Hay varias razones posibles para ello, como:

  • El cliente u otro proceso eliminó previamente el objeto.

  • Problema de autorización de firma de acceso compartido (SAS).

  • El código JavaScript del lado cliente no tiene permiso para acceder al objeto.

  • Error de red.

El cliente u otro proceso eliminó previamente el objeto

En escenarios en los que el cliente intenta leer, actualizar o eliminar datos en un servicio de almacenamiento, es fácil identificar en el recurso de almacenamiento registra una operación anterior que eliminó el objeto en cuestión del servicio de almacenamiento. A menudo, los datos de registro muestran que otro usuario o proceso eliminó el objeto. Los registros de Azure Monitor (lado servidor) muestran cuándo un cliente eliminó un objeto.

En el escenario en el que un cliente intenta insertar un objeto, es posible que no sea inmediatamente obvio por qué esto da como resultado una respuesta HTTP 404 (no encontrado), dado que el cliente está creando un nuevo objeto. Sin embargo, si el cliente está creando un blob, debe poder encontrar el contenedor de blobs. Si el cliente está creando un mensaje, debe poder encontrar una cola. Y si el cliente agrega una fila, debe poder encontrar la tabla.

Puede usar el registro del lado cliente de la biblioteca cliente de Storage para comprender mejor cuándo el cliente envía solicitudes específicas al servicio de almacenamiento.

El siguiente registro del lado cliente generado por la biblioteca cliente de Storage muestra el problema cuando el cliente no puede encontrar el contenedor para el blob que está creando. Este registro incluye detalles de las siguientes operaciones de almacenamiento:

ID de solicitud Operación
07b26a5d-... DeleteIfExists para eliminar el contenedor de blobs. Esta operación incluye una solicitud HEAD para comprobar la existencia del contenedor.
e2d06d78... CreateIfNotExists para crear el contenedor de blobs. Esta operación incluye una HEAD solicitud que comprueba la existencia del contenedor. HEAD devuelve un mensaje 404, pero continúa.
de8b1c3c-... UploadFromStream para crear el blob. Se produce un error en la PUT solicitud con un mensaje 404

Entradas de registro:

ID de solicitud Texto de la operación
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..

En este ejemplo, el registro muestra que el cliente intercala solicitudes del CreateIfNotExists método (id. de solicitud e2d06d78...) con las solicitudes del UploadFromStream método (de8b1c3c-...). Este intercalado se produce porque la aplicación cliente invoca estos métodos de forma asincrónica. Modifique el código asincrónico del cliente para asegurarse de que crea el contenedor antes de intentar cargar los datos en un blob de ese contenedor. Lo ideal es crear todos los contenedores de antemano.

Un problema de autorización de firma de acceso compartido (SAS)

Si la aplicación cliente intenta usar una clave SAS que no incluye los permisos necesarios para la operación, el servicio de almacenamiento devuelve un mensaje HTTP 404 (no encontrado) al cliente. Al mismo tiempo, en las métricas de Azure Monitor, también verá un AuthorizationError para la dimensión ResponseType .

Investigue por qué la aplicación cliente intenta realizar una operación para la que no se le han concedido permisos.

El código JavaScript del lado cliente no tiene permiso para acceder al objeto

Si usa un cliente JavaScript y el servicio de almacenamiento devuelve mensajes HTTP 404, compruebe los siguientes errores de JavaScript en el explorador:

SEC7120: el origen http://localhost:56309 no se encuentra en el encabezado Access-Control-Allow-Origin.
SCRIPT7002: XMLHttpRequest: error de red 0x80070005, se deniega el acceso.

Nota:

Puede usar F12 Developer Tools en Internet Explorer para realizar un seguimiento de los mensajes intercambiados entre el explorador y el servicio de almacenamiento al solucionar problemas de JavaScript del lado cliente.

Estos errores se producen porque el explorador web implementa la misma restricción de seguridad de directiva de origen que impide que una página web llame a una API en un dominio diferente del dominio del que procede la página.

Para solucionar el problema de JavaScript, puede configurar el uso compartido de recursos entre orígenes (CORS) para el servicio de almacenamiento al que está accediendo el cliente. Para obtener más información, consulte Compatibilidad con el uso compartido de recursos entre orígenes (CORS) para servicios de Azure Storage.

En el ejemplo de código siguiente se muestra cómo configurar blob service para permitir que JavaScript que se ejecuta en el dominio contoso acceda a un blob en el servicio 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);

Error de red

En algunas circunstancias, la pérdida de paquetes de red puede provocar que el servicio de almacenamiento devuelva mensajes HTTP 404 al cliente. Por ejemplo, cuando la aplicación cliente elimina una entidad del servicio de tabla, verá que el cliente inicia una excepción de almacenamiento que informa de un mensaje de estado "HTTP 404 (no encontrado)" desde table service. Al investigar la tabla en el servicio de almacenamiento de tablas, verá que el servicio eliminó la entidad según lo solicitado.

Los detalles de la excepción en el cliente incluyen el identificador de solicitud (7e84f12d...) asignado por table service para la solicitud: puede usar esta información para buscar los detalles de la solicitud en los registros de recursos de almacenamiento en Azure Monitor mediante la búsqueda en Campos que describen cómo se autenticó la operación de las entradas de registro. También puede usar las métricas para identificar cuándo se producen errores como este y, a continuación, buscar en los archivos de registro en función del momento en que las métricas registraron este error. Esta entrada de registro muestra que se produjo un error en la eliminación con un mensaje de estado "HTTP (404) Client Other Error". La misma entrada de registro también incluye el identificador de solicitud generado por el cliente en la client-request-id columna (813ea74f...).

El registro del lado servidor también incluye otra entrada con el mismo client-request-id valor (813ea74f...) para una operación de eliminación correcta para la misma entidad y desde el mismo cliente. Esta operación de eliminación correcta tuvo lugar poco antes de que se produjera un error en la solicitud de eliminación.

La causa más probable de este escenario es que el cliente envió una solicitud de eliminación para la entidad a Table Service, que se realizó correctamente pero no recibió una confirmación del servidor (quizás debido a un problema de red temporal). A continuación, el cliente reintentó automáticamente la operación (con el mismo client-request-id) y se produjo un error en este reintento porque la entidad ya se había eliminado.

Si este problema se produce con frecuencia, debe investigar por qué el cliente no recibe confirmaciones de Table Service. Si el problema es intermitente, debe interceptar el error "HTTP (404) No encontrado" y registrarlo en el cliente, pero permitir que el cliente continúe.

El cliente recibe mensajes HTTP 409 (conflicto)

Cuando un cliente elimina contenedores de blobs, tablas o colas, hay un breve período antes de que el nombre vuelva a estar disponible. Si el código de la aplicación cliente elimina y, a continuación, vuelve a crear inmediatamente un contenedor de blobs con el mismo nombre, el CreateIfNotExists método producirá un error HTTP 409 (conflicto).

La aplicación cliente debe usar nombres de contenedor únicos cada vez que cree nuevos contenedores si el patrón de eliminación o recreación es común.

Las métricas muestran que las entradas de registro percentSuccess o analytics bajas tienen operaciones con el estado de transacción ClientOtherErrors.

Una dimensión ResponseType igual a un valor de Success captura el porcentaje de operaciones que se realizaron correctamente en función de su código de estado HTTP. Las operaciones con códigos de estado de 2XX cuentan como correctas, mientras que las operaciones con códigos de estado en los intervalos 3XX, 4XX y 5XX se cuentan como incorrectas y reducen el valor de la métrica Success. En los registros de recursos de almacenamiento, estas operaciones se registran con un estado de transacción de ClientOtherError.

Estas operaciones se han completado correctamente y, por tanto, no afectan a otras métricas, como la disponibilidad. Algunos ejemplos de operaciones que se ejecutan correctamente, pero que pueden dar lugar a códigos de estado HTTP incorrectos, incluyen:

  • ResourceNotFound (no encontrado 404), por ejemplo, de una solicitud GET a un blob que no existe.
  • ResourceAlreadyExists (conflicto 409), por ejemplo, de una CreateIfNotExist operación donde el recurso ya existe.
  • ConditionNotMet (No modificado 304), por ejemplo, desde una operación condicional como cuando un cliente envía un ETag valor y un encabezado HTTP If-None-Match para solicitar una imagen solo si se ha actualizado desde la última operación.

Puede encontrar una lista de códigos de error comunes de la API REST que los servicios de almacenamiento devuelven en la página Códigos de error comunes de la API REST.

Vea también

Ponte en contacto con nosotros para obtener ayuda

Si tiene preguntas o necesita ayuda, cree una solicitud de soporte o busque consejo en la comunidad de Azure. También puede enviar comentarios sobre el producto con los comentarios de la comunidad de Azure.