MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Problemas de conexão do MongoDB no Azure


Alguns milhares de solicitações por minuto são um grande load, e a única maneira de fazer isso direito, é controlando e limitando o número máximo de threads que podem estar sendo executados a qualquer momento.

Como não há muita informação postada sobre como você implementou isso. Vou cobrir algumas circunstâncias possíveis.

Hora de experimentar...


As constantes:
  • Itens a serem processados:
    • 50 por segundo , ou em outras palavras...
    • 3.000 por minuto , e mais uma maneira de ver isso...
    • 180.000 por hora

As variáveis:

  • Taxas de transferência de dados:

    • A quantidade de dados que você pode transferir por segundo desempenhará um papel, não importa o que façamos, e isso varia ao longo do dia, dependendo da hora do dia.

      A única coisa que podemos fazer é disparar mais solicitações de diferentes CPUs para distribuir o peso do tráfego que estamos enviando de volta.

  • Poder de processamento:

    • Estou assumindo que você tem isso em um WebJob em vez de ter isso codificado dentro do site MVC, é ele mesmo. É altamente ineficiente e inadequado para o propósito que você está tentando alcançar. Ao usar um WebJob, podemos enfileirar itens de trabalho a serem processados ​​por outros WebJobs . A fila em questão é o Azure Queue Armazenamento .

Os problemas:
  • Estamos tentando concluir 50 transações por segundo, portanto, cada transação deve ser feita em menos de 1 segundo se estivermos utilizando 50 threads. Nosso tempo limite de 45 segundos não serve para nada neste momento.
  • Esperamos que 50 threads sejam executados simultaneamente e todos sejam concluídos em menos de um segundo, a cada segundo, em uma única CPU. (Estou exagerando um ponto aqui, só para fazer um ponto... mas imagine baixar 50 arquivos de texto a cada segundo. Processá-lo e depois tentar enviá-lo de volta para um colega na esperança de que eles estejam prontos para pegue-o)
  • Precisamos ter uma lógica de repetição, se após 3 tentativas o item não for processado, ele precisará ser colocado de volta na fila. Idealmente, devemos fornecer mais tempo para o servidor responder do que apenas um segundo a cada falha, digamos que demos uma pausa de 2 segundos na primeira falha, depois 4 segundos, depois 10, isso aumentará muito as chances de persistirmos / recuperando os dados que precisávamos.
  • Estamos assumindo que nosso MongoDb pode lidar com esse número de solicitações por segundo. Se você ainda não o fez, comece a procurar maneiras de escaloná-lo, o problema não está no fato de ser um MongoDb, a camada de dados pode ter sido qualquer coisa, é o fato de estarmos fazendo esse número de solicitações de uma única fonte que será a causa mais provável de seus problemas.

A solução:
  1. Configurar um WebJob e nomeie-o EnqueueJob . Este WebJob terá um único propósito, enfileirar itens de trabalho a serem processados ​​no Queue Storage .
  2. Crie um Queue Storage Container chamado WorkItemQueue , essa fila funcionará como um gatilho para a próxima etapa e iniciará nossas operações de expansão.
  3. Crie outro WebJob chamado DequeueJob . Este WebJob também terá um único propósito, desenfileirar os itens de trabalho do WorkItemQueue e dispare as solicitações para seu armazenamento de dados.
  4. Configure o DequeueJob para girar assim que um item for colocado dentro da WorkItemQueue , inicie 5 encadeamentos separados em cada um e enquanto a fila não estiver vazia, desenfileirar itens de trabalho para cada encadeamento e tentar executar o trabalho desenfileirado.
    1. Tentativa 1, se falhar, aguarde e tente novamente.
    2. Tentativa 2, se falhar, aguarde e tente novamente.
    3. Tentativa 3, se falhar, enfileira o item de volta para WorkItemQueue
  5. Configure seu site para dimensionar automaticamente para x quantidade de CPU (observe que seu site e trabalhos da Web compartilham os mesmos recursos)

Aqui está um vídeo curto de 10 minutos que fornece uma visão geral sobre como utilizar armazenamentos de filas e trabalhos da web.

Editar:

Outra razão pela qual você pode estar recebendo esses erros pode ser por causa de dois outros fatores, novamente causados ​​por estar em um aplicativo MVC ...

Se você estiver compilando o aplicativo com o DEBUG atributo aplicado, mas empurrando o RELEASE em vez disso, você pode ter problemas devido às configurações em seu web.config , sem o DEBUG atributo, um aplicativo Web ASP.NET executará uma solicitação por no máximo 90 segundos, se a solicitação demorar mais do que isso, ela descartará a solicitação.

Para aumentar o tempo limite para mais de 90 segundos você precisará alterar o [httpRuntime][3] propriedade em seu web.config ...
<!-- Increase timeout to five minutes -->
<httpRuntime executionTimeout="300" />

A outra coisa que você precisa estar ciente são as configurações de tempo limite de solicitação do seu navegador> aplicativo da web, eu diria que se você insistir em manter o código no MVC em vez de extraí-lo e colocá-lo em um WebJob, então você pode usar o código a seguir para disparar uma solicitação para seu aplicativo Web e compensar o tempo limite da solicitação.
string html = string.Empty;
string uri = "http://google.com";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Timeout = TimeSpan.FromMinutes(5);

using (HttpWebResponse response = (HttpWebResonse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
    html = reader.ReadToEnd();
}