9

警告 -- 原因はファイルの欠落ではありません -- すべてのスレッドが同じスクリプト ファイルを呼び出しています

Red Hat ボックスでローカル スクリプトを呼び出す 5 ~ 6 のスレッドを開始しています。

時々、次のエラーメッセージが表示されることに気付きました

couldn't read file "/home/leo/myScript.exp": no such file or directory

明らかに、すべてのプロセスがスクリプトを実行しているため、[1] OS がスクリプトを実行したり、読み取りのためにファイルにアクセスしたりできる同時プロセスに制限があるか、[2] Java が何らかの操作を実行しようとしていることに関連しているようです。準備ができていないストリーム (commons-exec がこれを処理してくれると想定していました)

これがコードです

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CommandLine commandline = CommandLine.parse("/home/leo/myScript.exp");
DefaultExecutor exec = new DefaultExecutor();
PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream);
exec.setStreamHandler(streamHandler);
try {
   exec.execute(commandline); <<< error happens here
}catch(IOException io) {
   throw new Exception("");
}

エラーが [1] の場合、Linux OS でこの制限を緩和する方法を知りたい

エラーが [2] の場合、commons-exec にリソースの準備が整うのを待つように指示する方法を知りたいです (最悪の場合、再試行を追加するだけですが、これはあまり役に立たないと思います)。エレガント)

エラーが別のものである場合、少なくとも原因を知っていれば、解決策を見つけるのに十分です。

更新 - 3 月 15 日

さて、これが問題です。

このスクリプトは、ライブラリを使用して Java クラスを呼び出す Expect スクリプトです。

私が気づいたことの 1 つは、データベース接続を作成する Java メソッドを呼び出すまで、スクリプトが正常に動作することです。

スレッド数が少ない(3~5)ので、データベースには問題ないと思います。代わりに、Javaコードが呼び出されている間、および/またはJavaコードがデータベース接続を作成している間に、何かがスクリプトの呼び出しをブロックしているように思えます。

私はまだ正確な例外を取得しようとしていますが、期待スクリプトは次のようになります (一種)

#!/opt/tclblend/bin/expect -f
set edfDir "/usr/local/nssa/bin/edf";
set env(LD_LIBRARY_PATH) "/opt/tclblend/lib/tcljava1.4.1"; # for tclBlend

## always use absolute paths
set env(TCL_CLASSPATH) "/home/leoks/EclipseIndigo/workspace2/xyzJavaWrapper/bin";
set env(CLASSPATH) {/home/leoks/EclipseIndigo/workspace2/xyzTomEE/lib/commons-logging-1.1.1.jar:/home/leoks/EclipseIndigo/workspace2/xyzConfiguration/lib/commons-configuration-1.9.jar:/home/leoks/EclipseIndigo/workspace2/xyzConfiguration/lib/commons-lang-2.4.jar:/home/leoks/EclipseIndigo/workspace2/xyz/3rdPartyJDBCJars/ojdbc6.jar:/home/leoks/EclipseIndigo/workspace2/xyzJavaWrapper/lib/commons-dbutils-1.5.jar:/home/leoks/EclipseIndigo/workspace2/xyzJavaWrapper/tcl/tcllib/xyzConfiguration.jar};

source $edfDir/lib/statics.tcl;
source $edfDir/lib/acclib.tcl; 

package require java

java::import com.abc.xyz.legacydriver.TCLDriverWrapper
java::import com.abc.xyz.legacydriver.LegacyDriverTaskInputData
java::import com.abc.xyz.legacydriver.LegacyDriverTaskEnum

set ticket  [ lindex $argv 0 ];
set inputData [ java::call com.abc.xyz.legacydriver.TCLDriverWrapper pullNextInputData $ticket ]

pullNextInputData は次のようになります

public static LegacyDriverTaskInputData pullNextInputData(String token) throws Exception {

    try {
        return pullNextInputDataImpl(token);
    } catch (Exception e) {
        e.printStackTrace();
        throw e;
    }
}

