Процессы, порты и 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)
Управление процессами
kill 1234 # попросить процесс завершиться (SIGTERM)
kill -9 1234 # убить принудительно (SIGKILL)
killall nginx # завершить все процессы с именем nginx
Кто занял порт?
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 # запустить
Фоновые процессы
./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>. Убедись, что порт освободился.