Использование PERMESSAGE_DEFLATE вызывает утечку собственной памяти в JETTY9.3.11

Мы используем контейнер Jetty версии 9.3.11 для развертывания нашего приложения.

мы используем клиент tyrus для подключения клиента к серверу веб-сокетов, который мы развернули.

когда я подключаюсь, используя следующий код:

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;

Удалось подключиться к 15000 соединений только с 15% памяти. Есть ли утечка с соответствующими дефляторами даже в последней версии сервера Jetty..

Есть ли способ отключить PERMESSAGE_DEFLATE на стороне сервера причала. Также мы используем стратегию весеннего веб-сокета, передающую 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, когда я подключаюсь из браузера в заголовке ответа, я вижу, что флаг все еще включен, любые другие изменения должны быть сделаны в контейнере для этого ??

Или есть какие-либо проблемы с конфигурацией весеннего веб-сокета:

Также заголовок ответа выглядит следующим образом:

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

Я думаю, что ошибка ниже еще не решена.

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

Есть ли какой-либо обходной путь для этого (явная конфигурация на сервере причала для отключения PERMESSAGE_DEFLATE в контейнере сервера причала или конфигурация весны для причала

После поиска я не смог найти какое-либо решение для конфигурации контейнера/кода сервера с весенним веб-сокетом, который не работал.

В качестве обходного пути я написал перехватчик, который удалит параметр Sec Websocket entension из заголовка, чтобы сервер отправил ответ без этого расширения.


person svs teja    schedule 16.09.2016    source источник


Ответы (1)


Причиной утечки памяти является ошибка 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();
    }
}
person Joakim Erdfelt    schedule 16.09.2016
comment
Я уже отменил регистрацию этого расширения WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER); policy.setInputBufferSize(8192); policy.setIdleTimeout (600000); WebSocketServerFactory ws=new WebSocketServerFactory(policy); ws.getExtensionFactory(). unregister (permessage-deflate); вернуть новый DefaultHandshakeHandler (новый JettyRequestUpgradeStrategy (ws)); - person svs teja; 17.09.2016
comment
Поскольку мы отменяем регистрацию на websocketServerFactory, он должен отключить дефляцию permessage, но с указанным выше кодом, указанным также в браузере Chrome, я все еще могу видеть Connection:Upgrade Sec-WebSocket-Accept:xbbUnu7pDWs9Q0st4T1LzsIfqao= Sec-WebSocket-Extensions:permessage-deflate. .Можете ли вы предоставить какой-либо обходной путь отключения в контейнере сервера (конфигурации сервера причала) - person svs teja; 17.09.2016
comment
Также есть ли что-то подобное в контейнере сервера причала (не в приложении) stackoverflow.com/questions/28894316/ - person svs teja; 17.09.2016
comment
В качестве обходного пути я написал перехватчик, который удалит параметр Sec Websocket entension из заголовка, чтобы сервер отправил ответ без этого расширения. - person svs teja; 18.09.2016