LINUX.ORG.RU

Демон на java

 ,


1

1

Всем доброго дня!

Стоит задача по автоматизации рабочих процессов. Есть машина, которая должна подключаться к почтовому серверу, получать с него сообщение с архивом, распаковывать, анализировать вложение, и передавать нужные данные в БД (PostgreSQL). Systemd отсутствует.

Правильно ли это - писать демона на java? Как лучше демонизировать программу? Что можно почитать по этой теме?

Спасибо!

Что можно почитать по этой теме?

Если вы задаете такие вопросы, то наверное лучше Job

int13h ★★★★★
()

Правильно ли это - писать демона на java?

Правильно, почему нет?

Как лучше демонизировать программу?

Звучит угрожающе.

Что можно почитать по этой теме?

horstmann - core java

BattleCoder ★★★★★
()
Последнее исправление: BattleCoder (всего исправлений: 1)

Заверни в батник и запускай по cron'у.

Или можешь сделать всё внутри джавы, а само приложение запихнуть в какой-нибудь wildfly.

sargeman
()

Правильно ли это - писать демона на java?

Суд по задаче - вполне.

Как лучше демонизировать программу?

nohup java ...args... > ~/output.txt 2> ~/error.txt < /dev/null &

Что можно почитать по этой теме?

Учебник по яве ;)

Nagwal ★★★★
()

Зачем тебе висящий постоянно в памяти демон? Вызывай по крону обработчик и все. Или тебе критично чтоб прям когда почта пришла, тогда и произошла обработка? Одна минута разницы в твоем случае существенна?

gnunixon ★★★
()

я помню как писавши на скале упоролся заюзав через jni libc6 для setuid getuid, получал дескрипторы лог-файлов, форкался и сбрасывал привелегии

не делай так

но впринципе можно

anonymous
()

Java — это всегда свой сервер, который будет постоянно будет кушать ~100 Мб.

Советую наколбасить скрипт на питоне, и засунуть демона в крон. Запуска задачи от имени пользователя usr, скрипт лежит в /home/your_command.py:

echo '* * * * *  usr   python /home/your_command.py >> /dev/null 2>&1' >> /etc/cron.d/mail-fetch

...

Получение почты: http://stackoverflow.com/questions/18497397/how-to-get-csv-attachment-from-em...

...

Шаляй-валяй с архивами — нужно искать библиотеку под эти форматы.

...

Запись данных в БД — sqlalchemy, код примерно вот такой:

from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql import text
from sqlalchemy import create_engine

# Change to postgresql
dbUrl = 'mysql+mysqldb://root:@localhost/my_db';

engine = create_engine(dbUrl)
Session = sessionmaker(bind=engine)
session = Session()
connection = session.connection()


cmd = 'INSERT INTO my_table (id, name) values(:a, :x);'
connection.execute(text(cmd), a=1, x='me')
session.commit()
anonymous
()
Ответ на: комментарий от gnunixon

Спасибо. Нет, не критично. Я с такими задачами не сталкивался, потому и спрашиваю. Буду смотреть в сторону крона.

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

Спасибо, за конкретику! Java используется потому что, весь проект на ней. 100мб - думаю, это умеренная плата за единообразие кода.

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

Библиотеки ставить через pip

pip install SQLAlchemy

Соответственно, для драйвера постгресса/других библиотеки в гугле надо наибть

"имя библиотеки" pip
, и будет тебе счастье.

anonymous
()
Ответ на: комментарий от NikolayM

Гм. Если весь проект на джаве — тогда можно питоном и не заморачиваться, видимо, про javax.mail, Spring JDBCTemplate и кварц все и так в курсе.

Значит, вопрос в том, чтобы прога запускалась вместе с сервером при рестарте.

Если это убунта с неубитым upstart-ом, то все просто — кладешь в /etc/init вот такой конфиг из одной строчки

run.sh

