【问题标题】:java-gearman-client - Producing more and more threadsjava-gearman-client - 产生越来越多的线程
【发布时间】:2012-08-08 07:16:16
【问题描述】:

我编写了一个应用程序,它使用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(Unknown Source)

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

在 org.gearman.impl.core.GearmanConnectionManager$SocketHandlerImpl.onDisconnect(Unknown Source)

在 org.gearman.impl.reactor.SocketImpl.closeConnection(Unknown Source)

在 org.gearman.impl.reactor.SocketImpl.close(Unknown Source)

在 org.gearman.impl.core.GearmanConnectionManager$SocketHandlerImpl$Connection.close(Unknown Source)

在 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(Unknown Source)

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

在 org.gearman.impl.serverpool.AbstractConnectionController.onDisconnect(Unknown Source)

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

在 org.gearman.impl.core.GearmanConnectionManager$SocketHandlerImpl.onAccept(Unknown Source)

在 org.gearman.impl.reactor.NioReactor$1.completed(Unknown Source)

在 org.gearman.impl.reactor.NioReactor$1.completed(Unknown Source)

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

在 sun.nio.ch.Invoker$2.run(Unknown Source)

在 sun.nio.ch.AsynchronousChannelGroupImpl$1.run(Unknown Source)

在 java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

如何避免 Gearman-Java-Service 在一段时间后产生这么多线程?

【问题讨论】:

    标签: java multithreading gearman


    【解决方案1】:

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

    还要注意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 将在到达文件末尾之前轮询后台作业的作业句柄(或错误消息)。这也将允许在您提交下一个作业之前完全提交作业。

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

    【讨论】: