Mongoose: Nenhum servidor primário disponível

Criado em 1 dez. 2015  ·  76Comentários  ·  Fonte: Automattic/mongoose

Eu tenho um problema que é bastante difícil de depurar e queria saber se alguém vê algo errado com minha configuração.

Error no primary server available

Versão do Nodejs 4.2.1 e versão do mongoDB 3.0.7 com mangusto 4.2.8 .

Isso parece acontecer aleatoriamente e abrirá muitas conexões até que eu finalmente reinicie o processo de nó. O cluster está íntegro em todos os momentos durante esse erro . Este erro ocorre centenas de vezes por hora. Não parece haver consistência quanto ao momento em que o erro começará. Por exemplo, ocorre quando o cluster está operando normalmente e nenhuma alteração no primário foi feita.

É assim que as estatísticas do banco de dados se parecem. Como você pode ver, o número de conexões aumentará constantemente. Se eu matar o processo do nó e iniciar um novo, tudo ficará bem.

screen shot 2015-11-30 at 5 21 01 pm

Config

  // Connect
  mongoose.connect(config.mongo.connectionString, {
    server: {
      socketOptions: {
        socketTimeoutMS: 5 * 60 * 1000,
        keepAlive: 1
      }
    },
    replset: {
      socketOptions: {
        socketTimeoutMS: 5 * 60 * 1000,
        keepAlive: 1
      }
    }
  });

String de conexão

mongodb://username:[email protected]:27000,mongo-2.cz.0200.mongodbdns.com:27000,mongo-3.cz.0200.mongodbdns.com:27000/dbase

Rastreamento de pilha

node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/replset.js:860pickServer    
node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/replset.js:437command   
node_modules/mongoose/node_modules/mongodb/lib/replset.js:392command    
node_modules/mongoose/node_modules/mongodb/lib/db.js:281executeCommand  
node_modules/mongoose/node_modules/mongodb/lib/db.js:305command 
node_modules/newrelic/lib/instrumentation/mongodb.js:177wrapped 
node_modules/mongoose/node_modules/mongodb/lib/collection.js:2327findAndModify  
node_modules/mongoose/node_modules/mongodb/lib/collection.js:2265findAndModify  
node_modules/newrelic/lib/instrumentation/mongodb.js:177wrapped [as findAndModify]  
node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:136(anonymous function) [as findAndModify]  
node_modules/mongoose/node_modules/mquery/lib/collection/node.js:79findAndModify    
node_modules/mongoose/lib/query.js:1833_findAndModify   
node_modules/mongoose/lib/query.js:1621_findOneAndUpdate    
node_modules/mongoose/node_modules/kareem/index.js:156none  
node_modules/mongoose/node_modules/kareem/index.js:18none
can't reproduce help wanted

Todos 76 comentários

Nada salta no momento. Tem certeza de que nenhum dos servidores mongodb está travando? Além disso, você consegue manter uma conexão estável usando o shell?

Executar o comando db.runCommand( { replSetGetStatus : 1 } ) enquanto o erro estava ocorrendo produz "health" : 1, em todos os 3 nós. Há também um conjunto primário "stateStr" : "PRIMARY", em um dos nós.

Você está se conectando usando a mesma string de conexão, usando o DNS? Também parece que seu armazenamento se esgotou após o problema. Você pode verificar se ficou sem espaço no disco rígido em uma de suas máquinas?

Você está se conectando usando a mesma string de conexão, usando o DNS?

Eu não estava usando a mesma string de conexão. Você acha que usar os endereços IP privados do EC2 resolveria isso?

Não sei o que está fazendo com que o armazenamento chegue ao máximo assim, mas mesmo depois de inicializar novas instâncias, o problema sem servidores primários ainda ocorre com muito espaço disponível.

Os endereços IP EC2 podem ajudar, dependendo de como o conjunto de réplicas está configurado. Você pode me mostrar a saída de rs.status() do shell ?

Este é o rs.status () enquanto as conexões estão aumentando.

