Vert.x OutOfMemoryError工作线程队列

时间:2018-10-25 11:01:57

标签: java vert.x

我正在使用Vert.x库打开WebSockets并消耗掉它们的消息。消息处理可能会阻塞,因此我会将这些消息传递给工作线程。我以为它们有一个预定义大小的有界队列,但它只是创建一个LinkedList,如在vertx核心库中的TaskQueue.java中所见:

private final LinkedList<Task> tasks = new LinkedList<>();

结果是,当我的进程成为缓慢的使用者时,没有给源头施加压力,它耗尽了内存-分析堆转储证实了这一点。我正在考虑根本不使用工作线程,尽管对此感到有些惊讶-如果单个套接字发送的数据过多,我们可能想单独施加压力,阻塞事件循环将对其他线程造成不利影响套接字也-也许我丢失了一些东西/没有低估如何正确使用库?

添加:代码段 好的,我有一个MarshallingStage.java类,已在webSocket上注册为textMessageHandler:

MarshallingStage marshallingStage = new MarshallingStage(ctx);
webSocket.textMessageHandler(marshallingStage);

因此marshallingStage实现了Handler<String>,它将解组json并将其传递给工作线程。

@Override
public void handle(String text) {
    Message message;
    try {
        message = mUnmarshaller.unmarshall(text);
    }
    catch (MarshallingException e) {
        mCtx.disconnect("failed to unmarshall "+ text, e);
        return;
    }
    if (message != null) {
        handleInbound(new MessageEvent(message), mCtx);
    }
    else {
        log.error("{} unmarshalled null message", mCtx.getConnectionId());
    }
}

@Override
public void handleInbound(PipelineEvent event, ProviderContext ctx) {
    Vertx.currentContext().executeBlocking(
            future -> process(event, ctx),
            asyncResult -> {}
    );
}

鉴于工作线程具有无限制的任务列表,如果事件循环线程消耗tcp缓冲区中的消息的速度快于工作线程消耗该列表中的任务的速度,则该列表将一直增长,直到进程用尽内存。我真的不知道这怎么可能。

1 个答案:

答案 0 :(得分:0)

您写错了:

@Override
public void handleInbound(PipelineEvent event, ProviderContext ctx) {
    Vertx.currentContext().executeBlocking(
            future -> process(event, ctx),
            asyncResult -> {}
    );
}

处理完成后,您需要实际呼叫future.handle(Future.succeededFuture())

@Override
public void handleInbound(PipelineEvent event, ProviderContext ctx) {
    Vertx.currentContext().executeBlocking(
            future -> { process(event, ctx); future.handle(Future.succeededFuture()); },
            asyncResult -> {}
    );
}

否则,您将不得不等待释放工作线程。