Compartir vía


Solución 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

Puede que los usuarios de la aplicación le notifiquen los errores de los que informa 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. Si bien Azure Monitor solamente registra los recuentos de diversos tipos de errores, puede obtener más detalles sobre cada una de las solicitudes examinando los registros del lado servidor, del lado cliente y de la red. Normalmente, el código de estado HTTP que devuelva el servicio de almacenamiento aportará una indicación del motivo de error en la solicitud.

Nota:

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

Los siguientes recursos resultan útiles para entender los códigos de error y estado relacionados con el almacenamiento:

El cliente recibe mensajes HTTP 403 (prohibido)

Si la aplicación cliente inicia errores HTTP 403 (prohibido), uno de los motivos más probables es que el cliente esté usando una Firma de acceso compartido (SAS) expirada al enviar una solicitud de almacenamiento (aunque hay otras causas posibles, como un sesgo del reloj, que las claves no sean válidas o que los encabezados estén vacíos).

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

En la siguiente tabla, puede ver una muestra del registro del lado cliente generado por la biblioteca de cliente de Almacenamiento que ilustra este problema:

Source Nivel de detalle Nivel de detalle Id. de solicitud de cliente Texto de operación
Microsoft.Azure.Storage Información 3 85d077ab-… Starting operation with location Primary per location mode PrimaryOnly.
Microsoft.Azure.Storage Información 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 Información 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 Información 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 Información 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 Información 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 el motivo por el que el token de SAS expira antes de que el cliente envíe el token al servidor:

  • Normalmente, no debe establecer una hora de inicio cuando cree una SAS para que un cliente lo use inmediatamente. Si existen pequeñas diferencias entre el reloj del host que genera la SAS y que usa la hora actual, por una parte, y el del servicio de almacenamiento, por otra, es posible que el servicio de almacenamiento reciba una SAS que todavía no es válida.

  • No establezca un tiempo de expiración muy corto en una SAS. También en este caso, si existen pequeñas diferencias entre el reloj del host que genera la SAS y el del servicio de almacenamiento, puede que la SAS expire, antes de lo que se esperaba.

  • ¿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 está usando? Recomendamos usar la última versión de la biblioteca de cliente de Storage.

  • Si vuelve a generar las claves de acceso de almacenamiento, esto puede invalidar todos los token de SAS existentes. Este problema puede producirse si genera tokens de SAS con un tiempo de expiración duradero para que los copien en caché las aplicaciones cliente.

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

El cliente recibe mensajes HTTP 404 (no encontrado)

Si la aplicación cliente recibe un mensaje HTTP 404 (No encontrado) del servidor, significa que el objeto que estaba tratando de usar el cliente (por ejemplo, una entidad, una tabla, un blob, un contenedor o una cola) no existe en el servicio de almacenamiento. Hay varios motivos posibles, por ejemplo:

  • El cliente u otro proceso eliminaron anteriormente el objeto

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

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

  • Error de red.

El cliente u otro proceso eliminaron anteriormente 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 una operación anterior que eliminó el objeto en cuestión del servicio de almacenamiento. A menudo, los datos de registro indican que otro usuario u otro proceso eliminaron el objeto. Los registros de Azure Monitor (servidor) se muestran cuando un cliente eliminó un objeto.

En el escenario en el que un cliente está intentando insertar un objeto, es posible que no sea evidente inmediatamente por qué se produce una respuesta HTTP 404 (no encontrada), 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 encuentra 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 método 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 método para crear el blob. Se produce un error en la PUT solicitud con un mensaje 404

Entradas del registro:

Id. de solicitud Texto de 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 las solicitudes del CreateIfNotExists método (id. de solicitud e2d06d78...) con las solicitudes del UploadFromStream método (de8b1c3c-...). Esta intercalación se produce porque la aplicación cliente invoca estos métodos de forma asincrónica. Modifique el código asincrónico del cliente para que cree el contenedor antes de tratar de cargar datos en un blob de ese contenedor. Lo ideal es que cree todos los contenedores de antemano.

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

Si la aplicación cliente trata de usar una clave SAS que no incluye los permisos necesarios para realizar 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á authorizationError para la dimensión ResponseType.

Investigue por qué la aplicación cliente está intentando 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 de JavaScript y el servicio de almacenamiento devuelve mensajes HTTP 404, compruebe los siguientes errores de JavaScript en el explorador:

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

Nota:

Puede usar las Herramientas de desarrollo F12 de Internet Explorer para realizar un seguimiento de los mensajes que se intercambian 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 restricción de seguridad directiva del mismo origen , que impide que una página web llame a una API de un dominio que no sea el dominio del que proviene 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 accede el cliente. Para más información, consulte Compatibilidad con Uso compartido de recursos entre orígenes (CORS) para los Servicios de Azure Storage.

El siguiente ejemplo de código muestra cómo configurar el servicio BLOB para permitir que el JavaScript que se ejecuta en el dominio Contoso acceda a un BLOB de su servicio de almacenamiento de 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);

Error de red

En algunas circunstancias, la pérdida de paquetes de red puede hacer que el servicio de almacenamiento devuelva mensajes HTTP 404 al cliente. Por ejemplo, cuando la aplicación cliente elimina una entidad del servicio table, verá que el cliente produce una excepción de almacenamiento que informa de un mensaje de estado "HTTP 404 (no encontrado)" del servicio table. Al investigar la tabla del servicio de almacenamiento de tabla, ve que el servicio sí que eliminó la entidad, como se solicitó.

Los detalles de la excepción del cliente incluyen el identificador de solicitud (7e84f12d...) que asigna Table service para la solicitud: puede usar esta información para localizar los detalles de solicitud en los registros del recurso de almacenamiento en Azure Monitor, buscando en los campos de las entradas del registro que describen cómo se autenticó la operación. También podría utilizar las métricas para identificar cuándo se producen errores como este y, luego, buscar los archivos de registro teniendo en cuenta el momento en el que las métricas registraron este error. Esta entrada de registro muestra que la eliminación no se realizó correctamente y produjo el mensaje de estado “HTTP (404) Otro error del cliente”. 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 la solicitud de eliminación con error.

La causa más probable de este escenario es que el cliente envió una solicitud de eliminación para la entidad al servicio table, 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 este reintento produjo un error porque la entidad ya se había eliminado.

Si este problema se produce a menudo, debe investigar por qué el cliente no recibe correctamente las confirmaciones del 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, tablas o colas de blobs, 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 produce un error HTTP 409 (conflicto).

La aplicación cliente debe usar nombres de contenedor únicos siempre que cree nuevos contenedores si el patrón eliminar / volver a crear es común.

Las métricas muestran un PercentSuccess bajo o las entradas de registro de análisis 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 intervalos 3XX, 4XX y 5XX se cuentan como incorrectos y reducen el valor de la métrica Success. En los registros del recurso de almacenamiento, estas operaciones se registran con el estado de transacción ClientOtherError.

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

  • ResourceNotFound (no encontrado 404), por ejemplo, desde una solicitud GET a un blob que no existe.
  • ResourceAlreadyExists (Conflicto 409), por ejemplo, desde una CreateIfNotExist operación en la que 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 habituales de la API de REST que devuelven los servicios de almacenamiento en la página Códigos de error comunes de la API de REST.

Consulte 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.