簡體   English   中英

頻繁發送到spring-websocket會話:在傳輸中丟失

[英]Frequent send to spring-websocket session: lost in transit

我得到了一個spring websocket服務器(基於Jetty和spring版本4.3.2.RELEASE)和客戶端的負載測試設置,它可以生成許多連接(基於spring的示例java websocket客戶端)。 下面的代碼將數據發送到給定的websocket會話:該代碼段利用了可以使用sessionId而不是User ID的情況( Spring WebSocket @SendToSession:向特定會話發送消息 )。 我可能經常每2-3毫秒執行一次這段代碼。 我使用SimpleMessageBroker。

 public void publishToSessionUsingTopic(String sessionId, String subscriptionTopic, Map<String, CacheRowModel> payload) {

        String subscriptionTopicWithoutUser = subscriptionTopic.replace(USER_ENDPOINT, "");
        // necessary message headers for per-session send
        SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
        headerAccessor.setSessionId(sessionId);
        headerAccessor.setLeaveMutable(true);          
        simpMessagingTemplate.convertAndSendToUser(sessionId, subscriptionTopicWithoutUser, Collections.singletonList(payload), headerAccessor.getMessageHeaders());

}

當這個代碼非常頻繁地執行(每2-3毫秒) ~100個會話時,我在我的日志中看到它運行並調用convertAndSendToUser,一些會話將不會收到該消息。 我很欣賞有關如何清除這些問題的任何建議。

好吧,我認為你的問題是:

@Bean
public ThreadPoolTaskExecutor clientOutboundChannelExecutor() {
    TaskExecutorRegistration reg = getClientOutboundChannelRegistration().getOrCreateTaskExecRegistration();
    ThreadPoolTaskExecutor executor = reg.getTaskExecutor();
    executor.setThreadNamePrefix("clientOutboundChannel-");
    return executor;
}

它為Executor使用此配置:

protected ThreadPoolTaskExecutor getTaskExecutor() {
    ThreadPoolTaskExecutor executor = (this.taskExecutor != null ? this.taskExecutor : new ThreadPoolTaskExecutor());
    executor.setCorePoolSize(this.corePoolSize);
    executor.setMaxPoolSize(this.maxPoolSize);
    executor.setKeepAliveSeconds(this.keepAliveSeconds);
    executor.setQueueCapacity(this.queueCapacity);
    executor.setAllowCoreThreadTimeOut(true);
    return executor;
}

請參閱,沒有配置RejectedExecutionHandler 默認情況下,它就像:

private RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy();

因此,當你有足夠多的消息和任務超過ThreadPool ,任何額外的消息都會被中止。

要解決此問題,您應該實現WebSocketMessageBrokerConfigurer並覆蓋其configureClientOutboundChannel()以提供一些自定義taskExecutor(ThreadPoolTaskExecutor taskExecutor) ,例如使用new ThreadPoolExecutor.CallerRunsPolicy()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM