Какое-то дёрганное лето получается. Новые проблемы сыпятся, как из рога изобилия. Жара что ли на сервера так влияет? Расскажу историю очередной проблемы, с которой столкнулся. Там есть несколько поучительных моментов.
На одном проекте ночью упал Redis, сайт начал 500-ю ошибку отдавать. Нечасто такое случается. Редис если и упадёт, то обычно быстро поднимается, потому что используют его в основном под кэш в оперативной памяти, данные можно не сохранять.
Redis словил ошибку Segmentation fault. Эта такая мутная тема, потому что нельзя однозначно сказать, из-за чего она возникает. Это могут быть как проблемы с железом, так и с самим софтом. Либо банально оперативной памяти на сервере не хватило.
У меня скорее всего последний вариант, так как в момент падения сервер реально сильно нагрузили, причём разносторонней нагрузкой. Рядом работающая СУБД в этот же момент скинула на диск свой пул и буферный кэш. Это осталось в её логе. Они это делают, чтобы освободить оперативную память, если её не хватает.
В настройках systemd юнита Redis указан параметр
Redis всю ночь поднимался и падал, постоянно записывая что-то на диск. Это видно по мониторингу. Забил весь ресурс дисков своей записью. Он писал свои трейсы в лог, но помимо них ещё какую-то информацию. Судя по всему своё состояние пытался скинуть, но не получалось. Я трейсы бегло посмотрел, но особо не вникал, так как там без должного понимания ничего особо не увидишь.
В общем случае с параметром
Но как я уже сказал, у меня что-то пошло не так. В данном случае было бы лучше, если бы он тихо помер и не мучал больше сервер. Помогло в итоге то, что я туром проснулся, вручную остановил его и запустил заново:
Так что сильно рассчитывать на systemd в таких вопросах не стоит. Очень желательно настраивать для критичных сервисов внешний мониторинг службы, чтобы она отвечала по настроенному TCP порту или Unix сокету. Отдавала какие-то данные или своё состояние передавала. И если не отвечает, то каким-то образом гарантированно перезапускать её, в зависимости от того, где она запущена, как служба на сервере или в отдельном контейнере.
Если бы это была СУБД, типа MySQL или Postgres, которая всю ночь пыталась подняться и падала, то даже не знаю, что бы стало с данными. Для этих баз данных такое поведение может быть фатальным, особенно если они упали из-за проблем с диском, а при старте запускали восстановление данных. Постоянные перезапуски их добьют. Так что аккуратнее с параметром
Я в итоге снизил потребление памяти у некоторых служб, чтобы избежать ситуаций, когда память вся закончится. Буду наблюдать. Надеюсь, что проблема не повторится.
#linux #systemd #ошибка
На одном проекте ночью упал Redis, сайт начал 500-ю ошибку отдавать. Нечасто такое случается. Редис если и упадёт, то обычно быстро поднимается, потому что используют его в основном под кэш в оперативной памяти, данные можно не сохранять.
Redis словил ошибку Segmentation fault. Эта такая мутная тема, потому что нельзя однозначно сказать, из-за чего она возникает. Это могут быть как проблемы с железом, так и с самим софтом. Либо банально оперативной памяти на сервере не хватило.
У меня скорее всего последний вариант, так как в момент падения сервер реально сильно нагрузили, причём разносторонней нагрузкой. Рядом работающая СУБД в этот же момент скинула на диск свой пул и буферный кэш. Это осталось в её логе. Они это делают, чтобы освободить оперативную память, если её не хватает.
В настройках systemd юнита Redis указан параметр
Restart=always. Подробно на эту тему я делал отдельную заметку. Рекомендую ознакомиться, если не знаете. Данный параметр означает, что при любой причине завершения работы службы будет попытка поднять её. Я упоминал в той заметке, что не всегда это бывает полезно. И это как раз мой случай.Redis всю ночь поднимался и падал, постоянно записывая что-то на диск. Это видно по мониторингу. Забил весь ресурс дисков своей записью. Он писал свои трейсы в лог, но помимо них ещё какую-то информацию. Судя по всему своё состояние пытался скинуть, но не получалось. Я трейсы бегло посмотрел, но особо не вникал, так как там без должного понимания ничего особо не увидишь.
В общем случае с параметром
Restart=always служба должна подняться автоматически. Я потестировал немного на отдельной виртуалке. Если Редису дать команду SIGSEGV, то он так же, как у меня вышло, скидывает свой трейс в лог, завершает работу и запускается заново. Проверить можно так:# kill -SIGSEGV $(pidof redis-server)Но как я уже сказал, у меня что-то пошло не так. В данном случае было бы лучше, если бы он тихо помер и не мучал больше сервер. Помогло в итоге то, что я туром проснулся, вручную остановил его и запустил заново:
# systemctl stop redis-server# systemctl start redis-serverТак что сильно рассчитывать на systemd в таких вопросах не стоит. Очень желательно настраивать для критичных сервисов внешний мониторинг службы, чтобы она отвечала по настроенному TCP порту или Unix сокету. Отдавала какие-то данные или своё состояние передавала. И если не отвечает, то каким-то образом гарантированно перезапускать её, в зависимости от того, где она запущена, как служба на сервере или в отдельном контейнере.
Если бы это была СУБД, типа MySQL или Postgres, которая всю ночь пыталась подняться и падала, то даже не знаю, что бы стало с данными. Для этих баз данных такое поведение может быть фатальным, особенно если они упали из-за проблем с диском, а при старте запускали восстановление данных. Постоянные перезапуски их добьют. Так что аккуратнее с параметром
Restart.Я в итоге снизил потребление памяти у некоторых служб, чтобы избежать ситуаций, когда память вся закончится. Буду наблюдать. Надеюсь, что проблема не повторится.
#linux #systemd #ошибка
👍103👎3
Не смог пропустить знаменательное событие сегодняшнего дня. Не забыли о нём? Сделаем так, чтобы на нашем сервере костры рябин горели вечно. Кстати, купил на днях в питомнике 3 рябины. Так что у меня скоро будут гореть реальные костры рябин.
Я уже раньше подобное делал с помощью cron. Пришло время применить systemd timers.
Итак, настроим на сервере вечное 3-е сентября. Для этого первым делом надо отключить синхронизацию времени, в зависимости от того, как она настроена. В современных серверах скорее всего это сделает команда:
Далее нам нужно установить дату на 3-е сентября и добавить в планировщик. Можно сделать это в лоб вот так:
Но тогда устанавливается время на 00:00. Можно сделать аккуратнее и менять только день, не трогая часы. Для этого создадим очень простой скрипт:
Берём текущее время, текущий год и выставляем третье сентября текущего года с неизменным временем. Сохраняем скрипт в
Создаём systemd сервис -
Делаем таймер для службы
Перечитываем конфигурацию и запускаем таймер со службой:
Теперь у вас постоянно переворачивается календарь и каждый день 3-е сентября. Подобную заготовку можно использовать под любой свой скрипт.
#юмор #systemd
Я уже раньше подобное делал с помощью cron. Пришло время применить systemd timers.
Итак, настроим на сервере вечное 3-е сентября. Для этого первым делом надо отключить синхронизацию времени, в зависимости от того, как она настроена. В современных серверах скорее всего это сделает команда:
# timedatectl set-ntp falseДалее нам нужно установить дату на 3-е сентября и добавить в планировщик. Можно сделать это в лоб вот так:
# date -s "2025-09-03 00:00:00"Но тогда устанавливается время на 00:00. Можно сделать аккуратнее и менять только день, не трогая часы. Для этого создадим очень простой скрипт:
#!/bin/bash
now_date=$(date +%H:%M:%S)
now_year=$(date +%Y)
date -s "$now_year-09-03 $now_date"
Берём текущее время, текущий год и выставляем третье сентября текущего года с неизменным временем. Сохраняем скрипт в
/usr/local/bin/3sep.sh и делаем исполняемым:# chmod +x /usr/local/bin/3sep.shСоздаём systemd сервис -
/etc/systemd/system/3sep.service:[Unit]
Description=Set system date to September 3rd, po zavetam Shafutinskogo
[Service]
Type=oneshot
ExecStart=/usr/local/bin/3sep.sh
[Install]
WantedBy=multi-user.target
Делаем таймер для службы
/etc/systemd/system/3sep.timer:[Unit]
Description=Turn over the calendar every minute
[Timer]
OnCalendar=*:0/1
Unit=3sep.service
Persistent=false
[Install]
WantedBy=timers.target
Перечитываем конфигурацию и запускаем таймер со службой:
# systemctl daemon-reload# systemctl enable --now 3sep.serviceТеперь у вас постоянно переворачивается календарь и каждый день 3-е сентября. Подобную заготовку можно использовать под любой свой скрипт.
#юмор #systemd
3👍107👎14
Относительно недавно (2018 год) по меркам Linux в составе базовых системных утилит популярных дистрибутивов появилась утилита choom. Узнал о ней случайно. В Debian и Ubuntu она есть по умолчанию, отдельно ставить не надо. В других не проверял.
Забегая вперёд скажу, что лично я для неё применения не увидел, но решил всё равно написать для общего образования. Кому-то может пригодится. Не просто же так её написали и добавили в дистрибутивы. С помощью choom можно управлять таким параметром, как OOM score adjustment (oom_score_adj). На его основе OOM-killer принимает решение о том, какой процесс завершить при нехватке оперативной памяти в системе.
Choom работает с запущенными процессами на лету, используя их pid. Примерно так:
Посмотрели текущее значения
Проверяем:
Oom_score стал 0, а oom_score_adj, как и указали -1000. В данном примере pid 1994 - это процесс mariadbd. Удобней было бы сделать сразу вот так:
Вообще, принцип работы OOM-killer довольно замороченный. Как видно, у него есть два параметра oom_score и oom_score_adj. Первый показывает текущие накопленные баллы, которые динамически изменяются в зависимости от различных условий, а второй - это то, что задаётся вручную и тоже влияет на oom_score. Сделав oom_score_adj минимальным, то есть -1000, мы и oom_score уменьшили.
Вручную всё это менять имеет смысл только в каких-то отладочных целях. Для постоянной работы этими параметрами удобнее управлять через systemd. Просто указываем в unit файле сервиса нужные значения:
Перезапускаем сервис и проверяем. В случае с mariadb это будет выглядеть так. Делаем корректировку стандартного юнита:
Добавляем в конфигурацию:
Перечитываем параметры юнита и перезапускаем его.
Проверяем значение:
По сути choom удобен именно для просмотра. Смотреть значения с помощью утилиты быстрее и проще, чем напрямую:
Она по сути именно это и делает. И меняет значение тоже переопределяя именно эти параметры.
На практике я никогда не занимался настройкой
Исключение, наверное, для каких-то специфических случаев, когда целенаправленно нужно использовать всю память сервера, но при этом гарантированно иметь работающим какое-то приложение. Я не могу придумать таких примеров, но думаю, что они есть. Если кто-то знает такие истории, поделитесь в комментариях. Когда вам приходилось целенаправленно настраивать OOMScoreAdjust? В голову приходят агенты мониторинга. Желательно, чтобы они всегда работали, но на практике я не видел, чтобы их первым отключал OOM-killer.
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#linux #terminal #systemd
Забегая вперёд скажу, что лично я для неё применения не увидел, но решил всё равно написать для общего образования. Кому-то может пригодится. Не просто же так её написали и добавили в дистрибутивы. С помощью choom можно управлять таким параметром, как OOM score adjustment (oom_score_adj). На его основе OOM-killer принимает решение о том, какой процесс завершить при нехватке оперативной памяти в системе.
Choom работает с запущенными процессами на лету, используя их pid. Примерно так:
# choom -p 1994pid 1994's current OOM score: 684pid 1994's current OOM score adjust value: 0Посмотрели текущее значения
oom_score и oom_score_adj. Для того, чтобы максимально уменьшить шанс для процесса быть убитыми, ему нужно присвоить параметр oom_score_adj -1000. Соответственно, параметр 1000 будет означать максимальный шанс. То есть там разбег от -1000 до 1000. И чем меньше значение, тем меньше шанса быть завершённым. # choom -p 1994 -n -1000Проверяем:
# choom -p 1994pid 1994's current OOM score: 0pid 1994's current OOM score adjust value: -1000Oom_score стал 0, а oom_score_adj, как и указали -1000. В данном примере pid 1994 - это процесс mariadbd. Удобней было бы сделать сразу вот так:
# choom -p $(pidof mariadbd) -n 1000Вообще, принцип работы OOM-killer довольно замороченный. Как видно, у него есть два параметра oom_score и oom_score_adj. Первый показывает текущие накопленные баллы, которые динамически изменяются в зависимости от различных условий, а второй - это то, что задаётся вручную и тоже влияет на oom_score. Сделав oom_score_adj минимальным, то есть -1000, мы и oom_score уменьшили.
Вручную всё это менять имеет смысл только в каких-то отладочных целях. Для постоянной работы этими параметрами удобнее управлять через systemd. Просто указываем в unit файле сервиса нужные значения:
[Service]............OOMScoreAdjust=-800............Перезапускаем сервис и проверяем. В случае с mariadb это будет выглядеть так. Делаем корректировку стандартного юнита:
# systemctl edit mariadbДобавляем в конфигурацию:
[Service]OOMScoreAdjust=-800Перечитываем параметры юнита и перезапускаем его.
# systemctl daemon-reload# systemctl restart mariadbПроверяем значение:
# choom -p $(pidof mariadbd)pid 2274's current OOM score: 152pid 2274's current OOM score adjust value: -800По сути choom удобен именно для просмотра. Смотреть значения с помощью утилиты быстрее и проще, чем напрямую:
# cat /proc/2274/oom_score# cat /proc/2274/oom_score_adjОна по сути именно это и делает. И меняет значение тоже переопределяя именно эти параметры.
На практике я никогда не занимался настройкой
OOMScoreAdjust. Если на сервере кончается память и приходит OOM-killer - это аварийная ситуация. Надо идти и разбираться, куда утекает память и почему её не хватает. Обычно после этого её должно хватать. Исключение, наверное, для каких-то специфических случаев, когда целенаправленно нужно использовать всю память сервера, но при этом гарантированно иметь работающим какое-то приложение. Я не могу придумать таких примеров, но думаю, что они есть. Если кто-то знает такие истории, поделитесь в комментариях. Когда вам приходилось целенаправленно настраивать OOMScoreAdjust? В голову приходят агенты мониторинга. Желательно, чтобы они всегда работали, но на практике я не видел, чтобы их первым отключал OOM-killer.
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#linux #terminal #systemd
3👍84👎1