run.sh - там прописано java -jar my_program..., в общем, обычный запускайчик.

Можно добавлять runlevel-ы и прочие конфиги, но самое простое - задать команду, и все дела, фоновый процесс готов, логи где-то в /var/log/upstart будут.

...

Если systemd все-таки есть - лучше его подключить. Стандартную лапшу на шелл-скриптах (SysVinit и прочий трэш) не советую.

...

Если нет ни upstart, ни systemd, то можно поставить supervisord, и скормить ему вот такой конфиг: http://serverfault.com/questions/425132/controlling-tomcat-with-supervisor

. Само собой, вместо $TOMCAT_HOME/bin/catalina.sh stop нужно прописать нужную прогу.

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

Значит, вопрос в том, чтобы прога запускалась вместе с сервером при рестарте.

Именно! Бегло взглянул на supervisord, я так понимаю, это то, что нужно - свою «обертку» писать очень не хочется. Спасибо большое! :)

NikolayM
() автор топика

Для себя накостылял скрипт. Может поможет.

#!/bin/bash

PID_FILE='app.pid'
LOG_FILE='app.log'

start_application() {
  java -jar your_app.jar &> $LOG_FILE &
  echo $! > $PID_FILE
}

kill_application() {
  kill -9 $(cat $PID_FILE)
}

case "$1" in
  start)
    echo "Starting app..."
    start_application
  ;;
  restart)
    echo "Restarting app..."
    kill_application
    start_application
  ;;
  stop)
    echo "Stop app..."
    kill_application
  ;;
esac
spoilt ★★★
()

Стоит задача по автоматизации рабочих процессов. Есть машина, которая должна подключаться к почтовому серверу, получать с него сообщение с архивом, распаковывать, анализировать вложение, и передавать нужные данные в БД (PostgreSQL). Systemd отсутствует.

Правильно ли это - писать демона на java?

Правильно. Java тут хорошо подойдёт, впрочем как любой другой язык высокого уровня.

Как лучше демонизировать программу?

Какую задачу пытаетесь решить «демонизацией»? Просто запускайте программу через java -jar xxx.jar и всё. Чтобы было удобно управлять — напишите systemd unit.

Legioner ★★★★★
()

Если у вас часть проекта это делает, то очень даже неплохо выделить отдельный процесс, сделать его демоном и пускай он занимается парсингом архивов почтовых, в то время как основной тред программы выполняет другую работу. При завершении основного треда и демон умрет. Вполне хорошее решение, мне кажется. Если же у вас это отдельная задача, то лучше писать на питоне скрипт и кидать его в крон. Даже при том, что у вас проект есть на jvm, все равно жрать памяти будет меньше в разы.

aarexer
()
Ответ на: комментарий от NikolayM

не слушай эти зануд. как обычно начинают про память. да и откуда сразу такие конкретные цифры? аха))))

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

Цифры не конкретные, а порядка 100 Мб.

Просто пустое приложение, где загруженные кварц, jdbcTemplate и javax.mail, займет ~50 Мб.

Если запускать просто java -jar, безо всяких опций, то такая прога займет ~200 Мб.

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

public class Main {

        public static void main(String[] args) throws Exception {
            DriverManagerDataSource dataSource = new DriverManagerDataSource();
            dataSource.setDriverClassName("com.mysql.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql://localhost:3306/schema");
            dataSource.setUsername("root");
            dataSource.setPassword("root");
            

            JdbcTemplate template = new JdbcTemplate(dataSource);


            for (int i=0; i< 1000; i++) {
                int rowCount = template.queryForObject("select count(*) from t", Integer.class);
                System.out.println(rowCount);
            }

            Thread.sleep(20000);
        }
}

Понятно дело, мусор, кэши, но сотню-другую памяти вынь да положь.

anonymous
()
Ответ на: комментарий от anonymous
# x server"

description "x server"

start on filesystem or runlevel [2345]
stop on runlevel [!2345]

