我正在使用 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