Partilhar via


Solucionar problemas de erros de aplicativo cliente em contas de armazenamento do Azure

Este artigo ajuda você a investigar erros do aplicativo cliente por meio de métricas, logs do lado do cliente e logs de recursos no Azure Monitor.

Diagnóstico de erros

Usuários do seu aplicativo podem notificá-lo de erros registrados pelo aplicativo do cliente. O Azure Monitor também registra contagens de diferentes tipos de resposta (dimensões ResponseType ) de seus serviços de armazenamento, como NetworkError, ClientTimeoutError ou AuthorizationError. Enquanto o Azure Monitor apenas registra as contagens de diferentes tipos de erros, você pode obter mais detalhes sobre solicitações individuais ao examinar os logs do servidor, do cliente e da rede. Normalmente, o código de status HTTP que voltam para o serviço de armazenamento darão uma indicação da razão da falha da solicitação.

Observação

Lembre-se de que você deve esperar ver alguns erros intermitentes. Por exemplo, erros devido a condições de rede transitórias ou erros de aplicativo.

Os seguintes recursos são úteis para compreender os status relacionados a armazenamento e os códigos de erro:

O cliente está recebendo mensagens HTTP 403 (Proibido)

Se o seu aplicativo do cliente está emitindo erros HTTP 403 (Proibido), uma possível causa é que o cliente esteja usando uma assinatura de acesso compartilhado (SAS) expirada quando envia uma solicitação de armazenamento (embora outras causas possíveis incluem distorção de relógio, chaves inválidas e cabeçalhos vazios).

A biblioteca do cliente de armazenamento para .NET habilita você a coletar dados de log do cliente relacionados as operações de armazenamento realizadas pelo seu aplicativo. Para saber mais, consulte Registro em log no lado do cliente com a biblioteca do cliente de armazenamento para .NET.

A tabela a seguir mostra um exemplo de log do lado do cliente gerado pela biblioteca do cliente de armazenamento que ilustra esse problema acontecendo:

Fonte Detalhamento Detalhamento ID de solicitação do cliente Texto de operação
Microsoft.Azure.Storage Informações 3 85d077ab-… Starting operation with location Primary per location mode PrimaryOnly.
Microsoft.Azure.Storage Informações 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 Informações 3 85d077ab -… Waiting for response.
Microsoft.Azure.Storage Aviso 2 85d077ab -… Exception thrown while waiting for response: The remote server returned an error: (403) Forbidden.
Microsoft.Azure.Storage Informações 3 85d077ab -… Response received. Status code = 403, Request ID = <Request ID>, Content-MD5 = , ETag = .
Microsoft.Azure.Storage Aviso 2 85d077ab -… Exception thrown during the operation: The remote server returned an error: (403) Forbidden..
Microsoft.Azure.Storage Informações 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 Informações 3 85d077ab -… The next location has been set to Primary, based on the location mode.
Microsoft.Azure.Storage Erro 1 85d077ab -… Retry policy did not allow for a retry. Failing with The remote server returned an error: (403) Forbidden.

Nesse cenário, você deve investigar porque o token de SAS está expirando antes do cliente enviar o token para o servidor:

  • Normalmente, você não deve definir uma hora de início ao criar uma SAS para um cliente usar imediatamente. Se houver pequenas diferenças entre os relógios do host que gera o SAS usando o horário atual e o serviço de armazenamento, então é possível que o serviço de armazenamento receba uma SAS que não seja válida.

  • Não defina um tempo de expiração muito curto em uma SAS. Novamente, pequenas diferenças de relógio entre o host que gera a SAS e o serviço de armazenamento podem fazer com que uma SAS expire mais cedo do que o esperado.

  • O parâmetro version na chave SAS (por exemplo, sv=2015-04-05) corresponde à versão da Biblioteca de Cliente de Armazenamento que você está usando? Recomendamos usar sempre a versão mais recente da biblioteca do cliente de armazenamento.

  • Se você regenerar suas chaves de acesso de armazenamento, isso poderá invalidar quaisquer tokens de SAS existentes. Esse problema poderá surgir se você gerar tokens de SAS com um tempo de expiração longo para aplicativos de cliente para o cache.

Se você estiver usando a biblioteca do cliente de armazenamento para gerar tokens de SAS, então será fácil compilar um token válido. Entretanto, se você estiver usando a API REST de Armazenamento e criando tokens de SAS manualmente, consulte Delegando acesso com uma Assinatura de Acesso Compartilhado.

O cliente está recebendo mensagens HTTP 404 (Não encontrado)

