Tarkibga o'tish

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 .service fayl 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-reload kerakligini 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:

/opt/hello/hello.sh
#!/usr/bin/env bash
while true; do
    echo "Hello, $(date)"
    sleep 10
done
sudo chmod +x /opt/hello/hello.sh

Endi shu skript uchun unit fayl yarating:

sudo nano /etc/systemd/system/hello.service
/etc/systemd/system/hello.service
[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:

sudo systemctl daemon-reload

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:

sudo systemctl enable --now hello.service

Tekshiring:

systemctl status hello.service
● 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:

sudo systemctl reset-failed hello.service
sudo systemctl start hello.service

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

  1. Sinov VM’ida yuqoridagi hello.service misolini yarating, uni daemon-reload va enable --now bilan ko'taring va chiqishini journalctl -u hello.service -f bilan kuzating (keyingi maqola — journalctl da chuqur ko'rib chiqiladi).
  2. Jarayonni kill -9 bilan o'ldirib, Restart=on-failure siyosati ishlashini tasdiqlang.
  3. Restart=on-failure ni Restart=no ga o'zgartiring, daemon-reload va restart ni bajaring, so'ng jarayonni yana kill -9 bilan o'ldiring va farqni tushuntiring.
  4. Ataylab Type=simple ni Type=oneshot ga 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.

Manbalar