You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Cloud API Gateway为何30秒后意外关闭WebSocket客户端TCP连接?

问题:Spring Cloud API Gateway代理WebSocket连接30秒后自动关闭

我开发了一套Spring Cloud API Gateway,后端部署了基于WebSocket的通知服务。直接连接通知服务时,WebSocket连接可以保持活跃;但通过API Gateway转发连接时,连接会在30秒后被自动关闭。

API Gateway的YAML配置

spring:
  main:
    allow-bean-definition-overriding: true
    web-application-type: reactive
  security:
    oauth2:
      client:
        registration:
          login-client:
            provider: uaa
            client-id: ${CLIENT_ID}
            client-secret: "*******"
            authorization-grant-type: authorization_code
            redirect-uri: "${BACKEND_ROOT_ADDRESS}/login/oauth2/code/{registrationId}"
        provider:
          uaa:
            authorization-uri: ${AUTH_SERVER_DOMAIN}/cas/oauth2.0/authorize
            token-uri: ${AUTH_SERVICE_INTERNAL_ADDRESS}/cas/oauth2.0/accessToken
            user-info-uri: ${AUTH_SERVICE_INTERNAL_ADDRESS}/cas/oauth2.0/profile
            user-name-attribute: id
            user-info-authentication-method: form
  cloud:
    gateway:
      globalcors:
        add-to-simple-url-handler-mapping: true
      default-filters:
        - TokenRelay=
        - RequestHashing=SHA-256
      routes:
        - id: notification
          uri: lb://NOTIFICATION
          predicates:
            - Path=/notification/**
          filters:
            - RewritePath=/notification(?<segment>/?.*), $\{segment}
          metadata:
            - response-timeout: 300000000
            - connect-timeout: 300000000
eureka:
  client:
    serviceUrl:
      defaultZone: http://discovery-service/eureka

直接连接通知服务的示例URL

ws://my-company/notification/openConnection?the_client_id=42

相关日志信息

通知服务端日志(确认连接因TCP结束包关闭)

[p-nio-80-exec-2] o.a.t.websocket.server.WsFrameServer     : wsFrameServer.onDataAvailable
[p-nio-80-exec-2] o.a.tomcat.util.net.SocketWrapperBase    : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@67f46c3f:org.apache.tomcat.util.net.NioChannel@2a4e5a44:java.nio.channels.SocketChannel[connected local=/172.28.0.11:80 remote=/172.28.0.12:56006]], Read from buffer: [0]
[p-nio-80-exec-2] org.apache.tomcat.util.net.NioEndpoint   : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@67f46c3f:org.apache.tomcat.util.net.NioChannel@2a4e5a44:java.nio.channels.SocketChannel[connected local=/172.28.0.11:80 remote=/172.28.0.12:56006]], Read direct from socket: [6]
[p-nio-80-exec-2] o.a.t.websocket.server.WsFrameServer     : Read [6] bytes into input buffer ready for processing
[p-nio-80-exec-2] o.a.t.websocket.server.WsFrameServer     : WebSocket frame received. fin [true], rsv [0], OpCode [8], payload length [0]
[p-nio-80-exec-2] s.w.s.h.LoggingWebSocketHandlerDecorator : StandardWebSocketSession[id=0df41ae3-ffc2-4d90-723c-88dacbfe11a3, uri=ws://da3a67eb76df/openConnection?party=42] closed with CloseStatus[code=1000, reason=null]
after close: 0df41ae3-ffc2-4d90-723c-88dacbfe11a3
[p-nio-80-exec-2] o.apache.tomcat.util.threads.LimitLatch  : Counting down[http-nio-80-exec-2] latch=1
[p-nio-80-exec-2] org.apache.tomcat.util.net.NioEndpoint   : Calling [org.apache.tomcat.util.net.NioEndpoint@11fe2371].closeSocket([org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@67f46c3f:org.apache.tomcat.util.net.NioChannel@2a4e5a44:java.nio.channels.SocketChannel[connected local=/172.28.0.11:80 remote=/172.28.0.12:56006]])

API Gateway端关闭连接日志

[or-http-epoll-7] r.n.http.client.HttpClientOperations     : [c66f9ad0-1, L:/172.28.0.12:58846 - R:1bc0b9f7e00d/172.28.0.11:80] Cancelling Websocket inbound. Closing Websocket
[or-http-epoll-7] r.n.resources.PooledConnectionProvider   : [c66f9ad0-1, L:/172.28.0.12:58846 ! R:1bc0b9f7e00d/172.28.0.11:80] Channel closed, now: 0 active connections, 0 inactive connections and 0 pending acquire requests.
[or-http-epoll-7] reactor.netty.ReactorNetty               : [c66f9ad0-1, L:/172.28.0.12:58846 ! R:1bc0b9f7e00d/172.28.0.11:80] Non Removed handler: reactor.left.httpAggregator, context: null, pipeline: DefaultChannelPipeline{(ws-decoder = io.netty.handler.codec.http.websocketx.WebSocket13FrameDecoder), (ws-encoder = io.netty.handler.codec.http.websocketx.WebSocket13FrameEncoder), (reactor.left.wsFrameAggregator = io.netty.handler.codec.http.websocketx.WebSocketFrameAggregator), (reactor.right.reactiveBridge = reactor.netty.channel.ChannelOperationsHandler)}
[or-http-epoll-7] r.n.http.server.HttpServerOperations     : [b51c2362-1, L:/172.28.0.12:80 ! R:/172.28.0.1:33582] Cancelling Websocket inbound. Closing Websocket
[or-http-epoll-7] r.n.r.DefaultPooledConnectionProvider    : [c66f9ad0, L:/172.28.0.12:58846 ! R:1bc0b9f7e00d/172.28.0.11:80] onStateChange(ws{uri=/openConnection?party=42, connection=PooledConnection{channel=[id: 0xc66f9ad0, L:/172.28.0.12:58846 ! R:1bc0b9f7e00d/172.28.0.11:80]}}, [response_completed])
[or-http-epoll-7] r.n.r.DefaultPooledConnectionProvider    : [c66f9ad0, L:/172.28.0.12:58846 ! R:1bc0b9f7e00d/172.28.0.11:80] onStateChange(ws{uri=/openConnection?party=42, connection=PooledConnection{channel=[id: 0xc66f9ad0, L:/172.28.0.12:58846 ! R:1bc0b9f7e00d/172.28.0.11:80]}}, [disconnecting])

内容的提问来源于stack exchange,提问作者sajad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 12:21:03