Se o aplicativo cliente recebe uma mensagem HTTP 404 (Não encontrado) do servidor, isso implica que o objeto do cliente estava tentando usar (tais como: uma entidade, tabela, blob, contêiner ou fila) não existe no serviço de armazenamento. Existem muitas razões para isso, tais como:

  • O cliente ou outro processo excluiu anteriormente o objeto.

  • Um problema de autorização SAS (Assinatura de Acesso Compartilhado).

  • O código JavaScript do lado do cliente não tem permissão para acessar o objeto.

  • Falha de rede.

O cliente ou outro processo excluiu anteriormente o objeto

Em cenários em que o cliente está tentando ler, atualizar ou excluir dados em um serviço de armazenamento, é fácil identificar nos logs de recursos de armazenamento uma operação anterior que excluiu o objeto em questão do serviço de armazenamento. Frequentemente, os dados de log mostram que um outro usuário ou processo excluiu o objeto. Os logs do Azure Monitor (do lado do servidor) mostram quando um cliente excluiu um objeto.

No cenário em que um cliente está tentando inserir um objeto, pode não ser imediatamente óbvio por que isso resulta em uma resposta HTTP 404 (Não encontrado), já que o cliente está criando um novo objeto. No entanto, se o cliente estiver criando um blob, ele deverá ser capaz de localizar o contêiner de blob. Se o cliente estiver criando uma mensagem, ele deverá ser capaz de localizar uma fila. E se o cliente estiver adicionando uma linha, ele deve ser capaz de encontrar a tabela.

Você pode usar o log do lado do cliente da Biblioteca de Cliente de Armazenamento para entender melhor quando o cliente envia solicitações específicas para o serviço de armazenamento.

O log do lado do cliente a seguir gerado pela biblioteca do Cliente de Armazenamento ilustra o problema quando o cliente não consegue encontrar o contêiner para o blob que está criando. Esse log inclui detalhes das seguintes operações de armazenamento:

ID de solicitação Operação
07b26a5d-... DeleteIfExists para excluir o contêiner de blob. Essa operação inclui uma solicitação HEAD para verificar a existência do contêiner.
e2d06d78… CreateIfNotExists para criar o contêiner de blob. Essa operação inclui uma HEAD solicitação que verifica a existência do contêiner. O retorna HEAD uma mensagem 404, mas continua.
de8b1c3c-... UploadFromStream para criar o blob. A PUT solicitação falha com uma mensagem 404

Entradas de log:

ID de solicitação Texto de operação
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..

Neste exemplo, o log mostra que o cliente está intercalando solicitações do método (ID de CreateIfNotExists solicitação e2d06d78...) com as UploadFromStream solicitações do método (de8b1c3c-...). Essa intercalação ocorre porque o aplicativo cliente está invocando esses métodos de forma assíncrona. Modifique o código assíncrono no cliente para garantir que ele crie o contêiner antes de tentar carregar qualquer dado para o blob nesse contêiner. Idealmente, crie todos os contêineres antes.

Um problema de autorização de assinatura de acesso compartilhado (SAS)

Se o aplicativo cliente tentar usar uma chave de SAS que não inclui as permissões necessárias para a operação, o serviço de armazenamento retorna uma mensagem HTTP 404 (Não encontrado) para o cliente. Ao mesmo tempo, nas métricas do Azure Monitor, você também verá um AuthorizationError para a dimensão ResponseType .

Investigue por que seu aplicativo cliente está tentando executar uma operação para a qual não recebeu permissões.

O código JavaScript do lado do cliente não tem permissão para acessar o objeto

Se você estiver usando um cliente JavaScript e o serviço de armazenamento estiver retornando mensagens HTTP 404, verifique os seguintes erros de JavaScript no navegador:

SEC7120: Origem http://localhost:56309 não encontrada no cabeçalho Access-Control-Allow-Origin.
SCRIPT7002: XMLHttpRequest: Erro de rede 0x80070005, acesso negado.

Observação

Você pode usar as Ferramentas para Desenvolvedores F12 no Internet Explorer para rastrear as mensagens trocadas entre o navegador e o serviço de armazenamento quando você estiver solucionando os problemas JavaScript do lado do cliente.

Esses erros acontecem porque o navegador da Web implementa a restrição de segurança de política de mesma origem , que impede uma página da Web de chamar uma API em um domínio diferente do domínio de onde a página vem.

Para contornar o problema do JavaScript, você pode configurar o CORS (Cross-Origin Resource Sharing) para o serviço de armazenamento que o cliente está acessando. Para saber mais, veja Suporte de CORS (Compartilhamento de Recursos entre Origens) para os Serviços de Armazenamento do Azure.

