3

我编写了一个应用程序,它使用Gearman将作业(客户端)提交给一个或多个工作人员,尤其是java-gearman-service 0.6.2。

现在我正在运行一个无限循环,每 10 秒检查一次是否需要向 Jobserver 提交新作业。这背后有一些逻辑。请注意,我只想提交它们,而不是得到结果或回调。

基本上我所做的是:

Gearman gearman = Gearman.createGearman();
GearmanClient client = gearman.createGearmanClient();
client.addServer(gearman.createGearmanServer("someip",somePort);
while(true) {
    // get the jobs to submit from the application logic
    client.submitBackgroundJob("functionname","dataBytes");
    // sleep for a few seconds.
}

这会产生越来越多的线程,直到消耗太多内存以致OutOfMemory抛出异常。

我试图实例化GearmanGearmanClient在循环中 - 并通过以下方式关闭它们:

client.shutdown();
gearman.shutdown();

在提交了所有作业之后,但这会导致:

28 [gearman-1] INFO gearman - [127.0.1.1:4730]:已连接

 634 [main] FATAL main - Exception!

java.lang.NullPointerException

在 org.gearman.impl.util.GearmanUtils.toString(未知来源)

在 org.gearman.impl.serverpool.AbstractConnectionController.onDisconnect(未知来源)

在 org.gearman.impl.server.remote.GearmanServerRemote$InnerGearmanConnectionHandler.onDisconnect(未知来源)

在 org.gearman.impl.core.GearmanConnectionManager$SocketHandlerImpl.onDisconnect(未知来源)

在 org.gearman.impl.reactor.SocketImpl.closeConnection(未知来源)

在 org.gearman.impl.reactor.SocketImpl.close(未知来源)

在 org.gearman.impl.core.GearmanConnectionManager$SocketHandlerImpl$Connection.close(未知来源)

在 org.gearman.impl.server.remote.GearmanServerRemote.shutdown(未知来源)

在 org.gearman.impl.GearmanImpl.shutdown(未知来源)

在 MyApplication.start(ClientManager.java:clientShutdownLine)

31 [gearman-1] INFO gearman - [127.0.1.1:4730]:断开连接

java.lang.IllegalStateException

在 org.gearman.impl.client.GearmanJobReturnImpl.eof(未知来源)

在 org.gearman.impl.client.ClientImpl.failTo(未知来源)

在 org.gearman.impl.client.ClientImpl.onClose(未知来源)

在 org.gearman.impl.client.ClientImpl.access $700(未知来源)

在 org.gearman.impl.client.ClientImpl$InnerConnectionController.onClose(未知来源)

在 org.gearman.impl.serverpool.AbstractConnectionController.closeServer(未知来源)

在 org.gearman.impl.serverpool.AbstractConnectionController.onDisconnect(未知来源)

在 org.gearman.impl.server.remote.GearmanServerRemote$InnerGearmanConnectionHandler.onDisconnect(未知来源)

在 org.gearman.impl.core.GearmanConnectionManager$SocketHandlerImpl.onAccept(未知来源)

在 org.gearman.impl.reactor.NioReactor$1.completed(未知来源)

在 org.gearman.impl.reactor.NioReactor$1.completed(未知来源)

在 sun.nio.ch.Invoker.invokeUnchecked(未知来源)

在 sun.nio.ch.Invoker$2.run(未知来源)

在 sun.nio.ch.AsynchronousChannelGroupImpl$1.run(未知来源)

在 java.util.concurrent.ThreadPoolExecutor.runWorker(未知来源)

我怎样才能避免 Gearman-Java-Service 一段时间后产生这么多线程?

4

1 回答 1

0

尝试更新到最新版本。我想你可能会看到这些问题:

另请注意,submitBackgroundJob是一个异步调用,并且在后台发生了一些排队。如果您提交作业的速度超过了客户端的速度,则会发生内存不足异常。鉴于您似乎在等待几秒钟,可能并非如此,但试试这个:

Gearman gearman = Gearman.createGearman();
GearmanClient client = gearman.createGearmanClient();
client.addServer(gearman.createGearmanServer("someip",somePort);
while(true) {
    // get the jobs to submit from the application logic
    GearmanJobReturn jobReturn = client.submitBackgroundJob("functionname","dataBytes");
    while(!jobReturn.isEOF()) {jobReturn.poll();}
}

GearmanJobReturn将在到达文件末尾之前轮询后台作业的作业句柄(或错误消息)。这也将允许在您提交下一个作业之前完全提交作业。

不要在提交之间关闭服务。这会减慢一切。任何已建立的连接都将关闭,您需要重新建立连接以提交下一个作业。

于 2012-08-09T15:08:55.457 回答