SSD Nodes Learn Hosting plans →
Panduan Matt ConnorOleh Matt Connor · Dikemas kini 2026-08-29

Cara Hadkan Memori dan CPU Proses dengan Systemd

Ketahui cara mengehadkan penggunaan sumber VPS menggunakan MemoryHigh, MemoryMax, dan CPUQuota. Elakkan sistem terhenti dengan menetapkan TasksMax pada unit systemd anda.

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 untuk memori. CPUQuota= ialah had untuk 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.service

Perintah tersebut membuka fail drop-in yang mengandungi arahan dalam bentuk komen. Tambahkan baris ini di atasnya:

[Service]
MemoryHigh=512M
MemoryMax=768M
MemorySwapMax=0
CPUQuota=80%
TasksMax=128
sudo systemctl daemon-reload
sudo systemctl restart myapp.service
systemctl show myapp.service -p MemoryHigh -p MemoryMax -p CPUQuotaPerSecUSec -p TasksMax

systemctl show mesti memaparkan semula nombor anda dalam unit kernel yang betul: MemoryMax=805306368 dan CPUQuotaPerSecUSec=800ms. Jika ia mencetak MemoryMax=infinity, 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 seksyen di atasnya akan menyebabkan systemd mencatat Assignment outside of section. Ignoring. dan menjalankan 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 memori tidak penuh

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 gesaan shell tidak pernah muncul. Mesin tersebut hidup dan sibuk, namun tiada kerja yang dilakukan adalah berguna.