O código a seguir mostra como configurar seu serviço blob para permitir que o JavaScript execute o domínio Contoso para acessar um blob no seu serviço de armazenamento 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);

Falha de rede

Em algumas circunstâncias, os pacotes de rede perdidos podem levar o serviço de armazenamento a retornar mensagens HTTP 404 para o cliente. Por exemplo, quando seu aplicativo cliente está excluindo uma entidade do serviço de tabela, você vê o cliente lançar uma exceção de armazenamento relatando uma mensagem de status "HTTP 404 (Não Encontrado)" do serviço de tabela. Quando você investiga a tabela no serviço de armazenamento da tabela, é possível ver que o serviço excluiu a entidade como solicitado.

Os detalhes da exceção no cliente incluem a ID da solicitação (7e84f12d...) atribuída pelo serviço de tabela para a solicitação: você pode usar essas informações para localizar os detalhes da solicitação nos logs de armazenamento do servidor no Azure Monitor pesquisando em Campos que descrevem como a operação foi autenticada nas entradas do log. Você pode também usar as métricas para identificar quando falhas como essa ocorrem e pesquisar os arquivos de log com base no horário que as métricas registraram esse erro. Essa entrada de log mostram a falha excluída com uma mensagem de status "HTTP (404) Outro Erro do Cliente". A mesma entrada de log também inclui a ID da solicitação gerada pelo cliente na client-request-id coluna (813ea74f...).

O log do lado do servidor também inclui outra entrada com o mesmo client-request-id valor (813ea74f...) para uma operação de exclusão bem-sucedida para a mesma entidade e do mesmo cliente. Essa operação de exclusão bem-sucedida ocorreu pouco antes da solicitação de exclusão com falha.

A causa mais provável desse cenário é que o cliente enviou uma solicitação de exclusão da entidade para o serviço tabela, que foi bem-sucedida, mas não recebeu uma confirmação do servidor (talvez devido a um problema temporário de rede). Em seguida, o cliente repetiu automaticamente a operação (usando o mesmo client-request-id) e essa nova tentativa falhou porque a entidade já havia sido excluída.

Se esse problema ocorre com frequência, investigue porque o cliente não está recebendo as confirmações do serviço de tabela. Se o problema for intermitente, intercepte o erro "HTTP (404) Não encontrado" e log no cliente, mas permita que o cliente continue.

O cliente está recebendo mensagens HTTP 409 (Conflito)

Quando um cliente exclui contêineres, tabelas ou filas de blob, há um breve período antes que o nome fique disponível novamente. Se o código em seu aplicativo cliente excluir e recriar imediatamente um contêiner de blob usando o mesmo nome, o CreateIfNotExists método eventualmente falhará com o erro HTTP 409 (Conflito).

O aplicativo do cliente deve usar nomes de contêiner exclusivos sempre que criar novos contêineres caso o padrão excluir/recriar for comum.

As métricas mostram uma baixa PercentSuccess ou as entradas de log analíticas têm operações com status de transação de ClientOtherErrors

Uma dimensão ResponseType igual a um valor de Sucesso captura a porcentagem de operações que foram bem-sucedidas com base em seu código de status HTTP. As operações com códigos de status de 2XX contam como bem-sucedidas, enquanto as operações com códigos de status nos intervalos 3XX, 4XX e 5XX são contadas como malsucedidas e reduzem o valor da métrica Êxito. Nos arquivos de log do armazenamento, essas operações são registradas com um status de transação de ClientOtherErrors.

Essas operações foram concluídas com êxito e, portanto, não afetam outras métricas, como disponibilidade. Alguns exemplos de operações que executam com sucesso, mas que podem resultar em códigos de status HTTP sem sucesso incluem:

  • ResourceNotFound (Not Found 404), por exemplo, de uma solicitação GET para um blob que não existe.
  • ResourceAlreadyExists (Conflito 409), por exemplo, de uma CreateIfNotExist operação em que o recurso já existe.
  • ConditionNotMet (Not Modified 304), por exemplo, de uma operação condicional, como quando um cliente envia um ETag valor e um cabeçalho HTTP If-None-Match para solicitar uma imagem somente se ela tiver sido atualizada desde a última operação.

Você pode encontrar uma lista de códigos de erro comuns da API REST que os serviços de armazenamento retornam na página Códigos de erro comuns da API REST.

Confira também

Entre em contato conosco para obter ajuda

Se você tiver dúvidas ou precisar de ajuda, crie uma solicitação de suporte ou peça ajuda à comunidade de suporte do Azure. Você também pode enviar comentários sobre o produto para a comunidade de comentários do Azure.