{
    "set" : "mongo2",
    "date" : ISODate("2015-12-04T23:39:32.520Z"),
    "myState" : 1,
    "members" : [
        {
            "_id" : 6,
            "name" : "mongo-8.loc.0600.mongodbdns.com:27000",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 444053,
            "optime" : Timestamp(1449272372, 32),
            "optimeDate" : ISODate("2015-12-04T23:39:32Z"),
            "lastHeartbeat" : ISODate("2015-12-04T23:39:32.507Z"),
            "lastHeartbeatRecv" : ISODate("2015-12-04T23:39:31.442Z"),
            "pingMs" : 0,
            "syncingTo" : "mongo-9.loc.0600.mongodbdns.com:27000",
            "configVersion" : 29
        },
        {
            "_id" : 7,
            "name" : "mongo-9.loc.0600.mongodbdns.com:27000",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 444056,
            "optime" : Timestamp(1449272372, 39),
            "optimeDate" : ISODate("2015-12-04T23:39:32Z"),
            "electionTime" : Timestamp(1449097485, 1),
            "electionDate" : ISODate("2015-12-02T23:04:45Z"),
            "configVersion" : 29,
            "self" : true
        },
        {
            "_id" : 8,
            "name" : "mongo-10.loc.0600.mongodbdns.com:27000",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 444053,
            "optime" : Timestamp(1449272371, 111),
            "optimeDate" : ISODate("2015-12-04T23:39:31Z"),
            "lastHeartbeat" : ISODate("2015-12-04T23:39:31.904Z"),
            "lastHeartbeatRecv" : ISODate("2015-12-04T23:39:30.903Z"),
            "pingMs" : 2,
            "syncingTo" : "mongo-8.loc.0600.mongodbdns.com:27000",
            "configVersion" : 29
        }
    ],
    "ok" : 1
}

Nada fora do comum no conjunto de réplicas. Você tem outros exemplos de código relevantes, por exemplo, algum código que está reagindo a eventos de conexão do mangusto?

Outro problema potencial que vale a pena considerar: você está usando um novo agente de relíquias atualizado? Eu tentaria correr sem nova relíquia e ver se isso ainda acontecia, o novo macaco-relíquia corrige o driver mongodb de forma que às vezes pode levar a um comportamento inesperado.

Estamos enviando os eventos de conexão do mangusto:

['connecting', 'connected', 'open', 'disconnecting', 'disconnected', 'close', 'reconnected', 'error', 'fullsetup'].forEach(function(name) {
  mongoose.connection.on(name, function() {
    notifySlack('Mongoose event: ' + name);
  });
});

Esta é a aparência de alguns registros

​[4:30] Mongoose event: fullsetup
​[4:30] Mongoose event: reconnected
​[4:30] Mongoose event: open
​[4:30] Mongoose event: connected
​[4:30] Mongoose event: reconnected
​[4:30] Mongoose event: reconnected
​[4:30] Mongoose event: reconnected
​[4:30] Mongoose event: reconnected
​[4:30] Mongoose event: reconnected
​[4:30] Mongoose event: reconnected
​[4:30] Mongoose event: fullsetup
​[4:30] Mongoose event: connected
​[4:30] Mongoose event: open
​[4:30] 
{
 "err": {
   "name": "MongoError",
   "message": "no primary server available"
 }
}

Eu estive no evento mongodb days esta semana, onde pude agendar algum tempo e mostrar esse problema para um dos engenheiros seniores do MongoDB, e eles não tinham certeza de qual era o problema. Eles mencionaram adicionar o conjunto de replicação e o tamanho máximo do pool à string de conexão, o que infelizmente não resolveu esse problema.

Também tentamos desativar o keep alive e configurá-lo com um valor menor nas instâncias, mas isso também não pareceu resolver o problema.

Estamos usando newrelic version 1.24.0 , e mongo-express-patch version 0.21.1 . Vou tentar executar sem newrelic para ver se isso resolve o problema.

Hmm sim, parece que o mangusto está se reconectando por algum motivo. Você pode me mostrar a saída de npm list | grep "mongoose" e npm list | grep "mongo" ?

$ npm list | grep "mongoose"
├─┬ [email protected]
$ npm list | grep "mongo"
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
├─┬ [email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]

Para que você está usando mongodb-core ? Além disso, você está executando com mongo-express habilitado no prod?

