Оригинал: Code Logs (идентификатор общедоступной учетной записи WeChat: codelogs), добро пожаловать в общий доступ, пожалуйста, сохраните источник для перепечатки.
Введение
Пока программисты работают долго, они всегда будут сталкиваться с какими-то странными вещами.Например, когда вы уходите с работы, сервис зависает, а потом придут бизнес-одноклассники.Кажется, что бизнес и сервис программы неотделимы от вас.
И когда вы входите в машину для устранения неполадки, вы обнаруживаете, что на машине нет процессов, и вы на некоторое время паникуете.Почему процессы исчезли?
фоновые задачи
Учащиеся, плохо знакомые с Linux, могут не знать концепции приоритетных и фоновых задач в Shell.Позвольте мне сначала представить это следующим образом:
- Когда команда выполняется напрямую, запускается задача переднего плана, а после добавления команды
&
символ, который позволяет запустить процесс в качестве фоновой задачи. - Используйте задания для запроса всех фоновых задач, запущенных в текущей оболочке.
- Если процесс является приоритетной задачей, нажмите
Ctrl+z
Ее можно сделать фоновой задачей, но при этом задача будет приостановлена. - использовать
bg
Задачу в состоянии паузы можно перевести в состояние выполнения. - использовать
fg
Фоновую задачу можно сделать задачей переднего плана, и если задача находится в приостановленном состоянии, она станет запущенной.
См. пример:
# 启动前台进程,然后按Ctrl+z使其变后台进程
$ java -jar app.jar
^Z
[1]+ Stopped java -jar app.jar
# 查询后台进程,可发现它是Stopped状态
$ jobs -l
[1]+ 19316 Stopped java -jar app.jar
# 使用bg后,可以发现任务变Running状态了
$ bg %1
[1]+ java -jar app.jar &
$ jobs
[1]+ Running java -jar app.jar &
# 再使用fg,会发现任务变成前台任务了
$ fg %1
# 直接使用&符号,直接就是后台任务并且Running状态
$ java -jar app.jar &
[1] 19620
$ jobs
[1]+ Running java -jar app.jar &
нет и отречься
Однако, если вы запустите процесс, используя описанный выше метод, когда вы выключите компьютер после работы, ssh-терминал потеряет соединение, и ваш java-процесс будет уничтожен.
Поскольку процессы, запущенные в оболочке, являются дочерними процессами процесса оболочки, когда ssh теряет соединение, процесс оболочки отправит сигнал SIGHUP своему дочернему процессу, который уничтожит дочерний процесс, запущенный в оболочке, включая фоновый процесс. , Не исключение.
Эту проблему можно решить с помощью команды nohup.Процесс, запущенный командой nohup, будет игнорировать сигнал SIGHUP, чтобы процесс мог продолжать свое существование следующим образом:
$ nohup java -jar app.jar &
Если вы еще не запускали процесс с помощью nohup, вы можете использоватьdisown
Команда заставляет процесс игнорировать сигнал SIGHUP следующим образом:
- использовать
Ctrl+z
Заставьте его работать в фоновом режиме, и процесс будет приостановлен. - использовать
jobs -l
Запросите идентификатор задания, только что переданный фоновой задаче, например 1, используйтеbg %1
заставить его работать. - использовать
disown -h %1
сделать эту фоновую задачу игнорируемойSIGHUP
Сигнал.
В дополнение к nohup вы также можете использовать программное обеспечение псевдотерминала, такое как tmux и screen, которое также может предотвратить уничтожение процесса при отключении терминала, как показано ниже:
# ubuntu安装tmux
$ sudo apt install tmux
# 新建一个伪终端会话,会话名为app
$ tmux new -s app
# 启动进程,注意现在已经在tmux伪终端里面了,这和平时操作没什么两样
# 如果要退出伪终端,先按Ctrl + b再按d,不要使用Ctrl+c
$ java -jar app.jar
# 列出所有伪终端会话
$ tmux ls
# 重新attach进入app这个会话,这样就可以看任务运行情况了
$ tmux attach -t app
В дополнение к безопасному запуску фонового процесса, tmux также может реализовывать расширенные функции, такие как многооконный режим и разделенный экран.Если вам интересно, вы можетеman tmux
Проверить.
убить и подать сигнал
Мы знаем, что kill может убить процесс, но, в принципе, kill не убивает процесс, kill просто посылает сигнал процессу, после того как процесс получает сигнал, он сам завершает работу.
пройти черезkill -l
Вы можете просмотреть сигналы, которые может отправить команда kill, следующим образом:
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
Спереди находится номер сигнала, за которым следует название сигнала, вы можете найти так называемыйkill -9
Фактически он отправляется в процессSIGKILL
сигнал, который также можно записать какkill -SIGKILL
.
Ниже приведены сценарии, в которых появляются общие сигналы:
Сигнал | Поведение по умолчанию | Сцены |
---|---|---|
SIGHUP | убить процесс | Терминал зависает, например, удаленное отключение ssh |
SIGINT | убить процесс | прерывание от клавиатуры,Ctrl+c должен сигнализировать об этом |
SIGQUIT | убить процесс | Выход с клавиатуры,Ctrl+\ отправить этот сигнал |
SIGKILL | убить процесс | убить программу,kill -9 отправить этот сигнал |
SIGPIPE | убить процесс | Операции записи в канал, который не читает пользователей, например сетевое соединение сокета, после того, как удаленный конец закрывает соединение, локальный конец продолжает писать |
SIGTERM | убить процесс | сигнал завершения программного обеспечения,kill Этот сигнал отправляется по умолчанию |
SIGCHLD | убить процесс | дочерний процесс остановлен или завершен |
SIGCONT | убить процесс | Если процесс останавливается, продолжайте процесс |
SIGTSTP | убить процесс | стоп-сигнал с терминала,Ctrl+z отправить этот сигнал |
Процесс, вызванный oom, исчезает
Помимо описанной выше ситуации, oom (переполнение памяти) также является частой причиной исчезновения процесса.В программе запрошено большое количество памяти, а нехватка памяти приводит к тому, что процесс умирает.Существуют две следующие ситуации:
- Процесс умирает из-за нехватки памяти jvm
Для такой программы, как java, программа использует более-Xmx
порог, jvm автоматически выйдет и останется в стандартном потоке выводаjava.lang.OutOfMemoryError
аномальный.
Поэтому при запуске java-процесса лучше всего использовать перенаправление, чтобы сохранить стандартный вывод и стандартную ошибку в файл журнала, а затем вы можете подтвердить, что oom является oom, следующими способами:
# 启动进程时,将标准输出与标准错误保存到日志文件中
$ nohup java -jar app.jar >stdout.log 2>stderr.log &
# 搜索是否存在OutOfMemoryError异常
$ grep -A5 'OutOfMemoryError' stdout.log stderr.log
stdout.log:java.lang.OutOfMemoryError: Java heap space
stdout.log- at java.base/java.lang.StringCoding.decodeUTF8_0(StringCoding.java:753) ~[na:na]
stdout.log- at java.base/java.lang.StringCoding.decodeUTF8(StringCoding.java:712) ~[na:na]
stdout.log- at java.base/java.lang.StringCoding.decode(StringCoding.java:318) ~[na:na]
stdout.log- at java.base/java.lang.String.<init>(String.java:592) ~[na:na]
stdout.log- at java.base/java.lang.String.<init>(String.java:614) ~[na:na]
- Механизм oom-killer приводит к тому, что процесс умирает
Студенты, незнакомые с Linux, как правило, игнорируют этот момент.Если системе Linux не хватает памяти, она будет использовать механизм oom-killer, чтобы найти процесс с большим объемом памяти и пожертвовать им.Как правило, процесс Java занимает большой объем памяти, поэтому им часто приходится жертвовать.
Когда oom-killer убивает процесс, он напечатает некоторую информацию в журнале dmesg, поэтому вы можете проверить, исчез ли процесс с помощью oom-killer, следующими способами:
$ dmesg -T | grep -A10 -i "kill"
[Fri Dec 17 22:35:47 2021] Memory cgroup out of memory: Killed process 3102186 (java) total-vm:10487368kB, anon-rss:287124kB, file-rss:0kB, shmem-rss:0kB, UID:0 pgtables:3764kB oom_score_adj:0
[Fri Dec 17 22:35:47 2021] oom_reaper: reaped process 3102186 (java), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
Примечание: dmesg эквивалентен журналу ядра, и ядро будет записывать в него некоторую ключевую информацию.Если вы не имеете ни малейшего понятия при устранении некоторых проблем, возьмите за привычку регулярно просматривать содержимое dmesg, возможно, вы сможете что-то найти!
Указатель статей этой серии
Дополнения к командам Linux — начало работы
Дополнения к командам Linux — обработка текста
Дополнения к командам Linux — наблюдение за программными ресурсами
Дополнения к командам Linux — наблюдение за аппаратными ресурсами
Дополнения к командам Linux — инструменты профилирования
Дополнения к командам Linux — инструмент динамического отслеживания
Сводки команд Linux — понимание нагрузки на систему
Что такое %nice в дополнениях к командам Linux -top
Дополнения к командам Linux — средство захвата сетевых пакетов
Прошлый контент
Дополнения к командам Linux — начало работы
Оказывается awk действительно артефакт
Навыки командной команды Linux (часть 1)
Навыки работы с текстовыми командами в Linux (часть 2)
Головоломка с кодировкой символов