Berikut adalah mekanismenya, kerana ia tidak begitu jelas. Apabila memori bebas menjadi rendah, kernel akan menuntut semula halaman (reclaim pages) dan bukannya memberikan halaman baharu. Halaman yang paling murah untuk dituntut semula ialah yang disokong oleh fail (file-backed), dan cache halaman menyimpan kod boleh laku bagi setiap perkara yang sedang berjalan. Oleh itu, kernel mengeluarkan halaman teks bagi sshd, dan arahan seterusnya yang dijalankan oleh sshd ialah kegagalan halaman (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 selalunya disambungkan melalui rangkaian atau dikongsi, jadi setiap kegagalan memakan 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 pembunuh kehabisan memori (OOM killer). Sebuah mesin boleh berada dalam keadaan itu selama beberapa minit sebelum apa-apa dihentikan.

Anda boleh memerhatikan perkara ini berlaku. Kernel mengeksport maklumat tekanan gerai (pressure stall information atau PSI) pada Linux 4.20 dan versi yang lebih baharu:

cat /proc/pressure/memory
cat /proc/pressure/io
some avg10=63.72 avg60=41.02 avg300=12.33 total=13729481
full avg10=48.15 avg60=30.44 avg300=8.90 total=9114233

Baris full adalah yang penting. full avg10=48.15 bermaksud sepanjang sepuluh saat yang lalu, 48% daripada masa setiap tugas yang boleh dijalankan pada mesin tersebut terhenti kerana menunggu kerja memori, jadi tiada apa-apa yang berjalan. Pelayan yang sihat mencatatkan bacaan hampir sifar pada full. Melebihi 10, ia terasa perlahan kepada manusia, dan 40 atau lebih adalah keadaan yang digambarkan oleh orang ramai sebagai beku.

Ini juga sebab mengapa had sahaja bukanlah satu jaminan. Unit yang ditahan di bawah MemoryHigh= akan diperlahankan (throttled) dan bukannya dihentikan, jadi ia kekal hidup dan kekal perlahan, dan tiada apa-apa yang memulakannya semula kerana dari sudut pandangan systemd, ia tidak pernah gagal. Unit yang dihadkan dan masih dibenarkan untuk menggunakan swap akan menjana bacaan dan tulisan yang dicaj kepada unit tersebut tetapi dilayan oleh satu peranti kongsi, jadi ia boleh menolak /proc/pressure/io naik bagi setiap servis lain pada mesin tersebut. Had menentukan siapa yang menanggung kekurangan, dan ia tidak boleh mencipta kapasiti.

Semak sama ada VPS anda menjalankan cgroup v2

stat -fc %T /sys/fs/cgroup

cat /sys/fs/cgroup/cgroup.controllers

cgroup2fs ialah hierarki bersatu, iaitu keperluan bagi setiap tetapan di bawah. tmpfs bermaksud pelayan but menggunakan susun atur v1 yang lama, di mana MemoryHigh= dan MemorySwapMax= tidak wujud dan kelakuan OOM bagi setiap unit adalah berbeza. Ubuntu 22.04 dan versi terbaharu, serta Debian 11 dan versi terbaharu, 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 tersebut sudah tersedia:

systemd-cgtop -m

systemd-cgtop

Perintah tersebut menyenaraikan cgroup yang disusun mengikut penggunaan memori, iaitu cara terpantas untuk menjawab "apa yang memakan sumber pelayan ini" sementara pelayan masih boleh bertindak balas. 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 unit yang anda tidak percayai sepenuhnya. Tanpa had, kekurangan memori menjadi masalah seluruh pelayan, dan OOM killer global akan memilih mangsanya berdasarkan oom_score, yang biasanya bermaksud proses yang paling besar. Proses yang paling besar biasanya ialah pangkalan data anda, bukan skrip yang mengalami kebocoran memori. Dengan had, tindakan 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 servis yang menjadi perlahan, manakala lonjakan mengejut akan terus menembusi Max dan menyebabkan servis 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.

Beberapa servis membolehkan anda menentukan keperluan memori mereka lebih awal dan bukannya mengukurnya: unit Ollama menetapkan saiz cache KV daripada tetingkap konteks (context window) yang anda berikan, jadi baca kos peningkatan num_ctx dalam RAM sebelum anda memilih had maksimum untuknya.

Had memerlukan polisi mulakan semula (restart policy) bersamanya, jika tidak, penamatan hanya akan menyebabkan servis anda berhenti.

[Unit]
StartLimitIntervalSec=300
StartLimitBurst=5

[Service]
Restart=on-failure
RestartSec=5s

StartLimit* perlu diletakkan di dalam [Unit] dan Restart= di dalam [Service]. Jika anda meletakkan mana-mana daripadanya di bahagian yang salah, systemd akan mengabaikannya. Lima kali mulakan semula dalam tempoh lima minit dianggap sebagai kebocoran dan bukannya gangguan kecil, jadi selepas itu systemd akan berhenti mencuba dan membiarkan unit tersebut 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% ialah separuh daripada satu teras. CPUQuota=200% adalah bersamaan dengan dua teras, yang mana unit tersebut boleh mengagihkannya merentasi seberapa banyak thread yang diingini. Pada pelan 2 vCPU, CPUQuota=200% ialah 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: kerja sandaran pada CPUWeight=20 akan mengalah kepada pelayan web pada 100 semasa beban tinggi, dan masih menggunakan keseluruhan kotak semasa 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 membekukan Linux, 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 satu jam. Menentukan 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 satu pun proses anda 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 menghentikan gelung fork

TasksMax= ialah bilangan proses dan thread yang boleh ditampung 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 ID proses.

TasksMax=128

Apabila sesuatu unit mencapai had tersebut, kernel akan mencatat satu baris log yang menamakan cgroup berkenaan:

cgroup: fork rejected by pids controller in /system.slice/myapp.service

Program 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 -f

Pilihan 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. Jalankan ia dengan sudo jika itu berlaku. Apabila sesuatu kerja memerlukan 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 mencapai had maksimum dan sesuatu akan terhenti dalam beberapa saat. Gangguan tersebut berlaku secara nyata, singkat, dan mudah dibaca dalam journal selepas itu. Dengan swap, kernel menulis halaman anomim 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 tempoh terhenti selama dua puluh minit, dan tempoh terhenti itu lebih buruk, kerana proses yang mati masih membolehkan anda menggunakan shell yang berfungsi, manakala sistem yang mengalami thrashing tidak membolehkannya.

swapon --show
free -h

Jalan 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 anomim, dan kedua-duanya memerlukan bacaan cakera kemudiannya. Ia mengubah halaman mana yang mengalami thrashing, bukan sama ada sistem itu mengalami thrashing atau tidak.

Daemon OOM awal mematikan proses sebelum berlaku stall

Kernel menunggu sehingga proses reclaim gagal sepenuhnya, dan pada VPS kecil, tempoh menunggu tersebut adalah saat tepat anda kehilangan akses kepada mesin. Dua daemon ruang pengguna (userspace) menutup jurang ini dengan memantau memori sendiri dan mematikan proses dengan lebih awal.

earlyoom memantau memori tersedia dan swap bebas, serta mematikan proses dengan skor tertinggi apabila mana-mana nilai tersebut jatuh di bawah ambang yang ditetapkan.

sudo apt install earlyoom
systemctl status earlyoom

Pakej 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 pada 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 lalainya adalah separuh daripada nilai pertama. Gunakan perubahan dengan sudo systemctl restart earlyoom, dan baca journalctl -u earlyoom untuk melihat proses yang telah dimatikan serta jumlah memori yang digunakan oleh proses tersebut.

systemd-oomd ialah pilihan yang satu lagi. Halaman manualnya menerangkannya 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 mematikan unit, bukan sekadar 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
oomctl

oomctl mencetak apa yang sedang dipantau, yang selalunya tiada apa-apa pada imej pelayan, kerana tetapan ini memerlukan pengaktifan (opt-in) bagi setiap unit. Pilih satu daemon sahaja dan berhenti di situ. Menjalankan kedua-duanya bermakna dua entiti berlumba untuk memilih mangsa, dan punca bagi sebarang tindakan mematikan 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:0

anon-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 punca 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:0

Awalan tersebut merupakan sebahagian besar daripada diagnosis. Memory cgroup out of memory bermaksud satu unit telah mencapai MemoryMax= yang anda tetapkan dan bahagian lain pelayan berada dalam keadaan baik. Out of memory yang biasa bermaksud mesin tersebut kehabisan memori secara keseluruhan, jadi had anda mungkin tiada atau terlalu longgar sehingga jumlah keseluruhannya melebihi kapasiti.

Seterusnya, tanya systemd tentang apa yang dilihatnya:

systemctl status myapp.service
journalctl -u myapp.service -n 50
myapp.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).