Atualmente não está usando mongodb-core para nada. Você acha que a incompatibilidade de versão entre a dependência do mangusto pode estar causando problemas?

Temos mongo-express habilitado em produção.

Não que eu saiba. Estou apenas tentando ver se há outras conexões com mongodb que podem estar contribuindo para esse problema. Pesquisei um pouco no Google - você está usando para a string de conexão os mesmos nomes DNS que aparecem em rs.status() ? De acordo com isso , você poderá ver problemas semelhantes se usar um DNS diferente para a string de conexão do que o seu conjunto de réplicas pensa.

Este erro ocorrerá ao usar o mesmo DNS na string de conexão que o atributo "syncingTo" em rs.status() . Também ocorre ao usar o IP ec2 interno na string de conexão.

A única coisa que não tentei ainda é apenas definir connectWithNoPrimary para true .

Eu também tentaria correr com mongo-express desconto também. Isso pode estar causando problemas ...

Estamos enfrentando o mesmo problema. Temos um site que está apresentando carga sustentada de cerca de 100 RPM com picos na ordem de 500-700 rpm +. Parece que vemos isso em todo o processo, mesmo durante períodos relativamente calmos.

Meio Ambiente:
Heroku - 75 dinamômetros 2x - Node.JS 5.1.1
Banco de dados - MongoLabs Dedicated Cluster M4 - Versão 3.0.7

String de conexão:
mongodb: // _: * _ @ ds043294-a0.mongolab. com: 43294 , ds043294-a1.mongolab. com: 43294 / heroku_hf8q79dt? replicaSet = rs-ds043294

NPM:

npm list | grep "mongoose"
├─┬ [email protected]
├── [email protected]
├── [email protected]
├─┬ [email protected]

Connection.js

// Mongoose import
var mongoose = require('mongoose');
var options = {
    server: {
        socketOptions: {
            keepAlive: 1,
            poolSize: 10,
            connectTimeoutMS: 30000,
            socketTimeoutMS: 30000
        }
    },
    replset: {
        socketOptions: {
            keepAlive: 1,
            poolSize: 10,
            connectTimeoutMS: 30000,
            socketTimeoutMS: 30000
        }
    }
};

mongoose.connect((process.env.MONGOLAB_URI || "mongodb://localhost/test"), options, function(error) {
    if (error) {
        console.log(error);
    }
});

module.exports = {
    mongoose: mongoose
};

Exploração madeireira:
Habilitamos uma boa quantidade de monitoramento para tentar depurar isso, então incluí nossos rastreamentos de pilha Raygun no evento que ajudaria a depurar. _Nota: _ Este é exatamente o mesmo número de linha que @ChrisZieba mostrou no rastreamento acima.

Mensagem: nenhum servidor primário disponível
Object.pickServer em /app/node_modules/mongodb-core/lib/topologies/replset.js:860
ReplSet.ReplSet.command em /app/node_modules/mongodb-core/lib/topologies/replset.js:437
ReplSet.ReplSet.command em /app/node_modules/mongodb/lib/replset.js:392
Object.executeCommand em /app/node_modules/mongodb/lib/db.js:281
Db.Db.command em /app/node_modules/mongodb/lib/db.js:305
Object.wrapped in /app/node_modules/newrelic/lib/instrumentation/mongodb.js:185
Object.findAndModify em /app/node_modules/mongodb/lib/collection.js:2327
Collection.Collection.findAndModify em /app/node_modules/mongodb/lib/collection.js:2265
Object.wrapped in /app/node_modules/newrelic/lib/transaction/tracer/index.js:155
Object.wrappedQuery em /app/node_modules/newrelic/lib/instrumentation/mongodb.js:218
Object.wrapped in [as findAndModify] (/app/node_modules/newrelic/lib/instrumentation/mongodb.js:188
NativeCollection.NativeCollection. (Anônimo em função) [as findAndModify] (/app/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:136
NodeCollection.NodeCollection.findAndModify em /app/node_modules/mquery/lib/collection/node.js:79
Query.Query._findAndModify em /app/node_modules/mongoose/lib/query.js:1833
Query.Query._findOneAndUpdate em /app/node_modules/mongoose/lib/query.js:1621
desconhecido. [anônimo] em /app/node_modules/kareem/index.js:156
desconhecido. [anônimo] em /app/node_modules/kareem/index.js:18
Object.wrapped in /app/node_modules/newrelic/lib/transaction/tracer/index.js:155
Object.doNTCallback0 em node.js: 430
process.process._tickCallback em node.js: 359

Monitoramento:
2015-12-09_22-22-51

Esse rastreamento de pilha realmente só me diz que 1) você está usando uma nova relíquia (o que é muito questionável, uma vez que a nova relíquia faz muitos macacos de correção do driver mongodb) e 2) o driver mongodb pensa que não há nenhum primário disponível, mas não sei por quê.

