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

How to fix Websockets and Shedlock compatibility in Spring Boot application

我有一个 Spring 引导实时应用程序,它使用带有 SockJS 的 Websockets。目前我正在使用 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");
    }
}

ShedLock 默认创建围绕 ThreadPoolTask​​Scheduler 的代理,似乎 Spring Websockets 需要 ThreadPoolTaskScheduler 实例。

您可以像这样将 ShedLock 切换到 AOP 代理模式 @EnableSchedulerLock(mode = PROXY_METHOD, defaultLockAtMostFor = "PT1S")documentation 中查看更多信息。 (顺便说一句,1秒lockAtMostFor时间很短,如果不另外指定,1秒后所有锁都会被释放)