Cara hadkan memori dan CPU proses dengan systemd
Ketahui cara menetapkan MemoryHigh, MemoryMax, CPUQuota dan TasksMax dalam unit systemd. Elakkan VPS terhenti akibat proses yang tidak terkawal dengan konfigurasi cgroup v2.
Mengehadkan memori dan CPU proses dengan drop-in systemd
Anda boleh mengehadkan memori dan CPU proses pada VPS Linux dengan menambah beberapa baris pada unit yang menjalankan proses tersebut. MemoryMax= ialah had maksimum bagi memori. CPUQuota= ialah had bagi masa pemproses. Kedua-duanya dikuatkuasakan oleh cgroup v2 (control groups, versi 2), iaitu ciri kernel yang digunakan oleh systemd untuk merekodkan setiap servis pada pelayan.
sudo systemctl edit myapp.servicePerintah tersebut membuka fail drop-in dengan arahan dalam bentuk komen. Tambahkan baris ini di atasnya:
[Service]
MemoryHigh=512M
MemoryMax=768M
MemorySwapMax=0
CPUQuota=80%
TasksMax=128sudo systemctl daemon-reload
sudo systemctl restart myapp.service
systemctl show myapp.service -p MemoryHigh -p MemoryMax -p CPUQuotaPerSecUSec -p TasksMaxsystemctl show mesti memaparkan semula nombor anda dalam unit kernel itu sendiri: MemoryMax=805306368 dan CPUQuotaPerSecUSec=800ms. Jika ia memaparkan MemoryMax=infinity, bermakna drop-in tersebut tidak dimuatkan. Pastikan fail tersebut berada di /etc/systemd/system/myapp.service.d/override.conf, dan ia bermula dengan pengepala [Service], kerana baris tetapan tanpa bahagian di atasnya akan menyebabkan systemd merekodkan Assignment outside of section. Ignoring. dan memulakan servis tanpa sebarang had.
Bahagian seterusnya dalam panduan ini menerangkan cara memilih nombor tersebut, dan perkara yang mungkin masih tidak berfungsi selepas ia ditetapkan.
Mengapa proses yang tidak terkawal membekukan VPS walaupun tidak memenuhi kapasiti
Proses yang mencapai had memori maksimum akan terhenti dalam masa kira-kira satu saat dan servis akan dimulakan semula. Itu adalah senario yang baik. Senario yang buruk ialah apabila tiada apa-apa yang terhenti: pelayan menjawab ping, SSH menerima sambungan, tetapi prompt shell tidak pernah muncul. Mesin tersebut hidup dan sibuk, namun tiada kerja yang berguna dilakukan.
Berikut adalah mekanismenya, kerana ia tidak begitu jelas. Apabila memori bebas semakin berkurangan, kernel akan menuntut semula halaman (page) dan bukannya memberikan yang baharu. Halaman yang paling murah untuk dituntut semula ialah yang disokong oleh fail (file-backed), dan cache halaman menyimpan kod boleh laku bagi setiap proses yang sedang berjalan. Oleh itu, kernel mengeluarkan halaman teks bagi sshd, dan arahan seterusnya yang dijalankan oleh sshd ialah page fault yang perlu membaca semula bait tersebut daripada storan. Setiap proses akhirnya menunggu cakera dan bukannya berjalan. Halaman yang sama keluar dan masuk dalam satu gelung, yang dipanggil thrashing.
Dua perkara menjadikan keadaan ini lebih buruk pada VPS berbanding komputer riba. Storan sering kali disambungkan melalui rangkaian atau dikongsi, jadi setiap fault mengambil masa lebih banyak milisaat berbanding peranti NVMe tempatan. Selain itu, kernel tidak mengukur masa, ia mengukur kegagalan: selagi proses tuntutan semula terus memberikan halaman, tidak kira betapa perlahan, kernel percaya ia sedang membuat kemajuan dan tidak memanggil out of memory (OOM) killer. Sebuah mesin boleh berada dalam keadaan itu selama beberapa minit sebelum ada apa-apa yang ditamatkan.
Anda boleh memerhatikan perkara ini berlaku. Kernel mengeksport pressure stall information (PSI) pada Linux 4.20 dan versi lebih baharu:
cat /proc/pressure/memory
cat /proc/pressure/iosome avg10=63.72 avg60=41.02 avg300=12.33 total=13729481
full avg10=48.15 avg60=30.44 avg300=8.90 total=9114233Baris full adalah yang paling penting. full avg10=48.15 bermaksud sepanjang sepuluh saat yang lalu, 48% daripada masa setiap tugas yang boleh dijalankan pada mesin tersebut terhenti menunggu kerja memori, jadi tiada apa-apa yang berjalan. Pelayan yang sihat mencatatkan bacaan hampir sifar pada full. Bacaan melebihi 10 akan terasa perlahan kepada manusia, dan 40 atau lebih adalah keadaan yang sering digambarkan sebagai beku.
Inilah sebabnya had (limit) sahaja bukanlah satu jaminan. Unit yang ditahan di bawah MemoryHigh= akan dikawal (throttle) dan bukannya ditamatkan, jadi ia kekal hidup dan perlahan, dan tiada apa-apa yang memulakan semula unit tersebut kerana dari sudut pandangan systemd, ia tidak pernah gagal. Unit yang dihadkan dan masih dibenarkan menggunakan swap akan menjana bacaan dan tulisan yang dicaj kepada unit tersebut tetapi dilayan oleh satu peranti yang dikongsi, jadi ia boleh menolak /proc/pressure/io naik bagi setiap servis lain pada mesin tersebut. Had menentukan siapa yang menanggung beban kekurangan, dan ia tidak boleh mencipta kapasiti tambahan.
Semak sama ada VPS anda menjalankan cgroup v2
stat -fc %T /sys/fs/cgroupcat /sys/fs/cgroup/cgroup.controllers
cgroup2fs ialah hierarki bersatu, iaitu apa yang diperlukan oleh setiap tetapan di bawah. tmpfs bermaksud pelayan but menggunakan susun atur v1 yang lebih lama, di mana MemoryHigh= dan MemorySwapMax= tidak wujud dan kelakuan OOM bagi setiap unit adalah berbeza. Ubuntu 22.04 dan versi lebih baharu, serta Debian 11 dan versi lebih baharu, menggunakan v2 secara lalai. Imej lama, atau kernel yang dibut dengan systemd.unified_cgroup_hierarchy=0, tidak menggunakannya.
Pada cgroup v2, systemd menghidupkan perakaunan memori untuk setiap unit secara lalai, jadi angka-angka tersebut sudah tersedia:
systemd-cgtop -msystemd-cgtop
Ini menyenaraikan cgroup yang disusun mengikut penggunaan memori, yang merupakan cara terpantas untuk menjawab "apa yang memakan sumber pelayan ini" semasa ia masih boleh memberi respons. Jika pelayan adalah baharu, kerja akaun dan firewall dalam sepuluh minit pertama pada VPS baharu perlu dilakukan sebelum ini.
MemoryHigh mengehadkan, MemoryMax menamatkan.
Perbezaan antara kedua-dua tetapan memori ini menentukan rupa kegagalan yang berlaku.
MemoryHigh=ialah had lembut (soft cap). Apabila melebihi had ini, kernel akan menuntut semula memori secara agresif daripada cgroup tersebut dan melambatkan peruntukan memorinya secara sengaja. Penggunaan masih boleh melebihi angka tersebut, dan tiada proses yang ditamatkan.MemoryMax=ialah had keras (hard cap). Apabila peruntukan tidak dapat dipenuhi di bawah had ini, OOM killer akan berjalan di dalam cgroup tersebut dan menamatkan salah satu proses unit itu sendiri.
Bahagian kedua itulah sebab sebenar untuk menetapkan MemoryMax= pada mana-mana perkhidmatan yang tidak dipercayai sepenuhnya. Tanpa had, kekurangan memori menjadi masalah seluruh pelayan, dan OOM killer global akan memilih mangsanya berdasarkan oom_score, yang biasanya merujuk kepada proses paling besar. Proses paling besar biasanya ialah pangkalan data anda, bukan skrip yang mengalami kebocoran memori. Dengan had, penamatan hanya berlaku di dalam unit yang menyebabkannya.
Tetapkan kedua-duanya, dengan MemoryHigh= sekitar 20 hingga 30 peratus di bawah MemoryMax=. Jurang ini merupakan zon amaran: kebocoran perlahan akan melepasi High dan kelihatan sebagai perkhidmatan yang menjadi perlahan, manakala lonjakan mendadak akan terus melepasi Max dan menyebabkan proses mati.
Nilai peratusan dibaca berdasarkan memori fizikal yang dipasang, jadi MemoryMax=25% pada pelan 4 GB adalah 1 GB dan kekal sebagai satu perempat daripada kapasiti pelayan selepas anda menukar saiz pelan tersebut. MemorySwapMax=0 menghalang unit tersebut daripada menggunakan swap sepenuhnya, yang menukarkan proses yang perlahan kepada penamatan yang pantas dan jelas.
Had memerlukan polisi mulakan semula (restart policy) bersamanya, jika tidak, penamatan hanya akan menyebabkan perkhidmatan terhenti.
[Unit]
StartLimitIntervalSec=300
StartLimitBurst=5
[Service]
Restart=on-failure
RestartSec=5sStartLimit* perlu diletakkan di dalam [Unit] dan Restart= di dalam [Service]. Jika diletakkan di bahagian yang salah, systemd akan mengabaikannya. Lima kali mulakan semula dalam tempoh lima minit dianggap sebagai kebocoran dan bukannya gangguan sementara, jadi selepas itu systemd akan berhenti mencuba dan membiarkan unit dalam keadaan gagal. Ini adalah keadaan yang anda mahu temui kemudian, bukannya gelung ranap (crash loop) yang menyembunyikan masalah sebenar.
Hadkan CPU dengan CPUQuota, atau kongsikannya dengan CPUWeight
CPUQuota= mengambil peratusan masa yang tersedia pada satu CPU. CPUQuota=50% adalah separuh daripada satu teras. CPUQuota=200% adalah setara dengan dua teras, yang mana unit tersebut boleh mengagihkannya merentasi seberapa banyak thread yang diperlukan. Pada pelan 2 vCPU, CPUQuota=200% adalah keseluruhan mesin.
CPUWeight= ialah lalai yang lebih baik untuk kebanyakan servis. Ia merupakan perkongsian relatif daripada 1 hingga 10000, dan lalai kernel ialah 100. Ia hanya memberi kesan apabila terdapat persaingan: tugasan sandaran pada CPUWeight=20 akan mengalah kepada pelayan web pada 100 semasa beban tinggi, dan masih menggunakan keseluruhan kotak apabila kotak tersebut melahu. Kuota keras akan membazirkan kapasiti melahu tersebut.
Jujurlah tentang apa yang anda perolehi daripada had CPU. Proses yang terikat dengan CPU jarang menyebabkan Linux terhenti, kerana penjadual terus memberikan masa kepada semua orang. Memori adalah perkara yang menjatuhkan sesebuah kotak. Gunakan CPUQuota= apabila anda mahukan siling yang boleh diramal, contohnya pada binaan atau ejen yang sebaliknya akan berjalan pada tahap maksimum selama sejam. Penentuan saiz beban kerja sebegini adalah persoalan tersendiri, yang dibincangkan dalam berapa banyak RAM dan CPU yang diperlukan oleh VPS ejen pengekodan.
Jika CPU dibaca sebagai sibuk sedangkan tiada proses anda yang melakukan banyak kerja, puncanya mungkin terletak di sebelah pihak hypervisor. Itu adalah masa curi CPU daripada jiran yang bising, dan tiada kuota yang anda tetapkan akan mengubahnya.
TasksMax menghalang gelung fork
TasksMax= ialah bilangan proses dan thread yang boleh dipegang oleh sesuatu unit. Thread juga dikira, jadi servis Java atau Go memerlukan ruang tambahan berbanding apa yang ditunjukkan oleh senarai proses. Ini merupakan perlindungan paling murah terhadap skrip yang melakukan fork secara berulang, kerana fork akan gagal di dalam unit tersebut dan bukannya menyebabkan pelayan kehabisan process ID.
TasksMax=128Apabila sesuatu unit mencapai had tersebut, kernel akan merekodkan satu baris log yang menamakan cgroup berkenaan:
cgroup: fork rejected by pids controller in /system.slice/myapp.serviceProgram itu sendiri biasanya akan melaporkan fork: retry: Resource temporarily unavailable. Semak nilai yang digunakan oleh pengurus secara lalai dengan systemctl show -p DefaultTasksMax.
Mengehadkan kerja sekali jalan dengan systemd-run
Anda tidak memerlukan fail unit untuk menggunakan mana-mana fungsi ini. systemd-run membina unit sementara di sekitar satu arahan tunggal.
sudo systemd-run --scope -p MemoryMax=1G -p MemorySwapMax=0 -p CPUQuota=50% -p TasksMax=64 ./import-data.sh--scope menjalankan arahan dalam terminal anda, selepas mencetak Running scope as unit: run-r7c1a....scope. Output kekal pada skrin anda dan had tersebut hilang apabila arahan tamat. Sebarang sifat daripada systemd.resource-control berfungsi selepas -p.
Untuk kerja yang panjang, gugurkan --scope dan berikan nama kepadanya. Ia kemudian berjalan di latar belakang sebagai servis sementara dan mencatat log ke dalam journal:
sudo systemd-run --unit=nightly-import -p MemoryMax=1G -p CPUWeight=20 ./import-data.sh
journalctl -u nightly-import -fPilihan yang sama berfungsi dengan --user apabila anda bukan root, walaupun pengurus pengguna anda hanya mempunyai pengawal yang diwakilkan kepadanya, jadi sesuatu sifat mungkin ditolak di situ. Jalankannya dengan sudo jika perkara itu berlaku. Apabila sesuatu kerja mendapat tempat kekal, tetapan tersebut dipindahkan tanpa perubahan ke dalam unit sebenar: lihat menjalankan skrip sebagai servis dan pemasa systemd.
Persoalan swap, dijawab dengan jujur
Swap mengubah bentuk kegagalan dan bukannya menghalangnya.
Tanpa swap, kebocoran memori akan mencapai had maksimum dan sesuatu proses akan mati dalam beberapa saat. Gangguan tersebut berlaku secara nyata, singkat, dan mudah dibaca dalam journal selepas itu. Dengan swap, kernel menulis halaman anonim yang tidak aktif ke cakera dan membeli masa. Jika proses tersebut akan stabil, swap menyelamatkan anda. Jika ia adalah proses yang tidak terkawal, swap menukarkan gangguan lima saat kepada kelembapan selama dua puluh minit, dan kelembapan itu lebih buruk, kerana proses yang mati masih membolehkan anda menggunakan shell, manakala sistem yang mengalami thrashing tidak membenarkannya.
swapon --show
free -hJalan tengah yang boleh digunakan pada VPS kecil: simpan fail swap yang sederhana untuk halaman yang diperuntukkan sekali dan tidak pernah disentuh lagi, serta tetapkan MemorySwapMax=0 pada unit yang anda sanggup korbankan. Servis penting mengekalkan swap mereka. Servis yang tidak dapat diramal akan mencapai had dengan cepat dan dimulakan semula.
Merendahkan vm.swappiness adalah langkah yang kurang berkesan, dan penting untuk mengetahui sebabnya. Ia hanya mengalihkan keseimbangan antara menyingkirkan page cache dan menukar halaman anonim, dan kedua-duanya memerlukan bacaan cakera kemudiannya. Ia hanya mengubah halaman mana yang mengalami thrashing, bukan sama ada sistem itu mengalami thrashing atau tidak.
Daemon OOM awal menamatkan proses sebelum berlaku stall
Kernel menunggu sehingga proses reclaim gagal sepenuhnya, dan pada VPS kecil, tempoh menunggu tersebut merupakan detik tepat anda kehilangan akses kepada mesin. Dua daemon ruang pengguna (userspace) menutup jurang ini dengan memantau memori sendiri dan menamatkan proses dengan lebih awal.
earlyoom memantau memori tersedia dan swap bebas, serta menamatkan proses dengan skor tertinggi apabila mana-mana nilai jatuh di bawah ambang yang ditetapkan.
sudo apt install earlyoom
systemctl status earlyoomPakej Debian dan Ubuntu memulakan servis ini semasa pemasangan. Pilihan konfigurasinya terletak dalam /etc/default/earlyoom:
EARLYOOM_ARGS="-m 5,2 -s 5,2 --avoid '^(sshd|systemd)$' --prefer '^(node|python3)$'"-m PERCENT menetapkan minimum memori tersedia dan -s PERCENT menetapkan minimum swap bebas, kedua-duanya ditetapkan kepada 10 peratus secara lalai. Nombor kedua dalam setiap pasangan ialah titik SIGKILL: earlyoom menghantar SIGTERM sebaik sahaja nilai jatuh di bawah nilai pertama, kemudian SIGKILL di bawah nilai kedua, yang secara lalai adalah separuh daripada nilai pertama. Gunakan perubahan dengan sudo systemctl restart earlyoom, dan baca journalctl -u earlyoom untuk melihat proses yang telah ditamatkan serta jumlah memori yang digunakan oleh proses tersebut.
systemd-oomd merupakan pilihan yang satu lagi. Halaman manualnya menyifatkannya sebagai "servis sistem yang menggunakan cgroups-v2 dan pressure stall information (PSI) untuk memantau serta mengambil tindakan pembetulan sebelum OOM berlaku dalam ruang kernel". Ia bertindak ke atas keseluruhan cgroups dan bukannya proses tunggal, jadi ia menamatkan unit, bukan proses anak yang terasing. Unit perlu memilih untuk menyertai dengan ManagedOOMMemoryPressure=kill atau ManagedOOMSwap=kill, dan ambang ditetapkan dalam /etc/systemd/oomd.conf.
systemctl status systemd-oomd
oomctloomctl mencetak maklumat yang sedang dipantau, yang selalunya tiada pada imej pelayan, kerana tetapan ini memerlukan pengaktifan (opt-in) bagi setiap unit. Pilih satu daemon dan gunakan itu sahaja. Menjalankan kedua-duanya bermakna dua entiti berlumba untuk memilih mangsa, dan punca bagi sebarang penamatan proses menjadi lebih sukar untuk dikenal pasti.
Unit manakah yang bertanggungjawab?
Mulakan dengan kernel, kerana ia merekodkan setiap tindakan penamatan (kill) yang dilakukannya.
journalctl -k --grep "Killed process" --since "2 hours ago"Tindakan penamatan daripada OOM killer global kelihatan seperti ini:
Out of memory: Killed process 4127 (node) total-vm:2731084kB, anon-rss:1874232kB, file-rss:0kB, shmem-rss:0kB, UID:1000 pgtables:4212kB oom_score_adj:0anon-rss ialah memori yang dipegang oleh proses tersebut dalam RAM semasa ia mati, iaitu kira-kira 1.8 GB dalam contoh ini. Baca nama di dalam kurungan dengan penuh syak wasangka. Itu adalah mangsa yang dipilih oleh kernel, dan kernel biasanya memilih proses yang paling besar, yang tidak semestinya merupakan proses yang menyebabkan kekurangan memori tersebut.
Tindakan penamatan daripada had cgroup mempunyai awalan yang berbeza, dan laporan yang dicetak di atasnya menamakan cgroup yang telah mencapai hadnya sendiri:
Memory cgroup out of memory: Killed process 8811 (python3) total-vm:1044320kB, anon-rss:769112kB, file-rss:0kB, shmem-rss:0kB, UID:998 pgtables:1720kB oom_score_adj:0Awalan tersebut merupakan sebahagian besar daripada diagnosis. Memory cgroup out of memory bermaksud satu unit telah mencapai MemoryMax= yang anda tetapkan dan bahagian pelayan yang lain berada dalam keadaan baik. Out of memory yang biasa bermaksud mesin tersebut kehabisan memori secara keseluruhan, jadi had anda mungkin tiada atau terlalu longgar untuk dikira.
Kemudian, tanya systemd tentang apa yang dilihatnya:
systemctl status myapp.service
journalctl -u myapp.service -n 50myapp.service: A process of this unit has been killed by the OOM killer.
myapp.service: Main process exited, code=killed, status=9/KILL
myapp.service: Failed with result 'oom-kill'.systemctl status menyatakan perkara yang sama dalam satu baris, sebagai Active: failed (Result: oom-kill).
Kaunter cgroup ialah sumber ketiga, dan satu-satunya sumber yang merekodkan throttling, yang tidak akan menghasilkan sebarang baris log:
cat /sys/fs/cgroup/system.slice/myapp.service/memory.events
cat /sys/fs/cgroup/system.slice/myapp.service/memory.peaklow 0
high 4213
max 118
oom 12
oom_kill 12high mengira berapa kali unit tersebut ditolak melebihi MemoryHigh= dan dikenakan throttling. max mengira berapa kerap ia mencapai had keras (hard cap), dan oom_kill mengira proses yang benar-benar ditamatkan. Nilai high yang besar dengan oom_kill 0 adalah kes senyap yang disebut sebelum ini: servis sedang berjalan, menjadi sangat perlahan, dan tidak melaporkan sebarang kegagalan kepada sesiapa. memory.peak (Linux 5.19 dan lebih baharu) menyimpan penggunaan tertinggi yang dicapai oleh cgroup, iaitu nombor yang perlu digunakan untuk menetapkan saiz MemoryMax=. Kedua-dua fail ini ditetapkan semula apabila unit dimulakan semula, kerana systemd mencipta cgroup tersebut sekali lagi.
Satu prasyarat terletak di bawah semua ini. Jika /var/log/journal tidak wujud, journal akan disimpan dalam RAM, dan setiap baris akan hilang selepas but semula (reboot) yang anda perlukan untuk memulihkan pelayan tersebut.
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
journalctl --list-bootsjournalctl --list-boots yang menunjukkan lebih daripada but semasa bermaksud sejarah kini tersimpan, jadi journalctl -k -b -1 boleh menunjukkan kepada anda mesej kernel daripada but yang mengalami kegagalan tersebut.
Titik permulaan untuk VPS kecil
Pada pelan 2 GB, peruntukkan 300 hingga 400 MB untuk kernel dan cache halaman, dan jangan biarkan jumlah had mencapai 2 GB sepenuhnya, kerana setiap unit boleh mencapai kemuncak penggunaan pada saat yang sama. Berikan bahagian terbesar kepada servis yang paling penting, kemudian hadkan semua servis spekulatif di sekelilingnya.
[Service]
MemoryHigh=256M
MemoryMax=384M
MemorySwapMax=0
CPUWeight=20
TasksMax=64
Restart=on-failure
RestartSec=5sMengekalkan akses masuk adalah berbaloi dengan satu lagi tetapan. OOMScoreAdjust=-500 dalam fail drop-in untuk ssh.service menjadikan OOM killer global kurang berkemungkinan untuk memilih daemon SSH anda sebagai mangsa, yang merupakan perbezaan antara membaiki pelayan dan melakukan but semula daripada panel kawalan. Ia hanya mengubah pilihan mangsa oleh kernel. Ia tidak memendekkan tempoh terhenti (stall).
Kontena berjalan dalam cgroupnya sendiri, yang dicipta oleh runtime kontena dan bukannya oleh fail unit anda, jadi had pada docker.service tidak menjadi had pada satu kontena. Setara bagi setiap kontena untuk MemoryMax= dan CPUQuota= diliputi dalam menetapkan had memori dan CPU dalam Docker Compose.
FAQ
Mengapa VPS saya membeku dan bukannya menamatkan proses yang tidak terkawal?
Kerana kernel menilai kemajuan berdasarkan sama ada proses reclaim mengembalikan halaman memori, bukan berdasarkan tempoh masa yang diambil. Apabila memori berkurangan, ia akan mengeluarkan page cache, termasuk halaman boleh laksana bagi program yang sedang berjalan, kemudian membacanya semula pada arahan seterusnya. Segala-galanya menunggu storan dan secara teknikal tiada peruntukan yang gagal, jadi OOM killer tidak dipanggil. Semak /proc/pressure/memory semasa perkara ini berlaku: full avg10 melebihi 40 bermakna hampir tiada tugasan yang dapat dijalankan dalam tempoh sepuluh saat terakhir. Daemon ruang pengguna seperti earlyoom akan menamatkan proses sebelum pelayan mencapai keadaan tersebut.
Apakah perbezaan antara MemoryHigh dan MemoryMax?
MemoryHigh= ialah had lembut yang melakukan throttling. Kernel melakukan reclaim secara agresif daripada unit tersebut dan memperlahankan peruntukannya, tetapi penggunaan boleh melebihi angka tersebut dan tiada apa-apa yang ditamatkan. MemoryMax= ialah had keras: peruntukan yang tidak dapat dipenuhi di bawah had ini akan mencetuskan OOM killer di dalam cgroup unit itu sendiri, jadi proses yang menyebabkan masalah tersebut akan ditamatkan dan bukannya proses terbesar pada pelayan. Tetapkan MemoryHigh= di bawah MemoryMax= dan anggap jurang antara keduanya sebagai zon amaran.
Bagaimanakah cara mencari servis yang ditamatkan oleh OOM killer?
Jalankan journalctl -k --grep "Killed process" --since "2 hours ago". Baris yang bermula dengan Memory cgroup out of memory bermakna satu unit telah mencapai MemoryMax= miliknya sendiri, manakala Out of memory biasa bermakna keseluruhan mesin kehabisan memori. Kemudian jalankan journalctl -u <unit> -n 50 dan cari Failed with result 'oom-kill'. Jika /var/log/journal tidak wujud pada pelayan anda, jurnal tersebut disimpan dalam RAM dan bukti tersebut hilang semasa but semula, jadi cipta direktori tersebut sebelum kejadian seterusnya.
Patutkah saya menambah swap pada VPS yang kecil?
Fail swap yang kecil membantu mengurus halaman sejuk yang diperuntukkan sekali dan tidak pernah disentuh lagi. Ia tidak membantu dengan proses yang tidak terkawal: ia hanya melambatkan penamatan dan menggantikan gangguan singkat dengan tempoh pegun yang lama sehingga anda tidak boleh log masuk untuk membaikinya. Pastikan saiz swap sederhana, dan tetapkan MemorySwapMax=0 pada unit yang anda sanggup korbankan, supaya unit tersebut mencapai hadnya dan dimulakan semula dengan cepat sementara servis penting mengekalkan swap mereka.
Bolehkah saya mengehadkan arahan tanpa menulis fail unit?
Boleh. sudo systemd-run --scope -p MemoryMax=1G -p CPUQuota=50% ./script.sh menjalankan arahan dalam terminal anda di dalam transient scope dengan had tersebut, dan had itu akan hilang apabila arahan tamat. Setiap sifat daripada systemd.resource-control tersedia selepas -p, jadi MemorySwapMax=, TasksMax= dan CPUWeight= juga berfungsi di sana. Gugurkan --scope dan tambah --unit=name untuk menjalankan tugasan di latar belakang dengan outputnya disimpan dalam jurnal.