Jag visar hur Filbeskrivningsgräns på servern begränsar anslutningar, filer och socklar och avgör därmed prestandan. Jag vidtar tydliga åtgärder för att höja gränserna, mäta efterfrågan och förhindra EMFILE-fel innan tjänsterna går sönder under belastning.
Centrala punkter
För att du ska kunna agera snabbt har jag sammanfattat de viktigaste Spak för att optimera FD-gränserna:
- OrsakVarje socket, varje fil, varje DB-anslutning förbrukar FD.
- SymptomHTTP 500, EMFILE-meddelanden, blockerad I/O, kraschade tjänster.
- Mätning: ulimit, /proc/limits, file-max och lsof ger klarhet.
- Optimering: Höj gränserna i limits.conf, systemd och sysctl specifikt.
- SäkerhetFlankera höga gränser med hastighetsbegränsning och övervakning.
Vad är filbeskrivare och varför räknas gränser
En filbeskrivning är ett enkelt heltal Identifierare, som kärnan använder för att referera till öppna filer, socklar, rör eller enheter per process. Varje process har en mjuk och en hård gräns, och det finns också ett systemomfattande globalt maximum som begränsar alla processer tillsammans och därmed minimerar antalet processer som kan köras. Knapphet bör förhindras. Som standard finns det ofta bara 1024 FD:er tillgängliga per process, vilket snabbt blir trångt för webbplatser med hög trafik, API-gateways eller chattbackends och så vidare. Belastningstoppar intensifieras. Om en process når sin gräns misslyckas nya anslutningar, arbetare kan inte längre öppna filer och loggar fylls med EMFILE, vilket kan leda till att Svarstider utökad. Det blir särskilt kritiskt med konfigurationer som upptar flera handtag per begäran: PHP-FPM, cache-backends, loggfiler och omvända proxyer ackumulerar FD tills Gränser block.
Identifiera och mäta symtom
De första tecknen på att en gräns är för snäv ser man ofta som HTTP-500 utan tydlig orsak, långsamma svar eller sporadiska omstarter av enskilda tjänster. Typiska loggposter som „För många öppna filer“ indikerar EMFILE och signalerar omedelbar Behov av åtgärder. Jag kontrollerar först processrelaterade gränser och strömförbrukning för att skilja mellan lokala flaskhalsar och systemövergripande problem och därmed bestämma Orsak för att vara mer exakt. Denna kompakta guide är lämplig för en strukturerad introduktion Guide för serverbegränsningar, om du vill få en snabb överblick över justerskruvarna och Steg plan. Jag använder sedan lsof för att mäta hur många deskriptorer en process verkligen innehåller, eftersom uppmätta värden slår antaganden så snart lastprofiler förändring.
# Mjuk och hård gräns för det aktuella skalet
ulimit -n
ulimit -Hn
# Kontrollera gränserna för en process
cat /proc//limits | grep "öppna filer"
# Systemets övergripande status
cat /proc/sys/fs/file-nr # öppna | fria | maximala
cat /proc/sys/fs/file-max # globalt maximum
# Grov uppskattning av förbrukning per process
lsof -p | wc -l
Kontroll av limiter och tolkning av nyckeltal
Jag gör en strikt åtskillnad mellan processrelaterade och globala gränser, så att jag kan identifiera flaskhalsar på ett målinriktat sätt. eliminera istället för att bara flytta den. Den hårda gränsen anger den övre gränsen för ökningar i sessioner, medan fs.file-max och fs.nr_open definierar den globala ramen och därmed Kapacitet hos värden. En beprövad tumregel är att tillåta minst 65535 FD:er per process, förutsatt att RAM-minnet och arbetsbelastningen stöder detta och att du har Last vet. Samtidigt ser jag till att summan av aktiva arbetare, underordnade processer och nätverksanslutningar i realistiska scenarier med hög belastning inom den globala Ramvärden kvarstår. En tydlig bild av dessa siffror förhindrar blinda ökningar utan en plan och håller systemintegriteten under kontroll. Tryck.
| Kommando/Sökväg | Funktion | Vad man ska tänka på |
|---|---|---|
ulimit -n / -Hn | Mjuk/hård gräns för den aktuella sessionen | Hård gräns sätter övre gräns för Lyftning |
/proc//begränsningar | Begränsningar per process och öppna filer | Kritiskt för daemons som t.ex. nginx/php-fpm |
/proc/sys/fs/file-max | Globalt maximum av alla FD | Måste läggas till processbeloppet och RAM passform |
/proc/sys/fs/file-nr | Öppet, fritt, maximalt antal | Trend i belastningsprov och Toppar kontroll |
lsof | Visar öppna handtag | Per arbetare/tråd förbrukad Mät FD |
Justera FD-gränser tillfälligt och permanent
För snabba tester använder jag ulimit för att ställa in en högre Mjuk gräns, innan jag definierar permanenta regler och startar om tjänsterna. Jag skriver sedan lämpliga poster i /etc/security/limits.conf, lägger till systemd-överstyrningar och verifierar ändringen med en riktad Belastningstest. Viktigt: Tjänsteanvändaren måste vara korrekt, annars kommer ökningen inte att ha någon effekt och Problem dyker upp igen under belastning. Jag justerar också den globala gränsen så att många arbetsprocesser inte överskrider systemgränsen tillsammans. ackumulera låt. Endast när process- och systemsidorna passar ihop kan konfigurationen klara verkliga högbelastningsscenarier och undvika EMFILE.
# Temporär (tills inloggning/omstart)
ulimit -n 65535
# Systemomfattande (tills omstart eller permanent via sysctl.conf)
sudo sysctl -w fs.file-max=2097152
# Permanent (exempel för webbserveranvändare)
echo -e "www-data mjuk nofile 65535\nww-data hård nofile 65535\n* mjuk nofile 65535\n* hård nofile 65535" | sudo tee -a /etc/security/limits.conf
# systemd-tjänster (t.ex. nginx)
sudo mkdir -p /etc/systemd/system/nginx.service.d
cat <<'EOF' | sudo tee /etc/systemd/system/nginx.service.d/limits.conf
[Tjänst]
LimitNOFILE=65536
EOF
sudo systemctl daemon-reload && sudo systemctl restart nginx
Ställ in kernelparametrar korrekt
Jag validerar fs.file-max och fs.nr_open tillsammans så att kärnan har tillräckligt med Buffert för toppbelastningar. Om du bara ökar gränsen per process kommer du annars att nå den globala gränsen och flytta flaskhals på systemnivå. Det är rimligt att upprätthålla en skillnad mellan den typiska toppbelastningen och de globala värdena så att det finns reserver för underhållsfönster eller trafikstörningar och Risktoppar kan dämpas. Du hittar mer information om systemomfattande tuning i artikeln om Justering av kärnan, som jag gärna använder som ett verktyg för djupgående OS-anpassningar. Checklista använda. Efter att ha gjort ändringar laddar jag om parametrarna, kontrollerar fil-nr igen och verifierar att alla tjänster har startats om med de nya gränserna och Värden ta över.
# Permanenta kärnparametrar
sudo bash -c 'cat >> /etc/sysctl.d/99-ulimits.conf <<EOF
fs.fil-max = 2097152
fs.nr_open = 2097152
EOF'
sudo sysctl --system
#-kontroll
cat /proc/sys/fs/file-max
cat /proc/sys/fs/nr_open || sysctl fs.nr_open
Kapacitetsplanering och arkitektur
Realistisk kapacitetsplanering börjar med mätning Profiler per förfrågan: Hur många FD:er behöver webbservern, applagret, databasen och cacheminnet tillsammans? Från dessa siffror härleder jag det totala antalet samtidigt öppna handtag per värd och planerar buffertar för Toppar på. Beräkna konservativt: loggrotation, ytterligare socklar, temporära filer och backup-jobb ökar efterfrågan och tar resurser i anspråk. Reserver. Jag uppmärksammar det faktum att horisontell skalning med lastbalanserare minskar FD-belastningen per nod, vilket minskar feltoleransen och förändringsfönstren. Förenklad. Endast med tydliga gränsvärden per nivå kan du sätta specifika gränser och fördela kapacitet mellan tjänster på ett förnuftigt sätt. dela.
Finjustering av webbserver och databas
För webbservrar håller jag mig till regeln Trådar*4 mindre än FD-gränsen så att det finns reserver för uppströmsanslutningar, temporära filer och loggar. För nginx och Apache inkluderar jag keep-alive, open access och felloggar samt uppströms sockets i beräkningen och säkrar mig på så sätt Buffert. Databaser som MariaDB eller PostgreSQL öppnar många uttag mot applikationer, replikering och övervakning; deras gränser måste matcha anslutningspoolen och trafiktopparna. passform. Cacher (Redis, Memcached) minskar DB-belastningen, men minskar inte nödvändigtvis antalet FD:er om många klienter gör parallella förfrågningar och anslutningar. håll. Jag planerar därför samordnade gränser längs hela kedjan: frontend, uppströms, DB, cache och meddelandeköer, så att den första hårda gränsen inte överskrids någonstans. Barriär når.
# Exempel: nginx systemd-gräns och arbetare
LimitNOFILE=65536 # systemd
arbetare_processer auto;
arbetare_anslutningar 4096; # 4096 * Arbetare <= 65536
# Exempel: PostgreSQL
max_connections = 1000 # FD-krav ~ 1-2 per anslutning + filer / loggar
Håll WordPress- och PHP-stackarna effektiva
WordPress-instanser med många plugins öppnar fler filer, fler nätverksanslutningar och mer Loggar. Jag minskar antalet onödiga includes med hjälp av OPCache, minskar belastningen på databaser med Redis Object Cache och lägger ut statiska tillgångar via ett CDN för att minimera filåtkomst och Anslutningar för att minska belastningen. Samtidigt ökar jag specifikt gränserna för php-fpm och webbservern så att toppar under cronjobs, crawlers eller butikskassor inte är ett problem. avbrott generera. En ren hantering av felloggar och rotationer hindrar loggskrivare från att stöta på ingenting och inte öppna nya filer kan. Det är så här jag kombinerar förbrukningsminskning och limitökning så att stacken förblir prisvärd under belastning och Genomströmning håll.
Containrar och molnmiljöer
I Docker och Kubernetes ärver processer ofta FD-gränserna för Noder, Det är därför jag först kontrollerar värdparametrarna och sedan tjänstdefinitionerna. Analoga principer gäller för systemd-nspawn eller containerd, men implementeringen görs i enhetsfiler, PodSpecs eller daemonkonfigurationer med Åsidosätter. Jag dokumenterar gränserna som kod (IaC) och håller dem konsekventa via playbooks så att nya noder har identiska gränser. Gränser ta med sig. Med Kubernetes kontrollerar jag också SecurityContexts och ställer in de nödvändiga funktionerna så att systemsidan Gränser träda i kraft. I slutändan är mätningen i klustret fortfarande viktig, eftersom schemaläggning, automatisk skalning och rullande uppdateringar ändrar fördelningen av öppna handtag och testar din Buffert.
# Exempel: systemd i containervärdar
cat <<'EOF' | sudo tee /etc/systemd/system/myapp.service.d/limits.conf
[Tjänst]
LimitNOFILE=65536
EOF
# Kubernetes: podSpec (containeravbildningen måste respektera ulimit)
# Obs: rlimit-inställningarna måste ställas in på olika sätt beroende på körtid/OS
Säkerhet, hastighetsbegränsning och övervakning
Höga gränser ger andrum, men de ökar också attackytan för Översvämningar, Jag begränsar därför förfrågningar vid kanten med hastighetsbegränsning och ställer in anslutningsgränser i webbservern. En brandvägg för webbapplikationer och förnuftiga timeouts förhindrar att inaktiva anslutningar blockerar FD:erna permanent. binda. För återkommande tester använder jag reproducerbara belastningsprofiler och använder Prometheus, Netdata eller Nagios för att konsekvent övervaka mätvärdena för öppna filer och Socklar. Beroende på arbetsbelastningen korrigerar jag gränsvärdena gradvis istället för att öka dem plötsligt så att effekterna förblir mätbara och Demontering är enkelt. Om du vill fördjupa dig i gränsvärden på anslutningssidan kan du hitta vägledning i den här kompakta artikeln om Gränser för anslutning, som jag använder vid nätverksgränser som Guide tjänar.
Felsökning med EMFILE: strukturerad procedur
Jag börjar med en titt in i Journal och i serviceloggarna för att begränsa tiden och frekvensen för felen. Jag använder sedan lsof för att kontrollera toppförbrukningen per process och identifiera mönster som läckor, ökande loggning eller ovanliga Sockel-typer. Därefter jämför jag de fastställda gränserna med verkliga toppar och höjer dem tillfälligt till en början så att jag kan validera orsak och verkan i ett kontrollerat test och utifrån detta fastställa Permanenta inställningar avleda. Om jag upptäcker en läcka korrigerar jag eller rullar tillbaka komponenten, eftersom högre gränser bara döljer symtom och skjuter upp problemet. Problem. Slutligen dokumenterar jag korrigeringen, ställer in larm och planerar ett nytt belastningstest så att lösningen är giltig och kan användas igen. Förtroende skapar.
Realistisk bedömning av resurskostnaderna för höga FD-gränser
Varje öppen fil eller socket kostar kärnminne. Därför bör du planera RAM-minnesutrymme Beroende på kärnversion och arkitektur krävs det några hundra byte till några kilobyte per FD (inklusive VFS/socket-strukturer). Med hundratusentals FD:er blir det en stor summa. Jag dimensionerar global file-max på ett sådant sätt att det i värsta fall finns tillräckligt med sidcache och arbetsminne kvar för applikationer. En enkel motkontroll görs via vmstat, free och trenden av öppna FD:er via file-nr under en Test av toppbelastning. Målet är en konfiguration som varken tippar över till swap vid toppbelastning eller utlöser överdriven återvinnings- eller OOM-aktivitet.
Fällor för distributions- och startvägar (PAM, systemd, Cron)
Huruvida begränsningar gäller beror på Starta sökvägen från. PAM-baserade inloggningar (ssh, su, login) läser /etc/security/limits.conf, medan systemd-tjänster främst använder sina enhetsparametrar (LimitNOFILE) och inte obligatorisk PAM. Cron/at kan ha sina egna kontexter. Jag validerar därför per tjänst:
- Hur startar processen? (systemctl status, ps -ef)
- Vilka gränser ser den verkligen? (cat /proc//limits)
- Fungerar PAM? (Kontrollera PAM-moduler i /etc/pam.d/*)
- Finns det systemomfattande standardvärden? (systemd: DefaultLimitNOFILE i system.conf)
På så sätt förhindrar jag att applikationer får olika FD-gränser beroende på startväg och från att inkonsekvent reagera.
Praktisk dimensionering med beräkningsexempel
Jag räknar med att Arbetare och anslutningsprofiler från bakåt till den FD-kapacitet som krävs:
- nginx med 8 arbetare med 4000 anslutningar vardera: ~32000 anslutningar. Som regel reserverar nginx 1 FD per aktiv anslutning; plus uppströms (keep-alive) och loggar lägger till ~10-20% buffert. Resultat: ~38000 FD:er för enbart nginx.
- php-fpm med 150 barn, vanligtvis 20-40 FDs per barn (inkluderar, sockets, loggar): konservativt 6000 FDs.
- Redis/DB-klienter: 200 parallella anslutningar, 1-2 FD:er vardera: ~400 FD:er.
Totalt per värd: ~44k FDs. Jag satte BegränsaNOFILE för nginx till 65536, php-fpm analog, och plan Globalt fs.file-max så att alla tjänster plus reserv (x1,5-x2) ryms. För flera hårt utnyttjade instanser per värd kan du skala globalt till 1-2 miljoner FD om RAM och I/O-vägar är tillräckliga. kapitulera.
Djupare diagnos: hitta läckor och hotspots
Om FD stiger kontinuerligt använder jag riktade verktyg för att hitta orsaken:
# Öppna handtag grupperade efter typ
lsof -p | awk '{print $5}' | sortera | uniq -c | sortera -nr
# Endast uttag i en process
lsof -Pan -p -i
# Vilka filer växer (loggar, temp)
lsof +L1 # Raderade men fortfarande öppna filer
ls -l /proc//fd
# Syscall-vy: vem öppnar hela tiden?
strace -f -p -e trace=open,openat,close,socket,accept,accept4 -s 0
Särskilt förrädiska är Raderade loggar, som fortfarande är öppna: De upptar utrymme och FD:er, men visas inte längre i filsystemet. Omstart eller en explicit återöppning (t.ex. med nginx via USR1) löser detta problem rent. Felaktigt konfigurerade watchers/exporters kan också ständigt öppna nya socklar - hastighetsbegränsningar och poolning.
Tydliga avgränsningar för Inotify, epoll och EMFILE
Det är inte alla resursgränser som kallas FD-gränser. I utvecklings- och CI-miljöer misslyckas ofta builds med ENOSPC i förhållande till Inotify (watcher limits). Jag kontrollerar och ställer in som ett komplement:
# Inotify-gränser (användarövergripande och instanser)
sysctl fs.inotify.max_användare_klockor
sysctl fs.inotify.max_användare_instanser
# Exempel på ökning
sudo sysctl -w fs.inotify.max_user_watches=524288
sudo sysctl -w fs.inotify.max_user_instances=1024
Medan epoll arbetar internt med FD, är den faktiska flaskhalsen med massiva Långlivade-anslutningar överskrider ofta själva FD-gränsen. Jag korrelerar därför epoll/event loop-data (t.ex. aktiva handtag) med filnummer och processrelaterad förbrukning.
Specialkunskaper inom språk och runtime (Java, Node.js, Go, Python)
Runtimes hanterar FD:er på olika sätt:
- Java/NettyMånga NOK-kanaler per process, ramverk för loggning håller filtillägg öppna. Jag sätter generösa gränser och roterar loggar med en återöppningsstrategi istället för att stänga/ersätta.
- Node.jsEMFILE uppstår snabbt med filsystemtunga arbetsbelastningar (t.ex. watcher, build pipelines). Jag reglerar parallella fs-operationer, ökar gränserna och ställer in backoff / retry-strategier.
- Gå tillHög parallellitet genom goroutines kan öppna många socklar. Jag begränsar tidsgränserna för uppringnings- och svarshuvud och kontrollerar om anslutningarna stängs på rätt sätt (IdleConnTimeout).
- Python/uWSGI/Gunicorn: Modeller med arbetare/trådar förbrukar FD för loggar, socklar och temporära filer; jag harmoniserar antalet arbetare, trådpooler och ingen fil-begränsningar.
De har alla en sak gemensamt: Utan samordnad stockrotation och tillförlitlig Hantering av anslutningar FD:er stiger gradvis.
Behållare i konkreta termer: Docker- och Kubernetes-inställningar
För att säkerställa att behållarna faktiskt ser de önskade gränserna sätter jag dem konsekvent längs kedjan:
- Körning av Dockerstartas med -ulimit nofile=65535:65535 eller ställs in av daemonens standard (t.ex. standardgränser).
- BilderStartskript bör inte återställa ett restriktivt ulimit.
- KubernetesBeroende på körtiden (containerd, cri-o) får rlimit-inställningarna olika effekt. Jag testar i podden via cat /proc/self/limits och justerar node/runtime-standardvärden om podspecifikationer inte är tillräckliga.
Speciellt i miljöer med flera hyresgäster säkrar jag Totalt belopp mot fs.file-max och isolera bullriga granneffekter med hjälp av separata nodesets eller pod-budgetar så att enskilda driftsättningar inte förbrukar de värdreserverade FD:erna.
Förtydliga övervakningsmått och larm
Förutom fil-nr och fil-max övervakar jag även FD:er och trendlinjer per process:
- SystemomfattandeTilldelat kontra maximalt, förändringstakt, förhållandet topp/maximum.
- Per processFD per arbetare/tråd, Top-N-processer, avvikelser på natten (batch/jobb).
- KvalitativHTTP-felfrekvenser, kölängder, accept/handskakningsfel synkroniserade med FD-trenden.
Jag ställer in varningar flera nivåerVarning vid 70-80%, kritisk från 90% av den konfigurerade gränsen, plus Detektering av läckage via stigande 7-dagars trender. Detta gör att jag kan reagera i god tid innan hårda barriärer träder i kraft.
Runbook för nödsituationer
När EMFILE drabbar akut agerar jag i tydliga steg:
- Identifiera de största förbrukarna (lsof, /proc//fd, journalposter).
- Öka tillfälligt den mjuka gränsen (ulimit i sessionen eller LimitNOFILE-överstyrning) och starta om tjänsten.
- Om loggar är orsaken: Stoppa rotationen, trigga återöppning, minska loggnivån.
- Överbelastad trafik vid kanten gasreglage (Öka eller skärpa prisgränserna/anslutningsgränserna - beroende på situationen).
- Åtgärda grundorsaken (läckage, för aggressiv parallellism, saknade timeouts) och permanenta begränsningar dra åt.
Uppföljning är viktigt: dokumentation, upprepade belastningstester och skärpningslarm så att samma kedja känns igen i ett tidigt skede.
Kortfattat sammanfattat
Med utökade FD-gränser, tydligt inställda kernelparametrar och en testad arkitektur kan jag tillhandahålla tjänster till mina kunder. Utrymme för manövrering under hög belastning. Jag mäter först, sätter sedan lämpliga gränsvärden, verifierar med belastningstester och säkrar resultatet med hastighetsbegränsning, övervakning och rensning. Regler.


