configure java daemon with systemd

Рассмотрим следующий сценарий awk, duplicates.awk :

#!/usr/bin/awk -f
BEGIN {
    RS = "(\r\n|\n\r|\r|\n)"
    FS = "[\t\v\f ]*;[\t\v\f ]*"
    split("", count)
}

{
    count[$3]++
}

END {
    for (item in count) {
        if (count[item] > 1)
            printf "%s\n", item
    }
}

Не забудьте сделать его исполняемым, используя, например, chmod a + rx duplicates.awk . Вы можете передать входные данные команде по конвейеру или передать один или несколько входных файлов в качестве параметров командной строки (несколько файлов обрабатываются так, как если бы они были объединены в один файл).

Правило BEGIN устанавливает универсальные символы новой строки (то есть принимает все соглашения о новой строке от MS-DOS до старых Mac и Unix) и точки с запятой ; в качестве разделителя полей.Для иллюстрации я сделал так, чтобы разделитель полей также занимал все окружающие его пробелы, так что x; foo bar; y разбирается на три поля: x , foo bar и y .

Правило записи (средняя часть фрагмента) применяется к каждой записи (строке) во входных данных. Поскольку awk поддерживает ассоциативные массивы, мы просто используем третье поле, строку, как ключ к массиву count , и увеличиваем эту запись на единицу. (Увеличение несуществующей записи массива в awk дает 1, поэтому первое приращение дает 1, и код работает так, как и следовало ожидать.)

Правило END сканирует массив count , распечатывая записи, которые произошло как минимум дважды. Обратите внимание, что этот вывод находится в случайном порядке. (Есть способы отсортировать вывод по количеству вхождений или даже сохранить исходный порядок (первых вхождений) в файле, но OP не упомянул никаких требований относительно упорядочения, поэтому я не беспокоился; undefined порядок является самым простым для реализации.)

Если вы хотите напечатать, например, количество вхождений, за которыми следует строка (значение из третьего столбца), затем используйте вместо этого следующее правило END:

END {
    for (item in count)
        printf "%15d %s\n", count[item], item
}

Вывод форматируется так, что первые пятнадцать символов вывода зарезервированы для числа, а значение начинается с 17-го символа.

10
01.11.2016, 17:07
1 ответ

Вот некоторые незначительные изменения:

  1. Поскольку он прослушивает сетевой сокет, сделайте его зависимым от network.target .
  2. nohup не требуется, поскольку systemd демонизирует исполняемый файл за вас.
  3. Я думаю, что отдельный сценарий оболочки был бы излишним, поэтому просто добавьте его в служебный файл.
  4. Перенаправление ( и т. Д.) Не требуется, поскольку systemd устанавливает соответствующий стандартный контекст ввода-вывода. В самом деле, если вы уберете перенаправление из , systemd будет записывать все, что отправлено на стандартный вывод программой Java в своем журнале, без специального механизма ведения журнала.
  5. Асинхронный запуск из вызывающей оболочки ( & ) не требуется и не подходит.
  6. Для Type = forking требуется особый шаблон поведения, и если демон не будет следовать ему, все пойдет не так. Поэтому попробуйте ввести Type = simple (или Type = notify ).

Итак, служебный файл выглядит так:

[Unit]
Description=Some job
After=network.target

[Service]
WorkingDirectory=/home/user/tmp/testout
SyslogIdentifier=SocketTest
ExecStart=/bin/sh -c "exec java -jar /home/user/programming/tests/java/core/SocketTest/SocketTest.jar"
User=dlt
Type=simple

[Install]
WantedBy=multi-user.target

Примечания:

  1. Вы не можете просто использовать java в качестве имени запускаемой программы. systemd не выполняет поиск исполняемых файлов в PATH , и имя исполняемого файла, присвоенное ExecStart , должно быть абсолютным. Поэтому, если вам нужен поиск по пути, вы должны вызвать его через оболочку или / usr / bin / env . Здесь мы выбираем / bin / sh .
  2. Поскольку это Type = simple , оболочка должна exec Java, а не запускать ее как дочерний процесс.systemd управляет службой через основной процесс, и это должен быть Java, а не процесс родительской оболочки.
  3. Поскольку это не вызывает напрямую исполняемый файл Java, systemd поместит имя sh в свой журнал в качестве имени службы. См. Как избежать отметки / usr / bin / env в журналах systemd как исполняемый файл для получения дополнительной информации.

Насколько мне известно, нет никаких особых предостережений относительно запуска Java-приложений с Systemd.

17
27.01.2020, 20:01

Теги

Похожие вопросы