【发布时间】:2023-08-31 21:38:01
【问题描述】:
我有一个使用 websocket 和 stomp 作为消息传递协议的应用程序。为了创建这个应用程序,我遵循了官方的 spring 文档。几天后,我收到一份报告说,运行应用程序的主机收到了来自 Prometheus 的名为 FdExhaustionClose 的警报,据我了解,这意味着某些连接没有正确关闭。 p>
应用程序在 kubernetes (linux) 中运行,我们使用 RabbitMQ 作为消息代理。
我该如何解决这个问题?在本地运行时,我意识到自应用程序启动以来的连接数总数实际上与未关闭的文件描述符的数量相匹配。
我检查了生产中的日志,并且代理状态正在打印:
WebSocketSession[42 current WS(42)-HttpStream(0)-HttpPoll(0), 52766 total, 0 closed abnormally
还有一个简单的lsof -p PID | wc -l 返回数字 52752
WebSocket配置
//...
@Configuration
public class WebSocketChatConfig extends DelegatingWebSocketMessageBrokerConfiguration {
@Autowired
private ApplicationProperties properties;
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/wss").setAllowedOrigins("*");
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
RabbitMqProperties rabbitProperties = properties.getRabbitmq();
ReactorNettyTcpClient<byte[]> client = new ReactorNettyTcpClient<>(tcpClient -> tcpClient
.host(rabbitProperties.getHost())
.port(rabbitProperties.getPort())
.option(ChannelOption.SO_TIMEOUT, 3600000)
.noProxy()
.secure(SslProvider.defaultClientProvider()), new StompReactorNettyCodec());
registry.setApplicationDestinationPrefixes("/app", "/topic", "/chat");
registry.enableStompBrokerRelay("/topic")
.setRelayHost(rabbitProperties.getHost())
.setRelayPort(rabbitProperties.getPort())
.setVirtualHost(rabbitProperties.getUsername())
.setSystemLogin(rabbitProperties.getUsername())
.setSystemPasscode(rabbitProperties.getPassword())
.setClientLogin(rabbitProperties.getUsername())
.setClientPasscode(rabbitProperties.getPassword()).setTcpClient(client);
}
}```
【问题讨论】:
标签: java spring spring-boot spring-websocket stomp