websocket - 在 JETTY9.3.11 中使用 PERMESSAGE_DEFLATE 导致 native 内存泄漏

标签 websocket jetty spring-websocket jetty-9

我们正在使用jetty版本9.3.11版本jetty容器来部署我们的应用程序

我们正在使用 tyrus 客户端将客户端连接到我们部署的 websocket 服务器。

当我使用以下代码连接时:

WebSocket ws = null;
        try {

            ws = new WebSocketFactory().createSocket(server)
                    .addListener(new NotifierAdapter(userId, channel))
                    .addExtension(WebSocketExtension.PERMESSAGE_DEFLATE).connect();

        } catch (WebSocketException we) {
            connect(server, userId, channel);
        }catch(Exception e)
        {
            e.printStackTrace();
        }return ws;

我的机器大约有 8000 个连接占用了 40% 的内存

但是通过修改代码(删除deflate扩展)

try {

            ws = new WebSocketFactory().createSocket(server)
                    .addListener(new NotifierAdapter(userId, channel))
                    .connect();

        } catch (WebSocketException we) {
            connect(server, userId, channel);
        }catch(Exception e)
        {
            e.printStackTrace();
        }return ws;

仅用 15% 内存就能连接到 15000 个连接 即使在最新版本的 Jetty 服务器中,是否存在与放气装置相关的泄漏。

有没有办法在jetty的服务器端禁用PERMESSAGE_DEFLATE.. 我们还使用 spring websocket 传递 jettyrequestupgrade 策略

Spring配置代码如下:

@Configuration
@EnableWebMvc
@EnableAspectJAutoProxy
@EnableWebSocket
public class WebMVCConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {


    private static final String NOTIFIER_ENDPOINT_URL = "/notificationHandler";

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(socketHandler(), NOTIFIER_ENDPOINT_URL).setAllowedOrigins("*");
    }

    @Bean
    public WebSocketHandler socketHandler() {
        return new NotificationSocketHandler();
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Bean
    public DefaultHandshakeHandler handshakeHandler() {

        WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
        policy.setInputBufferSize(8192);
        policy.setIdleTimeout(600000);
        WebSocketServerFactory ws=new WebSocketServerFactory(policy);
        ws.getExtensionFactory().unregister("permessage-deflate");
        return new DefaultHandshakeHandler(new JettyRequestUpgradeStrategy(ws));
    }

}

尽管当我从浏览器在响应 header 中连接时,我没有注册 permessage-deflate,但我可以看到该标志仍然启用,因此应该在容器中进行任何其他更改吗?

或者是spring websocket配置有问题:

响应头如下:

Connection:Upgrade
Sec-WebSocket-Accept:xbbUnu7pDWs9Q0st4T1LzsIfqao=
Sec-WebSocket-Extensions:permessage-deflate
Upgrade:WebSocket

我认为下面的错误尚未解决。

https://github.com/eclipse/jetty.project/issues/293

是否有任何解决方法(在jetty服务器中显式配置以禁用jetty服务器容器中的PERMESSAGE_DEFLATE或Jetty的spring配置

搜索后我找不到任何关于服务器容器/代码配置的解决方案,spring websocket 不起作用..

作为解决方法,我编写了一个拦截器,它将从 header 中删除参数 Sec Websocket entension..以便服务器将发送没有此扩展名的响应

最佳答案

内存泄漏的原因是 JVM 类路径中 Deflate 实现的 JVM 错误。

设置对象池只会延迟不可避免的事情,它只会减缓内存泄漏。

如果您有权访问WebSocketServletFactory,那么...

 factory.getExtensionFactory().unregister("permessage-deflate");

如果您只能通过 JSR-356 进行访问,则实现自定义配置器并在扩展协商期间删除 permessage-deflate 扩展。

public class StripExtensionsConfigurator extends ServerEndpointConfig.Configurator
{
    @Override
    public List<Extension> getNegotiatedExtensions(List<Extension> installed, 
                                                   List<Extension> requested)
    {
        return Collections.emptyList();
    }
}

关于websocket - 在 JETTY9.3.11 中使用 PERMESSAGE_DEFLATE 导致 native 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39538512/

相关文章:

Java 注释和 websocket - 为什么使用注释而不是传统方法?

node.js - socket.io 重新连接示例

java - 强制 Jetty 加载父 ClassLoader 中的类

internet-explorer - 如何在 jetty 或 tomcat 中添加自定义 header ...以进行 IE 边缘仿真?

java - Spring 4 Websocket 支持和客户端订阅所有主题

spring - @MessageMapping 与占位符

django - Web Sockets 在 Heroku 上的 Django 应用程序中不起作用

python - 如何使用 Python 的内置日志记录和 Asyncio(权限错误)

java - 阻止 Jetty 在收到无效的 HTTP 请求时抛出堆栈跟踪

java - Spring MVC + Stomp + WebSocket + https 不作为 http