如何在Spring Boot应用程序中修复Websockets和Shedlock兼容性

时间:2019-05-07 07:14:18

标签: java spring-boot websocket hazelcast shedlock

我有一个Spring Boot实时应用程序,该应用程序将Websockets与SockJS一起使用。目前,我正在使用LoadBalancer和两个实例扩展我的应用程序。由于应用程序中的cron作业很少,因此我需要在两台服务器之间同步它,以一次仅运行一个任务。为此,我使用了shedlock-spring和shedlock-provider-hazelcast依赖关系(我也在应用程序中使用了Hazelcast)。

如果我将@EnableSchedulerLock(defaultLockAtMostFor = "PT1S")注释添加到MainApplication.class应用程序,则由于以下错误而无法启动:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'stompWebSocketHandlerMapping' defined in class path resource [org/springframework/web/socket/config/annotation/DelegatingWebSocketMessageBrokerConfiguration.class]: 
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: 
Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'stompWebSocketHandlerMapping' threw exception; nested exception is java.lang.IllegalStateException: 
@Bean method AbstractMessageBrokerConfiguration.messageBrokerTaskScheduler called as a bean reference for type [org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler] but overridden by non-compatible bean instance of type [com.sun.proxy.$Proxy136]. 
Overriding bean of same name declared in: class path resource [org/springframework/web/socket/config/annotation/DelegatingWebSocketMessageBrokerConfiguration.class]

@SchedulerLock注释可以正常工作,因为我在单独的应用程序中对其进行了测试,但是它似乎与Websockets冲突并覆盖了某些bean。我是Websockets配置的新手,所以如果有人知道此错误的原因以及如何解决此问题,请提供帮助。

这是我的Websocket配置,可以完美运行:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/socket")
                .setAllowedOrigins("*")
                .withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.setApplicationDestinationPrefixes("/app")
                .enableSimpleBroker("/notification");
    }
}

1 个答案:

答案 0 :(得分:2)

默认情况下,ShedLock在ThreadPoolTask​​Scheduler周围创建一个代理,并且看来Spring Websockets需要ThreadPoolTaskScheduler实例。

您可以像这样@EnableSchedulerLock(mode = PROXY_METHOD, defaultLockAtMostFor = "PT1S")将ShedLock切换到AOP代理模式,请参见documentation中的更多信息。 (作为一个附带说明,1秒的lockAtMostFor时间非常短,如果您未指定,则所有锁定将在1秒后释放)