Процессы, порты и systemd

Процессы, порты и systemd

Ты деплоишь приложение, запускаешь - «port 8080 already in use». Кто-то занял порт. Или сервис упал ночью и не перезапустился. Всё это - про процессы.

Просмотр процессов

ps aux                        # все процессы
ps aux | grep nginx           # найти nginx
top                           # мониторинг в реальном времени (q - выход)
htop                          # красивый top (установить: apt install htop)

Что значат колонки в ps aux:

USER   PID  %CPU %MEM    VSZ   RSS TTY  STAT START   TIME COMMAND
root     1   0.0  0.1  16956  3456 ?    Ss   10:00   0:01 /sbin/init
user  1234   2.3  1.5 123456 15678 ?    Sl   10:05   0:30 ./backend
  • PID - ID процесса (нужен для kill)
  • %CPU / %MEM - потребление ресурсов
  • STAT - статус (S = sleeping, R = running, Z = zombie)

Управление процессами

Сравнение SIGTERM 15 и SIGKILL 9: вежливое и принудительное завершение

kill 1234              # попросить процесс завершиться (SIGTERM)
kill -9 1234           # убить принудительно (SIGKILL)
killall nginx          # завершить все процессы с именем nginx
`SIGKILL` не даёт процессу время на graceful shutdown. Сначала попробуй обычный `kill` (SIGTERM) - он позволяет закрыть соединения, дописать логи, завершить транзакции.

Кто занял порт?

ss -tlnp                       # все слушающие TCP порты
ss -tlnp | grep 8080           # кто на порту 8080
lsof -i :8080                  # альтернатива (нужен lsof)

Пример вывода ss -tlnp:

State   Recv-Q  Send-Q  Local Address:Port  Peer Address:Port  Process
LISTEN  0       128     0.0.0.0:8080        0.0.0.0:*          users:(("backend",pid=1234,fd=3))
LISTEN  0       128     0.0.0.0:5432        0.0.0.0:*          users:(("postgres",pid=567,fd=5))

systemd - менеджер сервисов

На большинстве серверов сервисы управляются через systemd:

systemctl status nginx         # статус сервиса
systemctl start nginx          # запустить
systemctl stop nginx           # остановить
systemctl restart nginx        # перезапустить
systemctl enable nginx         # запускать при старте системы
systemctl disable nginx        # не запускать при старте

Логи через journalctl

journalctl -u nginx            # логи nginx
journalctl -u nginx -f         # следить в реальном времени
journalctl -u nginx --since "1 hour ago"   # за последний час
journalctl -u nginx --no-pager | tail -50  # последние 50 строк

Свой systemd-сервис

Файл /etc/systemd/system/myapp.service:

[Unit]
Description=My Go Backend
After=network.target postgresql.service

[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/backend
Restart=on-failure
RestartSec=5
Environment=DATABASE_URL=postgres://...
EnvironmentFile=/opt/myapp/.env

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload       # перечитать конфиги
sudo systemctl enable myapp        # включить автозапуск
sudo systemctl start myapp         # запустить
С `Restart=on-failure` systemd автоматически перезапустит сервис, если он упал с ненулевым exit code. Это бесплатный «мониторинг» для простых случаев.

Фоновые процессы

./script.sh &                  # запустить в фоне
nohup ./script.sh &            # в фоне + не умрёт при закрытии SSH
jobs                           # список фоновых задач
fg                             # вернуть в передний план

Мини-задание

  • Выполни ps aux | grep -c "" - сколько процессов в системе?
  • Найди, кто слушает порт 22 (SSH): ss -tlnp | grep 22
  • Посмотри статус любого сервиса: systemctl status sshd
  • Прочитай последние логи: journalctl -u sshd --no-pager | tail -10

Итог

  • ps aux + grep - найти процесс. kill - завершить. kill -9 - в крайнем случае.
  • ss -tlnp - узнать, кто слушает порты. Это первая команда при «port already in use».
  • systemctl - управление сервисами. journalctl - их логи.

Типичная ошибка

Запускать приложение через ./backend & на сервере. При закрытии SSH сессия умрёт - и процесс вместе с ней. Используй systemd-сервис или хотя бы nohup.

Мини-практика

Запусти php -S localhost:9090 & (или npx serve -l 9090 &). Найди этот процесс через ps aux | grep 9090. Узнай его PID. Проверь порт через ss -tlnp | grep 9090. Завершите процесс через kill <PID>. Убедись, что порт освободился.

Зарегистрируйтесь бесплатно, чтобы пройти квиз, решить задание с автопроверкой и вести прогресс.