Concurrent connections - Server Sent Events with Spring Cloud Gateway

Viewed 40

A reactive Spring Boot application is used to generate Server Sent Events for each subscribed client, e.g:

@GetMapping(path = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> sse(@RequestParam String key) {
  return Flux.interval(Duration.ofSeconds(2))
      .map((i) -> key + " Fixed delay task - " + System.currentTimeMillis() / 1000);
}

When I run it locally, up to 10K concurrent EventSource connections can be established. With more connections the following exception is thrown:

2022-09-07 12:59:02.123  WARN 90517 --- [ctor-http-nio-1] io.netty.channel.DefaultChannelPipeline  : An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.

java.io.IOException: Too many open files
    at java.base/sun.nio.ch.Net.accept(Native Method) ~[na:na]
    at java.base/sun.nio.ch.ServerSocketChannelImpl.implAccept(ServerSocketChannelImpl.java:425) ~[na:na]

Another problem occurs when Spring Cloud Gateway is in front of the service. The connection limit drops down to 2K connections. When exceeded, the service throws:

2022-09-07 13:09:37.590  WARN 90707 --- [ctor-http-nio-9] reactor.netty.channel.FluxReceive        : [559c58ed-1, L:/127.0.0.1:9999 - R:/127.0.0.1:54567] An exception has been observed post termination, use DEBUG level to see the full stack: java.net.SocketException: Connection reset

And the gateway throws:

2022-09-07 12:59:55.696 ERROR 90264 --- [ctor-http-nio-2] a.w.r.e.AbstractErrorWebExceptionHandler : [7772ec3b-4438]  500 Server Error for HTTP GET "/sse?key=2682"

java.net.SocketException: Connection reset
    at java.base/sun.nio.ch.SocketChannelImpl.throwConnectionReset(SocketChannelImpl.java:394) ~[na:na]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    *__checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
    *__checkpoint ⇢ HTTP GET "/sse?key=2682" [ExceptionHandlingWebHandler]
Original Stack Trace:
        at java.base/sun.nio.ch.SocketChannelImpl.throwConnectionReset(SocketChannelImpl.java:394) ~[na:na]
        at java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:426) ~[na:na]
        at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:258) ~[netty-buffer-4.1.79.Final.jar:4.1.79.Final]

The question is, why Spring Cloud Gateway has such an impact on the number of concurrent connections and how to reduce it? Also, is it possible to increase the number of connections to the service?

The source code of the service app, the gateway and a client JS app, used for receiving SSEs through multiple connections, is available on the git repo.

0 Answers
Related