Svarbiausias sprendimas – nustoti traktuoti kiekvieną Mongoose laiko limito klaidą kaip nustatymų problemą. Toks pranešimas kaip MongoServerSelectionError: connection timed out dažniausiai reiškia, kad MongoDB tvarkyklė negalėjo pasirinkti tinkamo serverio prieš pasibaigiant serverSelectionTimeoutMS. Dabartinė MongoDB trikčių šalinimo dokumentacija kaip dažnas priežastis nurodo tinklo ryšio problemas, Atlas IP prieigos apribojimus, DNS SRV nesėkmes ir TLS konfigūraciją. Laiko limito didinimas gali priversti programą laukti ilgiau, bet neištaiso nė vienos iš šių sąlygų.
Užuot tai darydami, naudokite šią tvarką: 1) nustatykite, kuris laiko limitas nepavyko, 2) įrodykite, kad programos pagrindinis kompiuteris gali pasiekti MongoDB, 3) ištaisykite jungties eilutę arba aplinkai specifinį adresą, ir 4) tikslinkite laiko limitų reikšmes tik tada, kai ryšys yra žinomas kaip veikiantis. Žemiau pateiktuose pavyzdžiuose naudojami modernūs Mongoose jungties šablonai ir dabartinis MongoDB tvarkyklės elgesys, dokumentuotas 2026 m. rugsėjį.
Pirmiausia žinokite, kurį laiko limitą tiriate
Mongoose po kapotu naudoja MongoDB Node.js tvarkyklę, todėl toje pačioje jungties konfigūracijoje gali pasirodyti keli skirtingi laiko limitų nustatymai. Jie nereiškia to paties.
| Nustatymas arba simptomas | Ką jis valdo | Dabartinė dokumentuota numatytoji reikšmė | Tipiška interpretacija |
serverSelectionTimeoutMS | Kiek laiko tvarkyklė bando rasti tinkamą MongoDB serverį | 30 000 ms | Topologijos, DNS, ugniasienės, IP prieigos, neprieinamo serverio arba tinkamo pirminio/antrinio serverio nebuvimo problemos |
connectTimeoutMS | Kiek laiko gali užtrukti vienas TCP lizdo jungties bandymas | 30 000 ms dabartinėje Node.js tvarkyklėje | Pagrindinis kompiuteris/prievadas nepasiekiamas, filtruojamas arba per lėtas TCP ryšiui užmegzti |
socketTimeoutMS | Kiek laiko jau prijungtas lizdas gali būti neaktyvus siuntimo/priėmimo metu prieš pasibaigiant laikui | 0, reiškia jokių lizdo laiko limitų dabartinėje Node.js tvarkyklėje | Paprastai svarbu po prisijungimo, ypač ilgoms arba sustingusioms operacijoms |
ETIMEDOUT / jungties laiko limitas | Tinklo lygmens nesėkmės simptomas | Ne konfigūracijos numatytoji reikšmė | Dažnai pasiekiamumo, ugniasienės, maršrutizavimo, DNS tikslo arba neprieinamo serverio problemos |
Dabartinė Mongoose jungties dokumentacija nurodo, kad serverSelectionTimeoutMS numatytoji reikšmė yra 30 sekundžių ir taikoma tiek pradiniam mongoose.connect(), tiek vėlesnėms operacijoms, kurioms reikia pasirinkti serverį. MongoDB Node.js tvarkyklės jungties parinkčių dokumentacija atskiria šią reikšmę nuo connectTimeoutMS ir socketTimeoutMS.
Serverio pasirinkimo laiko limitas yra pirmasis klasifikuotinas simptomas; klaidos detalės ir pagrindinė priežastis yra naudingesnės nei iškart didinti 30 sekundžių ribą.
1 žingsnis: užfiksuokite tikslią Mongoose klaidą ir jos pagrindinę priežastį
Pradėkite nuo minimalios jungties ir įrašykite pakankamai informacijos, kad atskirtumėte DNS, autentifikavimo, TLS ir pasiekiamumo nesėkmes:
import mongoose from 'mongoose';
try {
await mongoose.connect(process.env.MONGODB_URI, {
serverSelectionTimeoutMS: 5000
});
console.log('MongoDB connected');
} catch (err) {
console.error(err);
console.error('Reason:', err.reason);
process.exit(1);
}
Aukščiau pateikta 5 sekundžių reikšmė yra diagnostinis pasirinkimas, o ne gamybos rekomendacija kiekvienam diegimui. Mongoose teigia, kad serverSelectionTimeoutMS sumažinimas gali suteikti greitesnį grįžtamąjį ryšį, tačiau specialiai perspėja prieš neatsargiai jį mažinant replikų rinkiniams, nes numatytasis 30 sekundžių langas gali padėti operacijoms išgyventi rinkimus ir perjungimus. Mongoose lengviau rekomenduoja trumpesnes reikšmes atskiriems MongoDB arba serverless vykdymo aplinkose, kur greitas nesėkmės aptikimas yra naudingas.
Ieškokite tokių užuominų:
getaddrinfo ENOTFOUND – DNS pavadinimas negali būti išspręstas.
ECONNREFUSED – kažkas aktyviai atmetė TCP jungtį, dažniausiai todėl, kad niekas neklauso pagrindiniame kompiuteryje/prievade.
ETIMEDOUT – jungties bandymas nebuvo baigtas laiku, dažniausiai todėl, kad srautas filtruojamas, neteisingai nukreipiamas arba tikslas neprieinamas.
- TLS arba sertifikato tekstas – tirkite sertifikato pasitikėjimą, pagrindinio kompiuterio atitikimą, protokolo palaikymą arba TLS konfigūraciją.
- Autentifikavimo klaidės
err.reason viduje – ištaisykite kredencialus arba authSource, o ne keiskite tinklo laiko limitus.
Sąlyga: jei klaida jau sako, kad autentifikavimas nepavyko, praleiskite ugniasienės tikslinimą, kol kredencialai ir autentifikavimo duomenų bazė nebus teisingi. Tinklo laiko limitas ir atmestas prisijungimas yra skirtingos nesėkmės klasės.
2 žingsnis: įrodykite tinklo, Atlas IP prieigos ir DNS veikimą iš tos pačios vykdymo aplinkos
Vykdykite ryšio testus iš to paties kompiuterio, konteinerio, VM, serverless funkcijos arba Kubernetes po, kuriame veikia Node.js procesas. Testavimas iš jūsų nešiojamojo kompiuterio nepakanka, jei gamybos aplinka veikia kitur.
Atlas atveju patikrinkite, ar tikrasis programos išvykstantis IP yra leidžiamas; vietiniam diegimui patikrinkite, ar MongoDB procesas iš tikrųjų klauso tikėtinoje sąsajoje ir prievade.
Jei naudojate MongoDB Atlas
Atlas priima klientų jungtis tik iš adresų, leidžiamų projekto IP prieigos sąraše. MongoDB tai dokumentuoja IP prieigos sąrašo valdyme. Įsitikinkite, kad programos aplinkos viešasis išvykstantis IP yra įtrauktas, o ne tik jūsų asmeninės darbo stoties IP.
MongoDB serverio pasirinkimo laiko limito trikčių šalinimo vadovas taip pat rekomenduoja tikrinti išvykstantį TCP ryšį su MongoDB 27017 prievade, kartu su ugniasienėmis, saugumo grupėmis, tinklo ACL, VPN ir tarpiniais serveriais.
Pavyzdžiui, iš Linux arba macOS galite patikrinti konkretų Atlas mazgą arba savarankiškai valdomą pagrindinį kompiuterį naudodami:
nc -vz your-mongodb-host.example.com 27017
Windows PowerShell, apytikslis TCP pasiekiamumo testas yra:
Test-NetConnection your-mongodb-host.example.com -Port 27017
Sėkmingas TCP testas neįrodo, kad autentifikavimas arba TLS pavyks, tačiau nepavykęs TCP testas reiškia, kad Mongoose laiko limitų tikslinimas yra priešlaikinis.
Jei jūsų URI naudoja mongodb+srv://
SRV jungties eilutė priklauso nuo DNS SRV įrašų. Dabartiniai MongoDB trikčių šalinimo veiksmai rekomenduoja tikrinti SRV užklausą iš kliento aplinkos:
nslookup -type=SRV _mongodb._tcp.cluster-name.mongodb.net
Jei SRV užklausa nepavyksta, patvirtinkite pagrindinio kompiuterio pavadinimą ir DNS konfigūraciją. MongoDB dokumentuoja ne SRV mongodb:// jungties eilutę kaip galimą apėjimą, kai aplinka negali išspręsti SRV įrašų, tačiau turėtumėte gauti tą standartinę jungties eilutę iš Atlas arba savo diegimo konfigūracijos, o ne sugalvoti mazgų pavadinimus. Žr. Atlas jungties trikčių šalinimą.
Teisinga diagnostinė seka patikrina adresą ir tinklo kelią prieš traktuojant laiko limitų reikšmes kaip pagrindinę priežastį.
3 žingsnis: ištaisykite URI tam aplinkai, kurioje iš tikrųjų veikia Node.js
Sintaksiškai teisinga MongoDB URI vis tiek gali rodyti į neteisingą vietą. Patikrinkite schemą, pagrindinio kompiuterio pavadinimą, prievadą, duomenų bazės pavadinimą, replikų rinkinio reikalavimus, autentifikavimo šaltinį ir tai, ar pagrindinio kompiuterio pavadinimas yra prasmingas programos tinklo vardų erdvėje.
Vietinis Node.js ir vietinis MongoDB
Mongoose šiuo metu rekomenduoja 127.0.0.1 vietoj localhost vietiniam MongoDB:
await mongoose.connect('mongodb://127.0.0.1:27017/myapp');
Priežastis yra Node.js 18 ir naujesnės versijos: Mongoose pažymi, kad Node.js gali išspręsti localhost į IPv6 ::1, o vietinis MongoDB egzempliorius gali klausyti tik IPv4. Mongoose taip pat dokumentuoja { family: 4 } kaip parinktį, kai IPv6 pirmenybės sprendimas sulėtina jungties bandymus:
await mongoose.connect('mongodb://localhost:27017/myapp', {
family: 4
});
Naudokite family: 4 tik tada, kai IPv4/IPv6 sprendimo kelias iš tikrųjų yra problema. Jei jūsų MongoDB diegimas teisingai palaiko IPv6, priverstinis IPv4 naudojimas yra nereikalingas.
Node.js Docker viduje
Jei programa yra konteineryje, localhost reiškia tą konteinerį, o ne automatiškai MongoDB pagrindiniame kompiuteryje arba kitame konteineryje. Naudokite MongoDB paslaugos/konteinerio pagrindinio kompiuterio pavadinimą bendrame Docker tinkle arba platformai specifinį pagrindinio kompiuterio adresą, kai MongoDB veikia pagrindiniame kompiuteryje.
Pavyzdžiui, su Compose paslauga, pavadinta mongo:
MONGODB_URI=mongodb://mongo:27017/myapp
Sąlyga: šis pavyzdys taikomas tik jei konteineriai dalijasi tinklu ir MongoDB paslauga iš tikrųjų vadinasi mongo. Nekopijuokite pagrindinio kompiuterio pavadinimo į nesusijusį diegimą.
Atlas
Naudokite Atlas sugeneruotą jungties eilutę jūsų tvarkyklei, išsaugokite mongodb+srv:// pagrindinį kompiuterį tiksliai, URL koduokite rezervuotus simbolius vartotojo varduose arba slaptažodžiuose, kai reikia, ir patikrinkite, ar duomenų bazės vartotojas egzistuoja numatytame projekte.
Jei jungiatės prie savarankiškai valdomo replikų rinkinio, replikų rinkinio pranešti pagrindinių kompiuterių pavadinimai taip pat turi būti pasiekiami iš kliento. Sėklos pagrindinis kompiuteris gali būti pasiekiamas, tačiau vėlesnis serverio pasirinkimas vis tiek gali nepavykti, nes replikų rinkinio nariai skelbia pagrindinių kompiuterių pavadinimus, kurių programa negali išspręsti arba nukreipti.
4 žingsnis: tikslinkite laiko limitus tik tada, kai ryšys pavyksta
Kai DNS išsprendžiamas, tinklo kelias veikia, serveris yra prieinamas ir URI yra teisingas, laiko limitų tikslinimas tampa prasmingas.
Mongoose perduoda su laiko limitais susijusias jungties parinktis pagrindinei MongoDB tvarkyklei, tačiau kiekviena parinktis valdo skirtingą etapą; didesnės reikšmės neturėtų būti naudojamos norint paslėpti sugriautą kelią arba neprieinamą serverį.
Konservatyvus pavyzdys programai, kuri nori 10 sekundžių pradinio nesėkmės signalo, galėtų atrodyti taip:
await mongoose.connect(process.env.MONGODB_URI, {
serverSelectionTimeoutMS: 10000,
connectTimeoutMS: 10000
});
Ar 10 sekundžių yra tinkama, priklauso nuo diegimo. Kompromisas yra paprastas:
| Pasirinkimas | Privalumas | Kompromisas | Kur tai gali būti prasminga |
| Trumpesnis serverio pasirinkimo laiko limitas | Greita nesėkmė ir greitesnis paleidimo grįžtamasis ryšys | Mažiau laiko išgyventi laikinus topologijos pokyčius arba replikų rinkinio rinkimus | Kūrimas, sveikatos tikrinimai, kai kurie serverless paleidimo keliai, atskiras MongoDB |
| Numatytasis 30 sekundžių | Didesnė tolerancija laikiniems topologijos arba tinklo sutrikimams | Neteisinga konfigūracija gali užtrukti 30 sekundžių, kad būtų aptikta | Daugelis bendrų gamybos diegimų ir replikų rinkiniai |
| Ilgesnis serverio pasirinkimo laiko limitas | Didesnė kantrybė neįprastai lėtam atkūrimui | Užklausos ir paleidimas gali užstrigti ilgiau prieš nepavykstant | Tik tada, kai išmatuotas atkūrimo elgesys tai pateisina |
Kalbant apie socketTimeoutMS, dabartinė MongoDB Node.js tvarkyklės dokumentacija naudoja numatytąją reikšmę 0, reiškiančią jokių lizdo neaktyvumo laiko limitų. MongoDB rekomenduoja, kai nusprendžiate tai nustatyti, pasirinkti reikšmę, maždaug du ar tris kartus ilgesnę nei lėčiausia tikėtina operacija. Šis nustatymas taikomas lizdams, kurie jau prisijungė, todėl tai nėra pagrindinis pradinio serverio pasirinkimo laiko limito sprendimas.
Nekopijuokite senų Mongoose jungties parinkčių į dabartinį projektą
Daugelis senesnių pavyzdžių vis dar turi useNewUrlParser, useUnifiedTopology, keepAlive arba keepAliveInitialDelay. Dabartinis Mongoose nereikalauja senų parserio/topologijos įjungimų, o Mongoose dokumentuoja keepAlive kaip įjungtą pagal numatytuosius nustatymus nuo Mongoose 5.2 ir pasenusią kaip jungties parinktį nuo 7.2.
Modernus pagrindas yra tyčia mažas:
import mongoose from 'mongoose';
await mongoose.connect(process.env.MONGODB_URI);
Pridėkite jungties parinktis, nes jūsų aplinka jų reikia, o ne todėl, kad jos pasirodė prieš penkerius metus parašytame fragmente.
Ką daryti, jei jungtis veikia, tačiau užklausos vėliau viršija laiko limitą?
Tai yra kita problema. Jei mongoose.connect() pavyksta ir programa vėliau užstringa vykdydama užklausas, tirkite operacijos vėlavimą, jungčių baseino spaudimą, serverio apkrovą, indeksus bei lizdo arba operacijos laiko limitus. Dabartinė MongoDB Node.js tvarkyklė atskiria:
serverSelectionTimeoutMS – tinkamo serverio radimas.
connectTimeoutMS – vienos TCP jungties užmezgimas.
socketTimeoutMS – neaktyvumas jau užmegztoje jungtyje.
maxTimeMS – serverio operacijos vykdymo trukmės ribojimas, kai ji pasiekia MongoDB.
Jei nepavyksta tik ilgos užklausos, serverSelectionTimeoutMS didinimas mažai tikėtina, kad išspręs tikrąją problemą.
Greita diagnostika pagal klaidos sąlygą
| Stebima sąlyga | Naudingiausias kitas patikrinimas |
Server selection timed out after 30000 ms | Ištirkite err.reason, tada patikrinkite topologiją, DNS, TCP pasiekiamumą, Atlas prieigos sąrašą ir TLS |
getaddrinfo ENOTFOUND | Patikrinkite pagrindinio kompiuterio pavadinimą ir DNS/SRV sprendimą iš programos aplinkos |
ECONNREFUSED 127.0.0.1:27017 | Patvirtinkite, kad MongoDB veikia ir klauso tame adrese/prievade; Docker atveju patikrinkite, ar pagrindinio kompiuterio pavadinimas nėra neteisingai nustatytas į localhost |
ETIMEDOUT | Patikrinkite ugniasienę, maršrutizavimą, saugumo grupes, IP leidžiamųjų sąrašą, VPN/tarpinį serverį ir serverio prieinamumą |
| TLS rankos paspaudimo arba sertifikato klaida | Ištaisykite pasitikėjimo grandinę, pagrindinio kompiuterio pavadinimą, sertifikatą arba palaikomą TLS konfigūraciją; negalite išjungti patikrinimo kaip gamybos sprendimo |
| Autentifikavimas nepavyko | Ištaisykite vartotojo vardą, slaptažodį, URL kodavimą, authSource arba duomenų bazės vartotojo konfigūraciją |
Vietinis ryšys yra lėtas naudojant localhost | Pabandykite 127.0.0.1 arba family: 4, jei IPv6 pirmenybės sprendimas yra priežastis |
Gamybai palankus jungties šablonas
Laikykite paslaptis už kodo ribų, aiškiai žlugdykite paleidimą, kai duomenų bazė neprieinama, ir įrašykite pakankamai detalių diagnostikai, bet neatspausdinkite kredencialų:
import mongoose from 'mongoose';
export async function connectDatabase() {
const uri = process.env.MONGODB_URI;
if (!uri) {
throw new Error('MONGODB_URI is not set');
}
try {
await mongoose.connect(uri, {
serverSelectionTimeoutMS: 30000,
connectTimeoutMS: 30000
});
console.log('MongoDB connected');
} catch (err) {
console.error('MongoDB connection failed:', err.message);
console.error('Server selection reason:', err.reason);
throw err;
}
}
Tos 30 sekundžių reikšmės atitinka dabartines dokumentuotas numatytąsias reikšmes, todėl galite jas praleisti, nebent politikos aiškinimas padeda jūsų operacijoms. Svarbiausia dalis nėra skaičiai; svarbu žinoti, kodėl skirtingas skaičius būtų geresnis jūsų diegimui.
Galutinis sąrašas
- Užfiksuokite pilną klaidą ir ištirkite
err.reason.
- Patvirtinkite, kad MongoDB diegimas veikia ir yra prieinamas.
- Vykdykite DNS ir TCP testus iš tos pačios aplinkos kaip ir Node.js procesas.
- Atlas atveju patvirtinkite, kad programos išvykstantis IP yra IP prieigos sąraše.
mongodb+srv:// atveju patvirtinkite SRV DNS sprendimą.
- Vietiniam MongoDB pabandykite
127.0.0.1, jei localhost išsprendžiamas į netinkamą IPv6.
- Docker arba Kubernetes atveju naudokite pagrindinio kompiuterio pavadinimą, kuris yra galiojantis toje tinklo vardų erdvėje.
- Ištaisykite TLS arba autentifikavimo klaidas vietoj jų maskavimo didesniu laiko limitu.
- Tikslinkite
serverSelectionTimeoutMS, connectTimeoutMS arba socketTimeoutMS tik tam etapui, kurį jie iš tikrųjų valdo.
- Po pataisymo patikrinkite, ar programa nuosekliai jungiasi iš tikrosios diegimo aplinkos, o ne tik iš kūrėjo nešiojamojo kompiuterio.
Išvada
Jei Mongoose praneša apie MongoDB tinklo laiko limitą, pirmiausia įrodykite, kad tvarkyklė gali aptikti ir pasiekti tinkamą MongoDB serverį. Atlas IP apribojimai, ugniasienės, DNS SRV sprendimas, neteisingi konteinerių pagrindinių kompiuterių pavadinimai, IPv4/IPv6 neatitikimai, neprieinami MongoDB procesai ir TLS konfigūracija gali priversti 30 sekundžių laiko limitą atrodyti kaip problema, nors laikmatis tik praneša apie nesėkmę.
Naudokite laiko limitų nustatymus apibrėžti, kiek laiko jūsų programa turėtų laukti žinomos veikiančios sistemos, o ne kompensuoti sugriautą jungties kelią. Kai tinklo pasiekiamumas ir URI yra teisingi, tada pasirinkite laiko limitų reikšmes, atitinkančias jūsų prieinamumo modelį, perjungimo elgesį ir tikėtiną operacijos vėlavimą.