Pembilang cgroup adalah sumber ketiga, dan satu-satunya sumber yang merekodkan pendikitan (throttling), yang tidak menghasilkan sebarang baris log:

cat /sys/fs/cgroup/system.slice/myapp.service/memory.events
cat /sys/fs/cgroup/system.slice/myapp.service/memory.peak
low 0
high 4213
max 118
oom 12
oom_kill 12

high mengira berapa kali unit tersebut ditolak melebihi MemoryHigh= dan didikit. max mengira kekerapan 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 MemoryMax=. Kedua-dua fail ini ditetapkan semula apabila unit dimulakan semula, kerana systemd mencipta semula cgroup tersebut.

Satu prasyarat terletak di bawah semua ini. Jika /var/log/journal tidak wujud, jurnal disimpan dalam RAM, dan setiap baris akan hilang selepas but semula (reboot) yang anda perlukan untuk memulihkan pelayan.

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
journalctl --list-boots

journalctl --list-boots yang menunjukkan lebih daripada but semasa bermakna sejarah kini tersimpan, jadi journalctl -k -b -1 boleh menunjukkan kepada anda mesej kernel daripada but yang menyebabkan kegagalan tersebut.

Titik permulaan untuk VPS kecil

Pada pelan 2 GB, peruntukkan 300 hingga 400 MB untuk kernel dan page cache. Jangan biarkan jumlah had mencapai 2 GB sepenuhnya, kerana setiap unit boleh mencapai penggunaan puncak pada masa 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=5s

Mengekalkan akses masuk adalah berbaloi dengan satu tetapan tambahan. OOMScoreAdjust=-500 dalam fail drop-in untuk ssh.service menjadikan OOM killer global kurang berkemungkinan memilih daemon SSH anda sebagai mangsa. Ini adalah perbezaan antara membaiki pelayan dan melakukan but semula daripada panel kawalan. Ia hanya mengubah pilihan mangsa oleh kernel. Ia tidak memendekkan tempoh gangguan.

Kontena berjalan dalam cgroup tersendiri yang dicipta oleh runtime kontena dan bukannya oleh fail unit anda. Oleh itu, had pada docker.service tidak menjadi had untuk satu kontena. Persamaan bagi setiap kontena untuk MemoryMax= dan CPUQuota= dibincangkan dalam menetapkan had memori dan CPU dalam Docker Compose.

FAQ

Mengapa VPS saya membeku dan bukannya mematikan 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 menyingkirkan 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 ia berlaku: full avg10 melebihi 40 bermakna hampir tiada tugasan yang dapat dijalankan dalam sepuluh saat terakhir. Daemon ruang pengguna seperti earlyoom akan mematikan 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 melambatkan peruntukan memorinya, tetapi penggunaan boleh melebihi angka tersebut dan tiada apa-apa yang dimatikan. 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 dimatikan dan bukannya proses terbesar pada pelayan. Tetapkan MemoryHigh= di bawah MemoryMax= dan anggap jurang antara keduanya sebagai zon amaran.

Bagaimanakah cara untuk mencari servis yang dimatikan 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 apabila but semula, jadi cipta direktori tersebut sebelum kejadian seterusnya.

Perlukah saya menambah swap pada VPS yang kecil?

Fail swap yang kecil membantu menguruskan halaman sejuk (cold pages) yang diperuntukkan sekali dan tidak pernah disentuh lagi. Ia tidak membantu dengan proses yang tidak terkawal: ia hanya melambatkan proses penamatan dan menggantikan gangguan singkat dengan kegagalan jangka panjang yang menghalang anda daripada log masuk untuk membaikinya. Pastikan swap pada tahap 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?

Ya. 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.