LINUX.ORG.RU

Написал юнит systemd для YaCy (Java), прошу адептов systemd подкорректировать и помочь с вопросами

 , , ,


0

1

Я создал юнит

# /usr/lib64/systemd/system/yacy.service
[Unit]
Description=YaCy

[Service]
Environment=CLASSPATH=lib/*
ExecStart=/etc/java-config-2/current-system-vm/bin/java -Xmx600m -Xms180m -server -Djava.net.preferIPv4Stack=true -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Dsolr.directoryFactsolr.MMapDirectoryFactory net.yacy.yacy
User=yacy
WorkingDirectory=/usr/share/yacy

OMG! Оно даже работает!

Вопрос №1. Почему создают юниты с Type=forked? Я смотрел юниты разных Java-приложений из разных дистрибутивов. Везде я видел создание скрипта-враппера из кучи лапши на bash/sh, и всё что делает systemd — запускает этот скрипт. Но зачем?

Вопрос №2. Нормально ли указывать в качестве пути к бинарнику /etc/java-config-2/current-system-vm/bin/java? Я понимаю, что это дистрибутиво-специфично. Может, есть более правильное решение?

Вопрос №3. Зачем в этих скриптах-врапперах делают лапшу в виде (скрипт из Arch)

CP=/usr/share/java/yacy.jar:$YACY_HOME/htroot
for name in /usr/share/java/yacy/*.jar; do
        CP=$CP:$name
done
CLASSPATH=$CP
что в итоге превращается в

-classpath .:htroot:lib/J7Zip-modified.jar:lib/activation.jar:lib/apache-mime4j-0.6.jar:lib/bcmail-jdk15-145.jar:lib/bcprov-jdk15-145.jar:lib/commons-codec-1.7.jar:lib/commons-compress-1.4.1.jar:lib/commons-fileupload-1.2.2.jar:lib/commons-io-2.1.jar:lib/commons-jxpath-1.3.jar:lib/commons-lang-2.6.jar:lib/commons-logging-1.1.3.jar:lib/fontbox-1.8.3.jar:lib/geronimo-stax-api_1.0_spec-1.0.1.jar:lib/guava-15.0.jar:lib/htmllexer.jar:lib/httpclient-4.3.2.jar:lib/httpcore-4.3.1.jar:lib/httpmime-4.3.2.jar:lib/icu4j-core.jar:lib/jakarta-oro-2.0.8.jar:lib/jaudiotagger-2.0.4-20111207.115108-15.jar:lib/jcifs-1.3.17.jar:lib/jcl-over-slf4j-1.7.2.jar:lib/jempbox-1.8.3.jar:lib/jetty-client-8.1.14.v20131031.jar:lib/jetty-continuation-8.1.14.v20131031.jar:lib/jetty-http-8.1.14.v20131031.jar:lib/jetty-io-8.1.14.v20131031.jar:lib/jetty-security-8.1.14.v20131031.jar:lib/jetty-server-8.1.14.v20131031.jar:lib/jetty-servlet-8.1.14.v20131031.jar:lib/jetty-servlets-8.1.14.v20131031.jar:lib/jetty-util-8.1.14.v20131031.jar:lib/jetty-webapp-8.1.14.v20131031.jar:lib/jetty-xml-8.1.14.v20131031.jar:lib/jsch-0.1.50.jar:lib/json-simple-1.1.1.jar:lib/jsoup-1.6.3.jar:lib/log4j-over-slf4j-1.7.2.jar:lib/lucene-analyzers-common-4.6.0.jar:lib/lucene-analyzers-phonetic-4.6.0.jar:lib/lucene-classification-4.6.0.jar:lib/lucene-codecs-4.6.0.jar:lib/lucene-core-4.6.0.jar:lib/lucene-facet-4.6.0.jar:lib/lucene-grouping-4.6.0.jar:lib/lucene-highlighter-4.6.0.jar:lib/lucene-join-4.6.0.jar:lib/lucene-memory-4.6.0.jar:lib/lucene-misc-4.6.0.jar:lib/lucene-queries-4.6.0.jar:lib/lucene-queryparser-4.6.0.jar:lib/lucene-spatial-4.6.0.jar:lib/lucene-suggest-4.6.0.jar:lib/metadata-extractor-2.6.2.jar:lib/noggit-0.5.jar:lib/pdfbox-1.8.3.jar:lib/poi-3.9-20121203.jar:lib/poi-scratchpad-3.9-20121203.jar:lib/servlet-api-3.0.jar:lib/slf4j-api-1.7.2.jar:lib/slf4j-jdk14-1.7.2.jar:lib/solr-core-4.6.0.jar:lib/solr-solrj-4.5.1.jar:lib/spatial4j-0.3.jar:lib/webcat-0.1-swf.jar:lib/wstx-asl-3.2.9.jar:lib/xercesImpl.jar:lib/xml-apis.jar:lib/yacycore.jar:lib/zookeeper-3.4.5.jar:

ЗАЧЕМ??? Если можно сделать просто и удобно вроде

CLASSPATH=lib/*

Так вот, зачем такие простыни, если Java умеет по маске принимать classpath?

Вопрос №4. Как бы корректно изменять значения в параметрах -Xmx600m -Xms180m (см. юнит вначале)? Может так?

-Xmx${XMX}m -Xms${XMS}m
И вышеуказанные XMX и XMS указывать в EnviromentFile?

Вопрос №5. Как перед запуском сервиса на лету проверять некоторые вещи и в зависимости от результата генерировать нужные параметры запуска? Надо сэмулировать такой скрипт:

HUGEPAGESTOTAL="$(cat /proc/meminfo | grep HugePages_Total | sed s/[^0-9]//g)"
if [ -n "$HUGEPAGESTOTAL" ] && [ $HUGEPAGESTOTAL -ne 0 ]
then 
        JAVA_ARGS="$JAVA_ARGS -XX:+UseLargePages"
fi

Вопрос №6. Как корректно останавливать? Я видел, что просто добавляют в конце -shutdown, т.е.

ExecStop=/etc/java-config-2/current-system-vm/bin/java -Xmx600m -Xms180m -server -Djava.net.preferIPv4Stack=true -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Dsolr.directoryFactsolr.MMapDirectoryFactory net.yacy.yacy -shutdown

Нужно ли такое в systemd? Или там достаточно штатного сигнала завершения? Или на -shutdown висит специальный хук, который в обычном режиме не исполняется?

NB: не использую ни генту, ни java. Всё нижесказанное — продукт common sense.

  • Type=forking нужен, когда запускаемый файл форкается. Зачем пишут врапперы на шелле — вопрос второй...
  • /usr/bin/java не подходит?
  • видимо, от незнания того, что classpath можно задавать маской (хотя использовать для этого цикл — всё равно говнокод)
  • вроде того, ${VAR} и EnvironmentFile=
  • только скриптом (с exec java в конце). Но разве JVM крашится, если ей сказать UseLargePages при отсутствии таковых в системе?
  • судя по man java, она и по SIGTERM'у нормально умеет завершаться. Полагаю, что можно оставить без ExecStop.
intelfx ★★★★★
()
Ответ на: комментарий от rictb

Видимо, ТС оттуда и приводит фрагменты кода.

intelfx ★★★★★
()
Ответ на: комментарий от rictb

Да, я видел. Как правильно сказали ниже, я именно оттуда приводил куски кода.

Мне не нравится подход с написанием враппера на bash и кучи костылей, поэтому я хочу написать юнит, который будет напрямую пускать java.

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от Atheist

Всё, что начало работать, когда-то перед этим не работало. Так и здесь. После написания нормального юнита я смогу сказать «а в генте просто работает».

Chaser_Andrey ★★★★★
() автор топика

на лету проверять некоторые вещи

Там, где начинается скриптовая логика, кончается systemd.

Даже если сделать ExecStartPre="/usr/bin/bash -c 'HUGEPAGESTOTAL=...'", то это значение не сохранится в вызове ExecStart (как в Makefile, каждый Exec запускается в отдельном окружении). Придётся городить скрипт.

mtk
()

Вопрос №5. Как перед запуском сервиса на лету проверять некоторые вещи и в зависимости от результата генерировать нужные параметры запуска? Надо сэмулировать такой скрипт:

Никак, на это systemd не расчитан. P.S. в upstart так как там простые баш скрипты это можно реализовать.

bhfq ★★★★★
()
Ответ на: комментарий от mtk

У меня есть идея, но хреновая.

Я правильно понимаю, что EnviromentFile будет считан до ExecStartPre?

Если нет, то можно сгенерировать EnviromentFile с помощью команды ExecStartPre.

Если да, то можно создать ещё один юнит (yacy.genconf), который должен запускаться один раз (oneshot), и генерировать EnviromentFile для юнита yacy. Ну и зависимости поставить. Плюс — конфиг генерируется один раз, и не надо писать очередной враппер. Минус — ещё один юнит.

// cast intelfx, bhfq

Chaser_Andrey ★★★★★
() автор топика
Последнее исправление: Chaser_Andrey (всего исправлений: 1)
Ответ на: комментарий от devl547

Кого? YaCy? Напишу новый ебилд, о новом релизе узнаю через RSS. Или в чём проблема? Разве должен меняться кардинально unit от релиза к релизу? Да и пофиксить юнит в релизе не проблема, имхо.

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от vurdalak

А в генте разве есть рабочий yacy?

Я доработал старый ебилд, утянутый с zugaina.

devl547 ★★★★★
()
Ответ на: комментарий от vurdalak

Ну я сейчас пилю yacy-1.68.20140209.9000.ebuild (весьма новый). Об этом чуть позже создам тему, так как тоже есть вопросы.

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от Chaser_Andrey

А, ну пили. Я максимум нашёл в зугаине 1.01.20111207.9000, который собрал ещё 2 года назад :)

vurdalak ★★★★★
()
Ответ на: комментарий от devl547

А с ним тоже проблем нет. Появляется новый ебилд в оверлее nektoo или zugaina.

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от devl547

С ним тоже проблемы нет, самообновление можно выключить. Я уже давно _поддерживаю_ ебилд для i2p, проблем не было (разве что с тем самым юнитом systemd, ибо лень).

vurdalak ★★★★★
()
Ответ на: комментарий от Chaser_Andrey

В доке написано, что считывается «shortly before the process is executed». Опытным путём это подтвердилось. Так что подход со вторым юнитом корректен, но КОСТЫЛЬ.

intelfx ★★★★★
()
Ответ на: комментарий от Chaser_Andrey

Предлагается 1) проверить, умрёт ли брат, если запустить java с UseLargePages на машине без их поддержки, и 2) если умрёт, то сделать bash-враппер, который в конце будет делать «exec java» и таким образом не создавать практически никакого оверхеда (заметного не десктопе).

intelfx ★★★★★
()
Ответ на: комментарий от intelfx

но КОСТЫЛЬ

Гм... а какая разница?

1. В обоих случаях просто ещё один файл (в первом случае юнит, в втором — враппер).

2. Во втором случае оверхеда в целом больше (если уже придираться к мелочам)

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от Chaser_Andrey

Ну ящитаю, что если уж костылить, то более гибким способом. Всё равно вторичный юнит будет запускать скрипт (хоть и однократно на старте системы, но всё же). И файл с параметрами надо будет где-нибудь хранить :3

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от vurdalak

Я пока не умею годно готовить ебилды, поэтому у меня пока свой репозиторий. Но следи за тегом «gentoo» или «yacy», я сегодня выложу черновик в General.

Chaser_Andrey ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.