respawn
respawn limit 10 30
umask 022

console log

setuid xxx

script
  [ ! -s /etc/default/x.options ] && exit 1
  . /etc/default/x.options

exec java $JAVA_OPTS -classpath '/opt/cb/libs/x/*' ru.x.Main $COMMAND_OPTS

end script

так лучше в upstart.

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

Еще бы JBoss для такой задачи заюзал... Подключаешь sql2o и javax.mail стартуешь и занимает это 30Мб, щас только проверил, даже никакие -Xmx не вводил, стартанул тупо из Eclipse и посмотрел System Monitor в Ubuntu.

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

А на java это все написал щас за 10 минут и поместилось в 30Мб оперативки, если учитывать, что у меня еще перформанс будет в десятки раз быстрее твоего ужа и нормальные треды, то не такая большая плата.

На чем еще померимся пиписьками?

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

Запросы-то сделай. Просто запустить никому неинтересно.

import org.sql2o.Connection;
import org.sql2o.Sql2o;

import java.util.List;

public class MainSql2o {
    public static void main(String[] args) throws Exception {

        String DB_URL = "jdbc:mysql://localhost:3306/schema";
        String USER = "root";
        String PASS = "root";
        Sql2o sql2o = new Sql2o(DB_URL, USER, PASS);

        String sql = "select count(*) from t";

        try(Connection con = sql2o.open()) {
            for (int i = 0; i < 1000; i++) {
            
                List<Integer> tasks = con.createQuery(sql)
                        .executeAndFetch(Integer.class);

                System.out.println(tasks.get(0));
            }
        }

        Thread.sleep(1000 * 30);
    }
}

60 МБ. Добавь mail, кварц и день работы — соточка и выйдет.

Да, если в этом коде connection создается внутри цикла, то получишь 150-200 МБ.

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

for (int i = 0; i < 1000; i++)

Специально косарь подобрал, чтобы на соточку вышло? )

Запросы-то сделай. Просто запустить никому неинтересно.

Сделал один запрос в postgres и один запрос на pop.gmail.com через javax.mail, вышло 31Мб на java8+ubuntu15.04(64-bit).

кварц

Вот обязательно нужно что-нибудь жирное воткнуть, чем тебя java.util.Timer не устраивает для данной задачи?

и день работы

Добавь опции -Xmx32Mb -XX:+UseG1GC оно и будет крутиться вокруг этого значения - хоть день, хоть год.

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

Только вся ломовая силища Java именно в толстых спрингах и кварцах. Играем без них — все равно: шаг влево, библиотека вправо, прыжок на месте без хэ-мэ-хэ, и ресурсов хочется все больше и больше.

А потом добавить функций, потом прилепить кусок основного проекта, в общем — не прячьте ваши памяти по банкам и dimm-ам.

Но это хорошо, что у тебя вышло в 30 метров уложиться, спасибо. Веры в яву добавилось.

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

Только вся ломовая силища Java именно в толстых спрингах и кварцах.

Я также раньше считал, обкидывался жирнотой типа Hibernate и Tomcat. Но в итоге пришел к выводу, что на java можно построить альтернативную платформу, которая не будет жрать гигабайт памяти на одном разогретом веб-приложении. И если все сложится хорошо, то может через год-два выложу первые наброски этой платформы в open-source.

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

Такая альтернативная платформа называется Golang.

Очень похож на яву исторически.

Многозадачность — кооперативная (как в яве первых версий), многотредность-синхронизации встроены прямо в язык, прочие средства упрощены, как только можно (в яве генериков почти десять лет не было), дикая кроссплатформенность, режим работы server-side — не запустился-умер, как у скриптовых языков, а работаем-все-время-сами-себе-сервера.

И ест golang реально мало.

Но лекговесный JVM-стек был бы очень классной затеей, особенно для задач, как у автора треда.

Удачи в реализации, товарищ!

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