当前位置: 首页 > 知识库问答 >
问题:

Vertx WebClient使用的文件描述符太多

许毅
2023-03-14

我正在尝试在AWS Lambda中运行vertx WebClient。AWS Lambda最多有1024个文件描述符,并且不可调整。我很难找到到底是什么用完了我所有的文件描述符。我只使用vertx的WebClient,不运行任何verticle。这是我的共享WebClient:

var webClientOptions = new WebClientOptions()
                .setSsl(true)
                .setUseAlpn(true)
                .setReusePort(true)
                .setDefaultPort(443)
                .setHttp2MaxPoolSize(30)
                .setProtocolVersion(HttpVersion.HTTP_2)
                .setSslHandshakeTimeout(30)
                .setIdleTimeout(5)
                .setIdleTimeoutUnit(TimeUnit.SECONDS);

        return WebClient.create(vertx, webClientOptions);

此客户端在lambda调用之间重用,并且从不关闭。

我如何使用它:

var requestFutures = new ArrayList<CompletableFuture<Foo>>();
for (var request : requests) {
  CompletableFuture<Foo> future = new CompletableFuture();
  requestFutures.add(future);

  Buffer buffer = Buffer.buffer(request.getPayload());
  httpRequest.sendBuffer(buffer, (res) -> {
    future.complete(res);
  });
}

for (var requestFuture : requestFutures) {
  requestFuture.get();
}

我有45k-65k请求发送。我得到的是:

io.netty.channel.ChannelException: Failed to open a socket.
at io.netty.channel.socket.nio.NioSocketChannel.newSocket(NioSocketChannel.java:70)
at io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:87)
at io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:80)
at io.netty.bootstrap.AbstractBootstrap.initAndRegister(AbstractBootstrap.java:320)
at io.netty.bootstrap.Bootstrap.doResolveAndConnect(Bootstrap.java:163)
at io.netty.bootstrap.Bootstrap.connect(Bootstrap.java:145)
at io.vertx.core.net.impl.ChannelProvider.handleConnect(ChannelProvider.java:140)
at io.vertx.core.net.impl.ChannelProvider.connect(ChannelProvider.java:93)
at io.vertx.core.http.impl.HttpChannelConnector.doConnect(HttpChannelConnector.java:171)
at io.vertx.core.http.impl.HttpChannelConnector.connect(HttpChannelConnector.java:105)
at io.vertx.core.http.impl.pool.Pool$Holder.connect(Pool.java:125)
at io.vertx.core.http.impl.pool.Pool.checkPendingTasks(Pool.java:250)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:474)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:909)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.net.SocketException: Too many open files
at java.base/sun.nio.ch.Net.socket0(Native Method)
at java.base/sun.nio.ch.Net.socket(Unknown Source)
at java.base/sun.nio.ch.Net.socket(Unknown Source)
at java.base/sun.nio.ch.SocketChannelImpl.<init>(Unknown Source)
at java.base/sun.nio.ch.SelectorProviderImpl.openSocketChannel(Unknown Source)
at io.netty.channel.socket.nio.NioSocketChannel.newSocket(NioSocketChannel.java:68)
... 17 more

当我在本地运行这个程序并观察OSX活动监视器中打开的文件/套接字时,它会激增到数千个。基于我如何配置网络客户端,我不明白它为什么要这样做。

有人能从这些信息中看出我为什么要使用这么多的文件描述符吗?

共有1个答案

伯博
2023-03-14

setHttp2MaxPoolSize(30)很多,理论上只需要1,因为它是HTTP/2

 类似资料:
  • 文件描述符 Linux很重要的设计思想就是一切皆文件,网络是文件,键盘等外设也是文件,很神奇吧?于是所有资源都有了统一的接口,开发者可以像写文件那样通过网络传输数据,我们也可以通过/proc/的文件看到进程的资源使用情况。 内核给每个访问的文件分配了文件描述符(File Descriptor),它本质是一个非负整数,在打开或新建文件时返回,以后读写文件都要通过这个文件描述符了。 应用 我们想想操作

  • 文件描述符接口 函数 int  fd_new (void)   分配文件描述符   struct dfs_fd *  fd_get (int fd)   获取文件描述结构   void  fd_put (struct dfs_fd *fd)   放置文件描述符   int  fd_is_open (const char *pathname)   判断文件是否已被打开   int  select (

  • 问题内容: 有没有办法在原始文件描述符而不是FILE *上执行ftell()的操作(返回文件中的当前位置)?我认为应该有,因为您可以使用lseek()查找原始文件描述符。 我知道我可以使用fdopen()创建与文件描述符相对应的FILE *,但我宁愿不这样做。 问题答案: 只需使用:

  • 问题内容: 我需要从Java访问编号文件描述符-除0、1或2之外。 如何才能做到这一点?我查看了该类,但没有找到用给定的文件描述符号初始化它的任何方法。 作为一个具体示例,假设Java被另一种编程语言称为子进程。文件描述符3和4由另一种语言提供,用于输入和输出。 我在Java中需要的是和连接到这些文件描述符的对象,就像System.in,System.out和System.error都连接到文件描

  • 当使用了大量虚拟主机,而且每个主机又使用了不同的日志文件时,Apache可能会遭遇文件描述符(有时也称为文件句柄)耗尽的困境。Apache使用的文件描述符总数如下:每个不同的错误日志文件一个、每个其他日志文件指令一个、再加10-20个作为内部使用。Unix操作系统限制了每个进程可以使用的文件描述符数量。典型上限是64个,但可以进行扩充,直至到达一个很大的硬件限制为止(hard-limit)。 尽管

  • 处理文件描述符 尽管很不像,但是在大多操作系统中,标准输入输出流 stdin 和 stdout 虽然叫做「流」,但它们都有文件的接口。我们同样也会将它们实现成为文件。 但是不用担心,作为文件的许多功能,stdin 和 stdout 都不会支持。我们只需要为其实现最简单的读写接口。 进程打开的文件 操作系统需要为进程维护一个进程打开的文件清单。其中,一定存在的是 stdin stdout 和 std