在JETTY9.3.11中使用PERMESSAGE_DEFLATE导致本机内存泄漏

时间:2016-09-16 19:02:46

标签: 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服务器中,是否有任何与deflaters相关的泄漏..

有没有办法在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));
    }

}

虽然当我从浏览器连接到响应头时我没有注册permessage-deflate我可以看到该标志仍然启用任何其他更改应该在containter中为此做?

或者弹簧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 websocket无法正常工作..

作为一种解决方法,我编写了一个拦截器,它将从头部删除参数Sec Websocket entension。所以该服务器将发送没有此扩展的响应

1 个答案:

答案 0 :(得分:2)

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

设置ObjectPool只会延迟不可避免的事情,它只会减慢内存泄漏。

如果您有权访问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();
    }
}
相关问题