Как исправить совместимость Websockets и Shedlock в приложении Spring Boot - PullRequest
1 голос
/ 07 мая 2019

У меня есть приложение реального времени 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 Ответ

2 голосов
/ 08 мая 2019

ShedLock по умолчанию создает прокси вокруг ThreadPoolTaskScheduler, и кажется, что Spring Websockets требует ThreadPoolTaskScheduler экземпляр.

Вы можете переключить ShedLock в режим прокси AOP следующим образом @EnableSchedulerLock(mode = PROXY_METHOD, defaultLockAtMostFor = "PT1S") См. Дополнительную информацию в документации .(Как примечание: 1 секунда lockAtMost для времени довольно коротка, если вы не укажете иначе, все блокировки будут сняты через 1 с)

...