Perl, запущенный с Java, работает вечно - PullRequest
1 голос
/ 01 июня 2010

Я знаю, что это абсолютный выстрел в темноте, но мы совершенно сбиты с толку.

Скрипт perl (5.8.6), выполняемый Java (1.5), занимает больше часа. Тот же сценарий при запуске вручную из командной строки занимает 12 минут. Это на хосте Linux.

В обоих случаях ведение журнала одинаково, и сценарий запускается с одинаковыми параметрами в обоих случаях.

Сценарий выполняет некоторые сложные операции, такие как доступ к базе данных Oracle, некоторые scp и т. Д., Но, опять же, он выполняет одинаковые действия в обоих случаях.

Мы в тупике. Кто-нибудь сталкивался с подобной ситуацией? Если нет, и если вы столкнулись с той же ситуацией, как бы вы решили ее отладить?

Ответы [ 4 ]

4 голосов
/ 01 июня 2010

Подпроцессы, которые производят вывод на консоль, могут блокировать (и блокировать), если их потоки stdout / stderror не очищены. @gustafc, заданный код в конечном итоге блокирует подпроцесс, когда он пытается записать в stdout / stderror, и в потоке нет места (и поток не обслуживается Java).

Process p = startProcess();

final InputStream stdout = p.getInputStream();
final InputStream sterr = p.getErrorStream();

new Thread() {
 public void run() {
  int c;
  while ((c = sterr.read()) != -1) {
   System.out.print((char)c);
  }
 }
}.start();

new Thread() {
 public void run() {
  int c;
  while ((c = sterr.read()) != -1) {
   System.out.print((char)c);
  }
 }
}.start();
3 голосов
/ 01 июня 2010

Я полагаю, вы исключили возможность того, что обертка Java запускается одновременно, как что-то еще, что вызывает огромный конфликт из-за нехватки ресурсов? Хорошо.

Если у вас есть простой класс, подобный этому:

public class Exec {
    public static void main(String[] args) throws Throwable{
        class Transfer implements Runnable {
            private final InputStream in; 
            private final OutputStream out; 
            public Transfer(InputStream i, OutputStream o){
                in = i;
                out = o;
            }
            public void run(){
                try {
                    for (int i; (i = in.read()) != -1;) out.write(i);
                    out.close();
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } 
            }
        }
        Process proc = new ProcessBuilder(args).start();
        new Thread(new Transfer(System.in, proc.getOutputStream())).start();
        new Thread(new Transfer(proc.getInputStream(), System.out)).start();
        new Thread(new Transfer(proc.getErrorStream(), System.err)).start();
        System.exit(proc.waitFor());
    }
}

... а вы сравниваете time perl script.pl insert args here и time java Exec perl script.pl insert args here, что происходит? Если мир нормален, им требуется примерно одинаковое время (за исключением того, что второй требуется несколько секунд для запуска Java), и если это так, постепенно начинайте адаптировать класс Exec, чтобы он выглядел все больше и больше похожим на ваш среду развертывания, и посмотрите, когда она действительно займет много времени.

Если Exec выше действительно занимает больше времени, начните регистрироваться как сумасшедшие в скрипте Perl, чтобы увидеть, какие действия занимают больше времени. И, между прочим, войдите в Java-оболочку, чтобы увидеть, занимает ли запуск Perl действительно много времени или что-то в этом роде.

2 голосов
/ 01 июня 2010

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

Было бы неплохо использовать утилиты мониторинга, такие как top vmstat -5 iostat -5 и т. Д., Чтобы попытаться выяснить, соответствует ли медлительность некоторой патологии уровня ОС.

0 голосов
/ 07 июля 2010

Чтобы завершить этот поток, возможной причиной были неконтролируемые процессы, потребляющие слишком много ресурсов процессора. При запуске из командной строки скрипт имел обычный приоритет. При запуске из Java скрипт имел низкий приоритет и, следовательно, выполнялся вечно. Что сбило нас с толку, так это то, что код Java не просто выполнял сценарий, он выдавал те же команды через SSH, которые мы вводили в интерактивном режиме. Таким образом, мы не ожидали разницу в приоритете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...