【问题标题】:Server Sent Event with SQL Database connection using Spring Boot使用 Spring Boot 与 SQL 数据库连接的服务器发送事件
【发布时间】:2019-03-04 18:03:31
【问题描述】:

我想在 Spring Boot 中实现服务器发送事件。数据在 SQL 数据库中,导致连接阻塞。 Web Flux 是一个选项,但仅支持某些 NoSQL 数据库。

【问题讨论】:

  • 如果我的理解正确,或者如果您想安排活动,那么使用 @Async 应该可以解决您的目的,然后使用 Schedule annotation
  • 那么,@Async 的情况下我不需要使用 Flux 吗?如果您提供 sn-p 代码会有所帮助。
  • 详细检查我的答案..

标签: spring-boot server-sent-events spring-webflux


【解决方案1】:

是的,你说得对,WebFlux 框架在非阻塞模式下不支持 SQL 数据库,因为反应式驱动程序不存在。 但是 WebFlux 提供了一些工具来避免在我们阻塞对数据库的长查询时阻塞我们的主线程。

1) 使用Scheduler 创建配置,其中线程数等于池大小:

@Configuration
public class SchedulerConfiguration {
    @Value("${spring.datasource.maximum-pool-size}
    private final Integer connectionPoolSize;

   @Bean
   @Qualifier("jdbcScheduler")
   public Scheduler jdbcScheduler() {
      return Schedulers.fromExecutor(Executors.newFixedThreadPool(connectionPoolSize));
   }
}

2) 将“jdbcScheduler”注入服务类:

@Service
public class DataService {
    @Autowired
    private final DataRepository jdbcRepository;
    @Autowired @Qualifier("jdbcScheduler")
    private final Scheduler scheduler;

    public Mono<String> findById(long id) {
        return async(() -> repository.findById(id));
    }

    private <T> Mono<T> async(Callable<T> callable) {
        return Mono.fromCallable(callable).publishOn(scheduler);
    }
}

Mono.fromCallable 包装你的阻塞方法,并通过Mono.publishOn 从主线程委托给你的“调度程序”

您可以在此处阅读有关调度程序的更多信息:Threading and Schedulers

【讨论】:

    【解决方案2】:

    是的,您可以通过使用它们内置的 @Async 处理在 spring 中实现异步处理,无需通量,这里是如何实现的。

    第一步:启用 Aysnc 并为 Executor 定义一个 bean。您可以定义单独的配置或直接在主应用程序类下。

    @SpringBootApplication
    @EnableAsync
    public class Application {
    
        public static void main(String[] args) {
            // close the application context to shut down the custom ExecutorService
            SpringApplication.run(Application.class, args).close();
        }
    
        @Bean
        public Executor asyncExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(2);
            executor.setMaxPoolSize(2);
            executor.setQueueCapacity(500);
            executor.setThreadNamePrefix("GithubLookup-");
            executor.initialize();
            return executor;
        }
    

    第二步:

    以下是配置返回类型为 void 的方法异步运行的简单方法,您也可以使用 Future 对象通过检索异步过程的结果来调用方法。

    @Async
    public void asyncMethodWithVoidReturnType() {
        System.out.println("Execute method asynchronously. "
          + Thread.currentThread().getName());
    }
    

    更多信息,您可以访问Spring官方指南Spring Async

    【讨论】:

    • OP 询问了来自数据库的 SSE 流数据; Spring 的异步支持是关于在单独的线程上处理请求并避免阻塞容器线程。但这与流媒体是正交的。
    • 感谢@BrianClozel,因为我与她讨论了计划任务或异步,所以她询问了异步但肯定会再次确认她是否正在寻找调度任务..
    • 我希望安排在特定时间间隔内显示来自数据库的通知的任务
    猜你喜欢
    • 1970-01-01
    • 2019-01-26
    • 1970-01-01
    • 2020-10-04
    • 2012-04-22
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    相关资源
    最近更新 更多