Tente ativar o modo de depuração do driver mongodb adicionando replset: { loggerLevel: 'debug' } às opções de conexão, ou seja:

var options = {
    server: {
        socketOptions: {
            keepAlive: 1,
            poolSize: 10,
            connectTimeoutMS: 30000,
            socketTimeoutMS: 30000
        }
    },
    replset: {
        loggerLevel: 'debug',
        socketOptions: {
            keepAlive: 1,
            poolSize: 10,
            connectTimeoutMS: 30000,
            socketTimeoutMS: 30000
        }
    }
};

Isso registrará muitos dados de depuração do driver no stdout e nos ajudará a descobrir o que está errado. Você pode capturar esses dados quando ocorrer o erro "Nenhum servidor primário encontrado"?

Obrigado @ vkarpov15 ,

Adicionamos isso e faremos um relatório assim que tivermos outro acionado.

Felicidades,
Roy

Não acho que newrelic seja o problema aqui. Tentamos executar sem ele e o problema persiste. Irá coletar alguns dados de log de loggerLevel: 'debug' e postar aqui.

Obrigado, deixe-me saber se você conseguir obter mais detalhes sobre o erro.

Outro ponto de dados: o Mongoose dispara o evento "reconectado" continuamente à medida que a contagem de conexões aumenta.

Os erros "nenhum servidor primário disponível" geralmente disparam _após_ o número de conexões já começar a aumentar.

Nós também enfrentamos esse problema. Com ter um aplicativo Node hospedado no Heroku com MongoLab.
Na semana passada, perdemos repentinamente a conexão com o banco de dados e continuamos recebendo a mensagem Error no primary server available . Reiniciar nosso aplicativo resolveu o problema.
Tanto o Heroku quanto o MonogLab não viram nada em seus registros.
Espero que alguém encontre uma solução para isso.

Bump - estamos vendo isso em node v4.2.3 mongoose v4.1.5 em uma grande implantação de produção. É difícil discutir esse problema, pois:

  • não apresenta erros de forma consistente, o que nos impede de agir (reiniciar o processo / tirar o nó)
  • acontece aleatoriamente e parece não correlacionado ao status de reposição do mongo

@sansmischevia você está usando mongolab + heroku também?

^ Estamos enfrentando esse problema em uma grande implantação de produção no AWS EC2 com servidores mongodb auto-hospedados por meio do Cloud Manager.

Olá,

Também gostaríamos de colaborar.
Estamos executando node v0.12.8 , mongo v2.6.11 com mongoose v4.1.11 .

$ npm list | grep "mongo"
├─┬ [email protected]
│ └─┬ [email protected]
│   ├─┬ [email protected]
├─┬ [email protected] 
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
└─┬ [email protected]
  └─┬ [email protected]
    ├─┬ [email protected]
$ npm list | grep "mongoose"
├─┬ [email protected]

Muitas vezes, é reproduzível durante uma operação que semeia o banco de dados, envolvendo muitas consultas. Nosso aplicativo parece não ser afetado depois que isso ocorre. Sem erros no log do mongo e nosso conjunto de réplicas de três nós está saudável durante esse tempo.

Tentaremos loggerLevel: 'debug' e apresentaremos um relatório.

@ vkarpov15 estamos em replsets mongolab + ec2 diretamente

Também estou enfrentando esse problema no mongolab.

Também estamos enfrentando esse problema no MongoLab e no Modulus.

dê uma olhada em https://jira.mongodb.org/browse/NODE-622 e se alguém puder fornecer um conjunto completo de logs, isso seria extremamente útil para que possamos reproduzi-lo.

