Spring Webflux并从数据库中读取 [英] Spring webflux and reading from database

查看:862
本文介绍了Spring Webflux并从数据库中读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Spring 5通过

Spring 5 introduces the reactive programming style for rest APIs with webflux. I'm fairly new to it myself and was wondering wether wrapping synchronous calls to a database into Flux or Mono makes sense preformence-wise? If yes, is this the way to do it:

@RestController
public class HomeController {

    private MeasurementRepository repository;

    public HomeController(MeasurementRepository repository){
        this.repository = repository;
    }

    @GetMapping(value = "/v1/measurements")
    public Flux<Measurement> getMeasurements() {
        return Flux.fromIterable(repository.findByFromDateGreaterThanEqual(new Date(1486980000L)));
    }

}

是否存在异步CrudRepository之类的东西?我找不到.

Is there something like an asynchronous CrudRepository? I couldn't find it.

推荐答案

一种选择是使用完全无阻塞的替代SQL客户端.一些示例包括: https://github.com/mauricio/postgresql-async

One option would be to use alternative SQL clients that are fully non-blocking. Some examples include: https://github.com/mauricio/postgresql-async or https://github.com/finagle/roc. Of course, none of these drivers is officially supported by database vendors yet. Also, functionality is way much less attractive comparing to mature JDBC-based abstractions such as Hibernate or jOOQ.

另一个想法来自Scala世界.这个想法是将阻塞调用分派到隔离的ThreadPool中,而不是将阻塞和非阻塞调用混合在一起.这将使我们能够控制线程的总数,并使CPU在主执行上下文中以一些潜在的优化服务于非阻塞任务. 假设我们确实有基于JDBC的实现(例如Spring Data JPA),该实现确实处于阻塞状态,那么我们可以使其异步执行并在专用线程池上分派.

The alternative idea came to me from Scala world. The idea is to dispatch blocking calls into isolated ThreadPool not to mix blocking and non-blocking calls together. This will allow us to control the overall number of threads and will let the CPU serve non-blocking tasks in the main execution context with some potential optimizations. Assuming that we have JDBC based implementation such as Spring Data JPA which is indeed blocking, we can make it’s execution asynchronous and dispatch on the dedicated thread pool.

@RestController
public class HomeController {

    private final MeasurementRepository repository;
    private final Scheduler scheduler;

    public HomeController(MeasurementRepository repository, @Qualifier("jdbcScheduler") Scheduler scheduler) {
        this.repository = repository;
        this.scheduler = scheduler;
    }

    @GetMapping(value = "/v1/measurements")
    public Flux<Measurement> getMeasurements() {
        return Mono.fromCallable(() -> repository.findByFromDateGreaterThanEqual(new Date(1486980000L))).publishOn(scheduler);
    }

}

我们的JDBC Scheduler应该使用大小等于连接数的专用线程池进行配置.

Our Scheduler for JDBC should be configured by using dedicated Thread Pool with size count equal to the number of connections.

@Configuration
public class SchedulerConfiguration {
    private final Integer connectionPoolSize;

    public SchedulerConfiguration(@Value("${spring.datasource.maximum-pool-size}") Integer connectionPoolSize) {
        this.connectionPoolSize = connectionPoolSize;
    }

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

}

但是,这种方法存在一些困难.主要的是交易管理.在JDBC中,事务只能在单个java.sql.Connection中进行.要在一个事务中进行多个操作,它们必须共享一个连接.如果我们要在它们之间进行一些计算,则必须保持连接.这不是很有效,因为我们在进行之间的计算时会保持有限数量的连接处于空闲状态.

However, there are difficulties with this approach. The main one is transaction management. In JDBC, transactions are possible only within a single java.sql.Connection. To make several operations in one transaction, they have to share a connection. If we want to make some calculations in between them, we have to keep the connection. This is not very effective, as we keep a limited number of connections idle while doing calculations in between.

关于异步JDBC包装的想法并不是什么新东西,它已经在Scala库Slick 3中实现.最后,Java路线图上可能会出现非阻塞JDBC.正如它于2016年9月在JavaOne上宣布的那样,很有可能我们将在Java 10中看到它.

This idea of an asynchronous JDBC wrapper is not new and is already implemented in Scala library Slick 3. Finally, non-blocking JDBC may come along on the Java roadmap. As it was announced at JavaOne in September 2016, and it is possible that we will see it in Java 10.

这篇关于Spring Webflux并从数据库中读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