private static LegacyDriverTaskInputData pullNextInputDataImpl(String token) throws Exception {
    Connection conn = null;
    try{
        conn = new TCLDriverWrapper().getConnection();
        QueryRunner run = new QueryRunner();
        ResultSetHandler<LegacyDriverTaskInputData> rsh = new BeanHandler<LegacyDriverTaskInputData>(LegacyDriverTaskInputData.class);
        LegacyDriverTaskInputData inputData = run.query(conn,"select * from LegacyDriverTask where id = ?",rsh,Long.valueOf(token));
        return inputData;
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
        throw e;
    } catch (SQLException e) {
        e.printStackTrace();
        throw e;
    } finally {
        DbUtils.close(conn);
    }
}

getConnection() は、通常のドライバーのインスタンス化コードです (Apache dbutils を使用します)。

private Connection getConnectionImpl() throws Exception{    
    Class.forName("driver name");
    Properties props = new Properties();
    props.put("user", UtilConf.getProperty("javawrapper.user"));
    props.put("password", UtilConf.getProperty("javawrapper.password"));
    return DriverManager.getConnection(UtilConf.getProperty("javawrapper.jdbc"), props);
}

スタックトレースを取得したらすぐにここに配置します

更新 - 3 月 16 日

スタックトレースはあまり言いません:-(

2016-03-17 01:49:10,034 INFO   [QProcessor] Threads started (ok=0 nok=0 wait=0) org.apache.commons.exec.ExecuteException: Process exited with an error: 1 (Exit value: 1)
at org.apache.commons.exec.DefaultExecutor.executeInternal(DefaultExecutor.java:404)
at org.apache.commons.exec.DefaultExecutor.execute(DefaultExecutor.java:166)
at org.apache.commons.exec.DefaultExecutor.execute(DefaultExecutor.java:153)
at com.ericsson.xyz.tomee.q.QWorker.onMessageImpl(QWorker.java:776)
at com.ericsson.xyz.tomee.q.QWorker.onMessage(QWorker.java:303)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:182)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:164)
at org.apache.openejb.monitoring.StatsInterceptor.record(StatsInterceptor.java:180)
at org.apache.openejb.monitoring.StatsInterceptor.invoke(StatsInterceptor.java:99)
at sun.reflect.GeneratedMethodAccessor106.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:182)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:164)
at org.apache.openejb.core.interceptor.InterceptorStack.invoke(InterceptorStack.java:80)
at org.apache.openejb.core.stateless.StatelessContainer._invoke(StatelessContainer.java:212)
at org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:181)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod(EjbObjectProxyHandler.java:268)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler$1.call(EjbObjectProxyHandler.java:253)
at org.apache.openejb.async.AsynchronousPool$AsynchronousCall.call(AsynchronousPool.java:110)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
4

1 に答える 1

2

この件で助けてくれたすべての人に感謝したい。

この質問を削除したいのですが、懸賞金をかけているのでできません。(賞金の期限が切れたら、SO が許可してくれれば、そのときはそうします)

私はついに問題を起こさない方法を見つけました。それは、アプリケーションがスレッドにリソースを割り当てる方法に関連しているようです。そのため、質問で提供された情報を考えると、根本的な原因。

とにかく、ここで何が起こったのかを説明しようと思います。

ここに画像の説明を入力 (拡大するにはクリックしてください)

私が気づいた問題は、(5) (6) (7) でした。しかし、その原因は(3)にありました。

@Asynchronous メソッドを提供するスレッド プールの TomEE 構成のスレッド数が必要以上に少なかったため (私のアプリは既定値を使用していません)、一部のリソースが不足していたようです。

また、エラー メッセージにはまだ特定できていないバグがあるようで、この場合はエラー メッセージでさえ無効になる可能性があります。

質問には解決に必要なすべての変数が含まれていないため、ここで問題について全体的な説明を提供します。

これはクライアント コードであるため、コードを公開したり、すべての情報を提供したりすることはできません。パッケージ名も難読化する必要がありました。

繰り返しになりますが、ここで時間を割いて助けようとしてくれたすべての人に感謝したいと思います。また、必要なすべてのデータを提供できなかったことをお詫びします。

于 2016-03-17T13:03:15.677 に答える