Vou falar aqui, não estamos usando o mongoose, mas o cliente MongoDB nativo. Obtendo o mesmo erro no primary server available aqui. Estamos executando um conjunto de réplicas na instância EC2 dentro de um VPC privado, nossa string de conexão são os endereços IP privados das instâncias. MongoDB v3.0.3 . Parece-me que isso acontece quando há um alto rendimento de consultas, pois no uso geral o erro não ocorre.

            serverOpts = {
                server: {
                    sslValidate: false,
                    sslCA: ca,
                    socketOptions: {
                        connectTimeoutMS: 30000,
                        socketTimeoutMS: 180000
                    }
                },
                replSet: {
                    connectWithNoPrimary: false,
                    sslValidate: false,
                    sslCA: ca,
                    socketOptions: {
                        connectTimeoutMS: 30000,
                        socketTimeoutMS: 180000
                    }
                }
            };

Parece que há uma correção para isso nas próximas versões de driver: NODE-622

Nunca é cedo para presentes! :)

A versão corrigida já foi publicada no NPM https://www.npmjs.com/package/mongodb.

Posso confirmar que não recebemos mais o erro. : tada:

Continuo vendo este erro depois de atualizar o mangusto para 4.3.4 , que usa o núcleo do mongo 2.1.2 . https://jira.mongodb.org/browse/NODE-622 foi reaberto

+1 Acabei de notar isso acontecendo em nosso servidor de produção também. Não vejo nenhum padrão de por quê. Usando o nó 4.2.4 com mongoose 4.3.4 e mongodb 3.0.8. Eu uso os serviços MMS do mongodb para monitorar meu cluster e não vi nenhum alerta durante o tempo quando recebo: MongoError: nenhum servidor primário disponível

@ amit777 Você pode postar sua string de conexão e opções? Além disso, isso ocorreu durante uma carga de trabalho excepcionalmente pesada, por exemplo, muitas gravações no banco de dados?

Chris, isso definitivamente acontece durante as operações de gravação, embora eu não diria que nossa carga é particularmente pesada. Temos alguns nós em um cluster onde cada nó gravará independentemente no mongo.

Aqui está como nos conectamos:


var mongoose = require('mongoose');
var mongodb = {};

var connect = function () {
mongodb.db = "mongodb://node1:27017,node2:27017,node3:27017/myapp";
mongodb.dbOptions = {
      "db": {"native_parser": true},
      "replSet": {
        "rs_name": "mongocluster",
        "socketOptions": { "keepAlive": 1, "connectTimeoutMS": 30000, "socketTimeoutMS": 60000 }
        }
    };
  mongoose.connect(config.get('mongodb.db'), config.get('mongodb.dbOptions'));
};
connect();

Eu também notei que meus logs de mongod estão enchendo muito rápido com mensagens de conexão e desconexão:

