O'z systemd xizmatini yaratish
Shu paytgacha biz faqat paketlar o'rnatgan tayyor .service fayllarini boshqardik. Lekin administrator ishining katta qismi o'zingiz yozgan yoki qo'lda o'rnatgan dasturni xuddi shunday xizmatga aylantirishdan iborat: systemctl orqali boshqariladigan, boot paytida avtomatik ishga tushadigan va ishdan chiqqandan keyin avtomatik qayta ishga tushadigan xizmatga. Bu maqola yangi .service faylini noldan yozadi; Backend ilovani xizmat sifatida maqolasi esa xuddi shu bilimni haqiqiy backend ilovasi bilan to'liq, real vaziyatga qo'llaydi.
Nimalarni o'rganasiz
Bu maqola oxirida siz quyidagilarni qila olasiz:
- yangi
.servicefayl qayerga joylashishi va qanday nomlanishi kerakligini bilish; - asosiy
Type=qiymatlarini (simple,forking,oneshot) bir-biridan farqlash; ExecStart=,Restart=,User=kabi eng muhim[Service]direktivalarini qo'llash;- unit faylini yaratgan yoki tahrirlagandan keyin nega
daemon-reloadkerakligini tushuntirish; - yangi xizmatni ishga tushirish va tekshirishning to'liq siklini bajarish.
Minimal ishlaydigan misol
Faraz qilaylik, /opt/hello/hello.sh — cheksiz siklda har 10 soniyada xabar chiqaradigan skript:
Endi shu skript uchun unit fayl yarating:
[Unit]
Description=Hello demo service
After=network.target
[Service]
Type=simple
ExecStart=/opt/hello/hello.sh
Restart=on-failure
[Install]
WantedBy=multi-user.target
Info
Yangi unit fayllar har doim /etc/systemd/system/ ga joylashadi — bu systemd unitlari va targetlari maqolasida ko'rilgan eng yuqori ustuvorlikdagi katalog. /lib/systemd/system/ paket menejeri boshqaradigan fayllar uchun ajratilgan.
Type=: xizmat qanday ishga tushishini tasvirlash
systemd xizmatni qachon "muvaffaqiyatli ishga tushgan" deb hisoblashni bilishi kerak — Type= aynan shuni bildiradi:
Type qiymati |
Ishga tushish shakli | Qachon ishlatiladi |
|---|---|---|
simple (sukut bo'yicha) |
ExecStart= jarayoni oldingi planda ishlaydi, hech qachon fork qilmaydi |
O'zi fork qilmaydigan zamonaviy ilovalar va daemon’lar (ko'p Node.js, Python, Go dasturlari) |
forking |
ExecStart= jarayoni o'zini fork qiladi, ota-jarayon chiqib ketadi, bola davom etadi |
Klassik Unix daemon’lari (masalan, sukut bo'yicha rejimdagi nginx) |
oneshot |
Buyruq bir marta ishlaydi va chiqib ketadi, davom etadigan jarayon yo'q | Skript yoki bir martalik sozlash amali (masalan, boshqa xizmatdan oldin bajarilishi kerak bo'lgan tayyorgarlik) |
notify |
Dastur tayyorligini sd_notify() orqali systemd ga xabar qiladi |
sd_notify protokolini amalga oshirgan dasturlar |
Amalda backend ilovalari (Python, Node.js, Go, Java) deyarli har doim Type=simple dan foydalanadi, chunki ular fork qilmasdan oldingi planda ishlaydi.
Warning
Noto'g'ri Type= tanlash ko'rsatiladigan xizmat holatini chalkashtirib yuboradi. Masalan, aslida fork qiladigan dasturga Type=simple qo'llansa, ota-jarayon chiqib ketishi bilan systemd xizmatni "to'xtagan" deb hisoblaydi, garchi bola jarayon hali ishlayotgan bo'lsa ham.
Asosiy [Service] direktivalari
| Direktiva | Vazifasi |
|---|---|
ExecStart= |
Xizmat ishga tushganda bajariladigan buyruq (absolyut yo'l bo'lishi shart) |
ExecStop= |
Xizmatni to'xtatish uchun maxsus buyruq (ko'rsatilmasa, systemd standart signal yuboradi) |
ExecReload= |
systemctl reload chaqirilganda bajariladigan buyruq |
Restart= |
Xizmatni qachon avtomatik qayta ishga tushirish: no, on-failure, always va boshqalar |
RestartSec= |
Qayta ishga tushirishdan oldin qancha kutish (soniyalarda) |
User= / Group= |
Xizmat qaysi foydalanuvchi/guruh nomidan ishlaydi |
WorkingDirectory= |
Xizmatning ishchi katalogi |
EnvironmentFile= |
Xizmat muhit o'zgaruvchilarini o'qiydigan tashqi fayl |
[Service]
Type=simple
User=hello
WorkingDirectory=/opt/hello
ExecStart=/opt/hello/hello.sh
Restart=on-failure
RestartSec=5
Restart=on-failure xizmat noldan farqli (xato) kod bilan chiqsa yoki signal bilan o'ldirilsa, uni avtomatik qayta ishga tushiradi, lekin u systemctl stop bilan oddiy tarzda to'xtatilgan bo'lsa, qayta ishga tushirmaydi. Restart=always esa har qanday chiqishda (oddiy stop dan tashqari holatlarda ham) qayta ishga tushiradi — bu ko'proq maxsus holatlar uchun qoldirilgan.
Xizmatni root o'rniga User=/Group= ostida ishga tushirish muhim xavfsizlik amaliyoti bo'lib, Backend ilovani xizmat sifatida maqolasida chuqurroq ko'rib chiqiladi.
Yangi unit faylni faollashtirish
Unit fayl yaratilgan yoki tahrirlangandan keyin systemd uni darhol "ko'rmaydi" — u unit fayllarni faqat ishga tushganda yoki aniq aytilganda qayta o'qiydi:
daemon-reload systemd ga barcha unit fayllarni diskdan qayta o'qishni buyuradi. Bu buyruq /etc/systemd/system/ ostidagi fayl yaratilgan yoki o'zgartirilgan har safar ishga tushirilishi kerak — aks holda systemd xotiradagi eski konfiguratsiya bilan ishlashda davom etadi.
Endi xizmatni ishga tushiring va boot uchun yoqing:
Tekshiring:
● hello.service - Hello demo service
Loaded: loaded (/etc/systemd/system/hello.service; enabled; preset: enabled)
Active: active (running) since Fri 2026-07-24 11:05:02 UTC; 12s ago
Main PID: 5211 (hello.sh)
Tasks: 2 (limit: 4665)
Memory: 1.1M
CPU: 15ms
CGroup: /system.slice/hello.service
├─5211 /bin/bash /opt/hello/hello.sh
└─5215 sleep 10
Active: active (running) va enabled birgalikda xizmat hozir ham ishlayotganini, ham keyingi boot’da avtomatik ishga tushishini bildiradi — bu Xizmatlarni boshqarish maqolasidagi holatlar jadvaliga mos keladi.
Restart= siyosatini sinash
sudo kill -9 $(systemctl show -p MainPID --value hello.service)
sleep 6
systemctl status hello.service
kill -9 jarayonni majburan o'ldiradi (kutilmagan ishdan chiqishni simulyatsiya qiladi). RestartSec=5 sozlangan bo'lsa, bir necha soniyadan keyin systemctl status xizmat yangi PID bilan yana ishlayotganini ko'rsatishi kerak.
Avtomatik qayta ishga tushirish taslim bo'lganda: ishga tushish chastotasini cheklash
Restart= cheksiz urinmaydi. systemd ma’lum vaqt oynasi ichidagi qayta ishga tushishlarni sanaydi va agar xizmat juda qisqa vaqtda juda ko'p marta qayta ishga tushsa, urinishni to'xtatib, unit’ni failed holatiga o'tkazadi:
hello.service: Start request repeated too quickly.
hello.service: Failed with result 'start-limit-hit'.
Bu oynani [Unit] bo'limidagi ikkita direktiva boshqaradi — StartLimitIntervalSec= (sukut bo'yicha 10s) va StartLimitBurst= (sukut bo'yicha 5): Interval ichida Burst dan ortiq ishga tushish cheklovni ishga tushiradi. Bu ataylab qilingan — haqiqatan buzilgan xizmat (noto'g'ri konfiguratsiya, yetishmayotgan bog'liqlik) cheksiz ishdan chiqish siklida CPU’ni behuda sarflashining oldini oladi. Asl sabab tuzatilgach, xizmat yana ishga tushishi uchun hisoblagichni tozalash kerak:
Intervyuda
"Restart=always bo'lgan xizmat failed holatida qotib qolgan va qayta ko'tarilmayapti — nega?" — keng tarqalgan vaziyat savoli. Javob deyarli har doim ishga tushish cheklovi: jarayon ishga tushishda StartLimitBurst/StartLimitIntervalSec ruxsat berganidan tezroq ishdan chiqyapti, shuning uchun systemd ataylab taslim bo'lgan. To'g'ri yo'l — ishdan chiqish sababini journalctl -u <unit> dan o'qish, uni tuzatish, so'ng reset-failed qilish. Cheklovni oshirish emas, chunki bu faqat siklni yashiradi.
Keng tarqalgan xatolar
daemon-reload ni unutish
Agar unit fayl daemon-reload ishga tushirilmasdan tahrirlansa, systemctl restart eski konfiguratsiya bilan ishlaydi — fayl to'g'ri saqlangan bo'lsa ham, o'zgarish "kuchga kirmayotgandek" ko'rinadi.
ExecStart= da nisbiy yo'l ishlatish
WorkingDirectory= aniq o'rnatilmasa, systemd xizmatlari ishchi katalogni meros qilib olmaydi. ExecStart=./hello.sh kabi nisbiy yo'l ko'pincha "No such file or directory" xatosi bilan yiqiladi — har doim absolyut yo'l (/opt/hello/hello.sh) ishlating.
Kerak bo'lmasa ham xizmatni root sifatida ishga tushirish
User= direktivasi bo'lmasa, xizmat sukut bo'yicha root sifatida ishlaydi. Agar dasturga aslida root huquqlari kerak bo'lmasa, bu ortiqcha xavfsizlik xavfini tug'diradi — Backend ilovani xizmat sifatida maqolasida ko'rsatilganidek, alohida foydalanuvchi yaratish tavsiya etilgan yondashuv.
Mashqlar
- Sinov VM’ida yuqoridagi
hello.servicemisolini yarating, unidaemon-reloadvaenable --nowbilan ko'taring va chiqishinijournalctl -u hello.service -fbilan kuzating (keyingi maqola — journalctl da chuqur ko'rib chiqiladi). - Jarayonni
kill -9bilan o'ldirib,Restart=on-failuresiyosati ishlashini tasdiqlang. Restart=on-failureniRestart=noga o'zgartiring,daemon-reloadvarestartni bajaring, so'ng jarayonni yanakill -9bilan o'ldiring va farqni tushuntiring.- Ataylab
Type=simpleniType=oneshotga o'zgartiring va nima o'zgarishini kuzating (xizmatning yakuniy holatiga e’tibor bering).
Mashqni bajardim deyish uchun: tahrirdan keyin "yangilanmayotgandek" ko'rinadigan xizmat uchun uni tuzatish uchun ishga tushiriladigan birinchi buyruqni tushuntira olishingiz kerak.
Xulosa
Yangi .service fayl /etc/systemd/system/ ichida yaratiladi va kamida Description=, ExecStart= hamda — boot paytida avtomatik ishga tushish uchun — WantedBy= qiymatini o'z ichiga olishi kerak. Type= xizmat qanday ishga tushishini tasvirlaydi, Restart=/RestartSec= esa ishdan chiqqandan keyingi tiklanish siyosatini belgilaydi. Unit fayldagi har qanday o'zgarish daemon-reload ni talab qiladi, aks holda systemd eski konfiguratsiya bilan ishlashda davom etadi. Keyingi maqola — Backend ilovani xizmat sifatida aynan shu bilimni haqiqiy backend loyihasiga qo'llaydi va xavfsizlik hamda muhitni sozlash amaliyotlarini qo'shadi.