使用 Spring Boot 与 SQL 数据库连接的服务器发送事件

Posted

技术标签:

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

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

【问题讨论】:

如果我的理解正确,或者如果您想安排活动,那么使用 @Async 应该可以解决您的目的,然后使用 Schedule annotation 那么,@Async 的情况下我不需要使用 Flux 吗?如果您提供 sn-p 代码会有所帮助。 详细检查我的答案.. 【参考方案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,因为我与她讨论了计划任务或异步,所以她询问了异步但肯定会再次确认她是否正在寻找调度任务.. 我希望安排在特定时间间隔内显示来自数据库的通知的任务

以上是关于使用 Spring Boot 与 SQL 数据库连接的服务器发送事件的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用 intellij Datagrip 连接到在 Spring Boot 包中创建的数据库

无法从 Spring Boot 应用程序连接不间断 SQL

Spring-Boot 仅在一个配置文件中执行 data.sql

无法将 spring-boot 2 服务连接到不同容器中的 mysql

Spring Boot API 错误地重复 SQL 数据

使用 Spring Boot 与 SQL 数据库连接的服务器发送事件