2016-01-13T13:32:15.418-0500 I NETWORK  [conn91700536] end connection 192.168.1.50:33189 (5558 connections now open)
2016-01-13T13:32:15.418-0500 I NETWORK  [conn91700534] end connection 192.168.1.50:33187 (5558 connections now open)
2016-01-13T13:32:15.418-0500 I NETWORK  [conn91700540] end connection 192.168.1.50:33193 (5557 connections now open)
2016-01-13T13:32:15.418-0500 I NETWORK  [conn91700538] end connection 192.168.1.50:33191 (5558 connections now open)
2016-01-13T13:32:15.418-0500 I NETWORK  [conn91700542] end connection 192.168.1.50:33195 (5557 connections now open)
2016-01-13T13:32:15.418-0500 I NETWORK  [conn91700532] end connection 192.168.1.50:33185 (5556 connections now open)
2016-01-13T13:32:15.419-0500 I NETWORK  [conn91700533] end connection 192.168.1.50:33186 (5552 connections now open)
2016-01-13T13:32:15.419-0500 I NETWORK  [conn91700535] end connection 192.168.1.50:33188 (5552 connections now open)
2016-01-13T13:32:15.419-0500 I NETWORK  [conn91700537] end connection 192.168.1.50:33190 (5552 connections now open)
2016-01-13T13:32:15.419-0500 I NETWORK  [conn91700541] end connection 192.168.1.50:33194 (5551 connections now open)
2016-01-13T13:32:15.419-0500 I NETWORK  [conn91700543] end connection 192.168.1.50:33196 (5551 connections now open)
2016-01-13T13:32:15.419-0500 I NETWORK  [conn91700539] end connection 192.168.1.50:33192 (5552 connections now open)
2016-01-13T13:32:15.548-0500 I NETWORK  [initandlisten] connection accepted from 192.168.1.50:36754 #91705950 (5548 connections now open)
2016-01-13T13:32:15.549-0500 I NETWORK  [initandlisten] connection accepted from 192.168.1.50:36755 #91705951 (5549 connections now open)
2016-01-13T13:32:15.550-0500 I NETWORK  [initandlisten] connection accepted from 192.168.1.50:36756 #91705952 (5550 connections now open)
2016-01-13T13:32:15.550-0500 I NETWORK  [initandlisten] connection accepted from 192.168.1.50:36757 #91705953 (5551 connections now open)
2016-01-13T13:32:15.550-0500 I NETWORK  [initandlisten] connection accepted from 192.168.1.50:36758 #91705954 (5552 connections now open)
2016-01-13T13:32:15.551-0500 I NETWORK  [initandlisten] connection accepted from 192.168.1.50:36760 #91705955 (5553 connections now open)
2016-01-13T13:32:15.551-0500 I NETWORK  [initandlisten] connection accepted from 192.168.1.50:36759 #91705956 (5554 connections now open)
2016-01-13T13:32:15.551-0500 I NETWORK  [initandlisten] connection accepted from 192.168.1.50:36762 #91705957 (5555 connections now open)
2016-01-13T13:32:15.551-0500 I NETWORK  [initandlisten] connection accepted from 192.168.1.50:36761 #91705958 (5556 connections now open)
2016-01-13T13:32:15.553-0500 I NETWORK  [initandlisten] connection accepted from 192.168.1.50:36763 #91705959 (5557 connections now open)
2016-01-13T13:32:15.553-0500 I NETWORK  [initandlisten] connection accepted from 192.168.1.50:36764 #91705960 (5558 connections now open)
2016-01-13T13:32:15.554-0500 I NETWORK  [initandlisten] connection accepted from 192.168.1.50:36765 #91705961 (5559 connections now open)

Aqui estão algumas informações adicionais que podem ajudar a depurar. Estou começando a pensar que pode haver algum bug relacionado ao pool de conexão. Depois de reiniciar meus processos de nó, vejo um monte de novas conexões aparecendo no mongod.log. Depois de cerca de um minuto, vejo um monte de mensagens de conexão final em mongod.log.

Parece que a conexão / desconexão amplifica cada vez mais rápido com o tempo, (embora eu ainda esteja tentando confirmar isso).

a situação típica que causa isso é algo assim.

Replicaset contém hosts que não podem ser resolvidos pelo driver. Quando o driver se conecta, ele usa o replicaset como fonte canônica para todas as conexões. As reconexões usarão esses endereços. Eles DEVEM ser resolvidos pelo driver.

Você também deve evitar o uso de endereços IP, pois eles são uma fonte de muitos problemas como este, use nomes de host totalmente qualificados (sem nomes curtos)

@christkv se o sistema operacional é capaz de resolver os hosts (ou seja, fazendo ping), isso significa que o driver também deve ser capaz de resolver?

deveria sim, mas você sempre pode usar a porta do nome do host telnet para verificar.

sim, sou capaz de fazer telnet para o host e a porta .. (todos os hosts do banco de dados têm entradas / etc / hosts nos servidores de aplicativos).

Depois que nosso aplicativo é inicializado e o pool de conexão é criado, deve haver uma desconexão e reconexão se não houver problemas de rede? Ou há um tempo limite normal de conexão e reconexão que verei nos logs do mongodb?

