การใช้ PERMESSAGE_DEFLATE ทำให้เกิดการรั่วไหลของหน่วยความจำดั้งเดิมใน JETTY9.3.11

เรากำลังใช้ท่าเทียบเรือเวอร์ชัน 9.3.11 เวอร์ชันท่าเทียบเรือคอนเทนเนอร์สำหรับการปรับใช้แอปพลิเคชันของเรา

เรากำลังใช้ไคลเอนต์ 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;

การเชื่อมต่อประมาณ 8,000 ครั้ง เครื่องของฉันใช้หน่วยความจำ 40%

แต่ด้วยการปรับเปลี่ยนโค้ดการมองเห็น (การลบส่วนขยายแบบยุบ)

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,000 รายการด้วยหน่วยความจำเพียง 15% มีการรั่วไหลที่เกี่ยวข้องกับตัวดีแฟลตแม้แต่ในเซิร์ฟเวอร์ Jetty เวอร์ชันล่าสุดหรือไม่..

มีวิธีใดที่จะปิดการใช้งาน PERMESSAGE_DEFLATE ในฝั่งเซิร์ฟเวอร์ของท่าเทียบเรือ .. นอกจากนี้ เรากำลังใช้ spring websocket ผ่านกลยุทธ์การอัพเกรด jettyrequest

รหัสกำหนดค่า 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 เมื่อฉันเชื่อมต่อจากเบราว์เซอร์ในส่วนหัวการตอบกลับ แต่ฉันเห็นว่าการตั้งค่าสถานะยังคงเปิดใช้งานอยู่ การเปลี่ยนแปลงอื่นใดที่ควรทำในคอนเทนเนอร์สำหรับสิ่งนี้

หรือมีปัญหากับการกำหนดค่า spring websocket:

ส่วนหัวของการตอบสนองมีดังนี้:

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

ฉันคิดว่าข้อผิดพลาดด้านล่างยังไม่ได้รับการแก้ไข

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

มีวิธีแก้ไขปัญหาใด ๆ สำหรับสิ่งนี้ (การกำหนดค่าที่ชัดเจนในเซิร์ฟเวอร์ท่าเทียบเรือเพื่อปิดการใช้งาน PERMESSAGE_DEFLATE ในคอนเทนเนอร์เซิร์ฟเวอร์ท่าเทียบเรือหรือการกำหนดค่าสปริงสำหรับท่าเทียบเรือ

หลังจากค้นหาฉันไม่พบวิธีแก้ไขปัญหาใด ๆ เกี่ยวกับการกำหนดค่าเซิร์ฟเวอร์คอนเทนเนอร์ / รหัสด้วย spring websocket ไม่ทำงาน ..

เพื่อเป็นวิธีแก้ปัญหา ฉันเขียน interceptor ซึ่งจะลบพารามิเตอร์ Sec Websocket entension ออกจากส่วนหัว .. ดังนั้นเซิร์ฟเวอร์นั้นจะส่งการตอบกลับโดยไม่มีส่วนขยายนี้


person svs teja    schedule 16.09.2016    source แหล่งที่มา


คำตอบ (1)


สาเหตุของหน่วยความจำรั่วคือข้อบกพร่องของ JVM ที่มีการใช้งาน Deflate ใน JVM Classpath

การตั้งค่า ObjectPool จะทำให้สิ่งที่หลีกเลี่ยงไม่ได้ล่าช้า เพียงแต่จะทำให้หน่วยความจำรั่วช้าลงเท่านั้น

หากคุณมีสิทธิ์เข้าถึง WebSocketServletFactory ดังนั้น ...

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

หากคุณมีสิทธิ์เข้าถึงผ่าน JSR-356 เท่านั้น ให้ใช้งาน Configurator แบบกำหนดเองและตัดส่วนขยาย 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); นโยบาย setInputBufferSize (8192); นโยบาย setIdleTimeout (600000); WebSocketServerFactory ws = WebSocketServerFactory ใหม่ (นโยบาย); ws.getExtensionFactory().unregister(permessage-deflate); คืน DefaultHandshakeHandler ใหม่ (JettyRequestUpgradeStrategy ใหม่ (ws)); - person svs teja; 17.09.2016
comment
ขณะที่เรากำลังยกเลิกการลงทะเบียนบน websocketServerFactory ควรปิดการใช้งาน permessage deflate แต่ด้วยโค้ดด้านบนที่ระบุในเบราว์เซอร์ 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
เพื่อเป็นวิธีแก้ปัญหา ฉันเขียน interceptor ซึ่งจะลบพารามิเตอร์ Sec Websocket entension ออกจากส่วนหัว .. ดังนั้นเซิร์ฟเวอร์นั้นจะส่งการตอบกลับโดยไม่มีส่วนขยายนี้ - person svs teja; 18.09.2016