java.net.BindException:地址不可用

java.net.BindException:地址不可用

我正在使用 Gatling 对使用 Spring webflux 和 mongo 数据库构建的 Spring 应用程序进行负载测试。我的 API 只接受一个字符串参数并对 mongo 反应式存储库执行 get 调用。我的应用程序部署在 Google Cloud GKE 和 GCE(mongo DB)中。

我正在使用图像将 gatling 作为 docker 容器运行https://github.com/denvazh/gatling. Gatling 测试使用公共 IP 通过互联网访问 API 端点。

测试在负载达到 28000 个并发用户之前运行良好,当我一次注入 30K 个用户时,我收到“java.net.BindException:地址不可用”。有人能就这个问题给出一些想法吗?

我检查了主机和 docker 容器上的 FD 限制,对我来说没问题。我在最后粘贴了 ulimit 输出。我在 gatling 脚本 stdout 上得到了以下异常。

请求:getEligibilityMVCSimulation:KO incAbstractChannel$AnnotatedSocketException:地址不可用:/some_ip:80 会话:会话(getEligibilityMVCSimulation,30975,1556538559546,Map(gatling.http.ssl.sslContexts -> SslContexts(io.netty.handler.ssl.OpenSslClientContext@3ff8fa07,None),gatling.http.cache.dns -> io.gatling.http.cache.DnsCacheSupport$$anon$1@5273a181,gatling.http.cache.baseUrl ->http://localhost:8182/eligibility-service/v1/),0,KO,List(),io.gatling.core.protocol.ProtocolComponentsRegistry$$Lambda$435/194107588@4249260d)

HTTP 请求:GEThttp://some_ip/eligibility-service/v1/8672 标头=接受:application/json,text/javascript,/;q=0.01 接受字符集:ISO-8859-1,utf-8;q=0.7,*;q=0.7 来源:http://some_ip 主机:some_ip

HTTP response:

11:49:30.614 [WARN ] i.g.h.e.GatlingHttpListener - Request 'getEligibilityMVCSimulation' failed for user 30983
java.net.BindException: Address not available
        ... 34 common frames omitted
Wrapped by: io.netty.channel.AbstractChannel$AnnotatedSocketException: Address not available: /some_ip
        at sun.nio.ch.Net.connect0(Native Method)
        at sun.nio.ch.Net.connect(Net.java:454)
        at sun.nio.ch.Net.connect(Net.java:446)
        at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:648)
        at io.netty.util.internal.SocketUtils$3.run(SocketUtils.java:83)
        at io.netty.util.internal.SocketUtils$3.run(SocketUtils.java:80)
        at java.security.AccessController.doPrivileged(Native Method)
        at io.netty.util.internal.SocketUtils.connect(SocketUtils.java:80)
        at io.netty.channel.socket.nio.NioSocketChannel.doConnect(NioSocketChannel.java:312)
        at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.connect(AbstractNioChannel.java:254)
        at io.netty.channel.DefaultChannelPipeline$HeadContext.connect(DefaultChannelPipeline.java:1366)
        at io.netty.channel.AbstractChannelHandlerContext.invokeConnect(AbstractChannelHandlerContext.java:545)
        at io.netty.channel.AbstractChannelHandlerContext.connect(AbstractChannelHandlerContext.java:530)
        at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.connect(CombinedChannelDuplexHandler.java:497)
        at io.netty.channel.ChannelOutboundHandlerAdapter.connect(ChannelOutboundHandlerAdapter.java:47)
        at io.netty.channel.CombinedChannelDuplexHandler.connect(CombinedChannelDuplexHandler.java:298)
        at io.netty.channel.AbstractChannelHandlerContext.invokeConnect(AbstractChannelHandlerContext.java:545)
        at io.netty.channel.AbstractChannelHandlerContext.connect(AbstractChannelHandlerContext.java:530)
        at io.netty.channel.ChannelDuplexHandler.connect(ChannelDuplexHandler.java:50)
        at io.netty.channel.AbstractChannelHandlerContext.invokeConnect(AbstractChannelHandlerContext.java:545)
        at io.netty.channel.AbstractChannelHandlerContext.connect(AbstractChannelHandlerContext.java:530)
        at io.netty.channel.ChannelDuplexHandler.connect(ChannelDuplexHandler.java:50)
        at io.netty.channel.AbstractChannelHandlerContext.invokeConnect(AbstractChannelHandlerContext.java:545)
        at io.netty.channel.AbstractChannelHandlerContext.connect(AbstractChannelHandlerContext.java:530)
        at io.netty.channel.AbstractChannelHandlerContext.connect(AbstractChannelHandlerContext.java:512)
        at io.netty.channel.DefaultChannelPipeline.connect(DefaultChannelPipeline.java:1024)
        at io.netty.channel.AbstractChannel.connect(AbstractChannel.java:259)
        at io.netty.bootstrap.Bootstrap$3.run(Bootstrap.java:252)
        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:462)
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.lang.Thread.run(Thread.java:748)
11:49:30.614 [WARN ] i.g.h.e.r.DefaultStatsProcessor - Request 'getEligibilityMVCSimulation' failed for user 30983: i.n.c.AbstractChannel$AnnotatedSocketException: Address not available: /some_ip:80

我正在使用 Debian 9 stretch 处理 GCE VM。最初 ulimit -n 返回 1024,在我按照https://gatling.io/docs/current/general/operations/ulimit -a 返回为 65535。但我遇到了同样的异常。

ulimit -a gives below result,

joy123456@gatling-tests-vm-2:~$ ulimit -a


core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 60087

max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024

pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 60087

virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

我检查了 docker 容器上的 ulimit,结果如下,

joy123456@gatling-tests-vm-2:~$ 
sudo docker run -it --entrypoint sh denvazh/gatling


/opt/gatling # ulimit -a


-f: file size (blocks)             unlimited
-t: cpu time (seconds)             unlimited
-d: data seg size (kb)             unlimited
-s: stack size (kb)                8192
-c: core file size (blocks)        unlimited
-m: resident set size (kb)         unlimited
-l: locked memory (kb)             64
-p: processes                      unlimited
-n: file descriptors               1048576
-v: address space (kb)             unlimited
-w: locks                          unlimited
-e: scheduling priority            0
-r: real-time priority             0

有人可以就这个问题提供一些想法吗?

谢谢

答案1

问题与我运行 gatling 的 VM 有关。我必须启用一些 TCP 属性,例如端口重用和回收。它允许我发送 500K 个并发请求。

答案2

尝试 gatlingshareConnections 例如

val httpConf = http
    .baseURL("http://IP:8080")
    .acceptHeader("text/html,application/xhtml+xml")
    .acceptLanguageHeader("en-US,en;q=0.5")
    .acceptEncodingHeader("gzip, deflate")
    .shareConnections

相关内容