O problema é que é impossível correlacionar essas coisas para tentar entender e reproduzir o problema sem um conjunto completo de logs (veja meu último comentário em https://jira.mongodb.org/browse/NODE-622)

se você não tiver ops suficientes na janela de tempo limite do soquete para exercitar todas as conexões, o pool será fechado e reconectado. então, se você tiver uma janela de 30 segundos e 10 conexões, mas apenas 5 ops, isso causará um evento de reconexão a cada 30 segundos.

Ele encerrará todas as conexões com o pool? ou apenas as ligações que não foram exercidas? Se exercitarmos todas as conexões em 30 segundos, a mesma verificação será realizada na janela de 30 segundos seguinte?

Vou tentar obter os logs de suas solicitações no tíquete mongodb .. obrigado pela ajuda.

Todos. Se você conseguir exercitar todas as conexões no pool na janela socketTimeout, o node.js não atingirá o tempo limite dos soquetes e eles não fecharão forçando uma reconexão do pool.

Uma dica: muitas conexões só são úteis se você tiver muitas operações lentas em paralelo, caso contrário, você é mais adequado com um pool menor, pois o MongoDB usa um thread por soquete, o que significa que milhares de conexões requerem mais memória alocada no servidor e causar mais trocas de contexto da CPU.

A próxima grande revisão do mongodb-core mudará o pool para crescer, bem como algumas outras mudanças fundamentais para minimizar problemas de trem lento. No entanto, ainda faltam vários meses e provavelmente será vinculado ao trabalho do MongoDB 3.4.

Você vê que é possível / provável que a quantidade massiva de desconexão / reconexão pode causar intermitentemente o problema de nenhum servidor primário disponível?

sim, pois haverá um breve período em que pode não haver nenhum servidor no conjunto

@christkv Estou esperando que isso aconteça novamente para enviar alguns logs para aquele outro tíquete. Nosso cluster está estável nas últimas semanas e não vimos esse erro.

@ChrisZieba engraçado como isso sempre parece acontecer lol: +1: Vou deixar o tíquete aberto em Jira por enquanto e ver o que podemos descobrir.

@christkv Olá, Christian, estou apenas curioso para saber se você tem alguma sugestão sobre soluções alternativas no caso de tráfego reduzido. Eu estava pensando em apenas reduzir o tamanho do pool, bem como aumentar os tempos limite.

se ajudar mais alguém, removi o tempo limite do soquete e aumentei o keepAlive para 200 e também reduzi o tamanho do pool para 3 .. parece que tenho muito menos desconexão / reconexão .. no entanto, ainda acontece ocasionalmente.

Se isso ajudar alguém, removemos quase todas as configurações do mongoose, incluindo socketTimeout e connectionTimeout e keepAlive e as conexões começaram a ficar estáveis. Nosso poolSize é 200.
Não tenho certeza se é a abordagem recomendada, mas funciona agora. Ainda estamos monitorando para garantir que se mantenha.

mangusto v4.4.2
Nó 4
Mongo 3.0

Você tem uma grande quantidade de operações lentas? se você não fizer isso, acho que você não notará qualquer diferença entre um pool de 20 soquetes e 500.

Desculpe ... são 200. Corrigido o comentário.

E sim, você está certo. Não sentimos muita diferença, mas preferimos ter o tamanho da piscina maior do que menor.

O verdadeiro problema quando as conexões continuam abrindo e não fechando. Isso costumava acontecer até removermos todo o tempo limite do mangusto e as configurações de keepAlive. Eu me pergunto por que eles são controlados por mongoose / mongo-driver e não deixando o sistema operacional fazer isso?

O poço 2.1.7 e superior tem um pool redesenhado que evita isso. Se você definir socketTimeout como 0, você o delega ao sistema operacional, mas isso pode levar até 10 minutos de conexões interrompidas.

Está bem. interessante. Então, agora que removi as configurações de keepAlive e socketTimeout, quais são as configurações padrão?

depende, não tenho certeza se o mangusto definiu alguma configuração específica como padrão. se você usar o método MongoClient.connect no driver, são 30 segundos para os tempos limite de conexão e soquete.

Nós usamos connect mas quando definimos 30 segundos manualmente, as conexões começam a se acumular.

Bem, com 500 conexões, você precisa de pelo menos 500 ops dentro do período socketTimeout para manter o pool aberto, caso contrário, ele será fechado e forçará uma reconexão. No entanto, isso muda em 2.1.7, pois o pool é um modelo de crescimento / redução.

Estou tendo o mesmo problema com mongodb 3.2.6 e mongoose 4.3.4. Alguma ajuda nisso?

@ 15astro tente remover as configurações de socketTimeout e connectionTimeout e veja se isso ajuda.

@refaelos Ok ... tentarei isso ... Tentei com keepAlive = 6000, mas não ajudou. Só queria saber como remover socketTimeout e connectionTimeout pode ajudar?

Sim, nós tentamos com valores diferentes e somente quando removemos completamente essas configurações as coisas começaram a funcionar bem.

@refaelos : Não tive sorte em remover essas configurações. Alguma outra coisa que estou perdendo?

@ 15astro nenhum homem. Desculpe. É assim que nossas configurações estão hoje:

mongo   : {
    uri    : process.env.MNG_URL || 'mongodb://localhost/myDB',
    options: {
      user   : process.env.MNG_USER,
      pass   : process.env.MNG_PASS,
      replset: {
        poolSize: 200
      }
    }

  }

No meu caso, foi relacionado à falta de IP para vinculação de nomes em / etc / hosts.

Se você configurou um conjunto de réplicas com nomes em vez de IPs e tem algo assim em / etc / hosts de nós do MongoDB:

10.10.10.10 mongodb-2gb-fra1-02 10.10.10.11 mongodb-2gb-fra1-01 10.10.10.12 mongodb-2gb-fra1-03

Em seguida, você também precisa colocá-lo em / etc / hosts de todos os seus servidores de aplicativos.

Eu pensei que o node-mongo se conecta de acordo com o que eu coloquei no URI, mas não é o caso.

Parece que o node-mongo se conecta por IP ou nome do URI do Mongo e, em seguida, obtém os nomes de host de outros membros da réplica do primeiro nó do MongoDB que respondeu à solicitação. Ele obtém, por exemplo, mongodb-2gb-fra1-03 e passa para o sistema operacional para resolução. Se o sistema operacional não souber nada sobre mongodb-2gb-fra1-03 , ele exibe "Erro no servidor primário disponível".

Espero que ajude.

@adriank sim, está correto, ele baseia as conexões daqueles que recebe da configuração do replicaset. O motivo é que esta é a fonte canônica da verdade sobre um replicaset. É também por isso que todos os endereços na configuração do replicaset devem ser resolvidos pelo driver para que o driver faça failover corretamente e possa detectar servidores sendo adicionados e removidos do conjunto. Os drivers anteriores não implementavam as especificações SDAM e eram mais flexíveis. No entanto, isso causaria problemas em ambientes de produção.

@christkv No entanto, é um pesadelo para ferramentas como o nosso MongoSpector . Por causa disso, temos problemas para conectar com segurança a mais de uma réplica de um host. O DigitalOcean gera automaticamente nomes para gotas que quase ninguém altera e o efeito é que muitos clientes têm mongodb-2gb-fra1-01 como PRIMÁRIO. :) Espero que possamos descobrir algo.

Estamos rastreando um tíquete de servidor aqui https://jira.mongodb.org/browse/SERVER-1889. Eu adoraria que algo assim fosse possível.

Devemos também registrar um tíquete na DigitalOcean apontando o erro que eles estão cometendo e como isso está afetando seus usuários.

a propósito, você pode remover e adicionar novamente os membros da réplica com seus novos nomes sendo ips

Tendo um problema semelhante, após cerca de 12-24 horas de estar conectado, obtemos um erro "Nenhum servidor primário disponível"

Reiniciar geralmente corrige o problema.

conexão:
{ "url": "mongodb://user:password@cluser-shard-00-00, cluser-shard-00-01, cluster-shard-00-02/settings?ssl=true&replicaSet=primarycluster-shard-0&authSource=admin&retryWrites=true", "options": { "db": { "w": 1, "wtimeout": 3000, "fsync": true }, "authSource": "admin", "server": { "poolSize": 3, "socketOptions": { "autoReconnect": true, "keepAlive": 60000, "connectTimeoutMS": 7000, "socketTimeoutMS": 15000 } } }, "password": "password", "username": "username" }

Esta página foi útil?
0 / 5 - 0 avaliações