Асинхронный контроллер в Spring Boot - PullRequest
0 голосов
/ 09 мая 2019

Я создал Webservice, используя Spring boot, и в нем есть контроллер rest, который обращается к базе данных через драйвер JDBC на основе поставщика и извлекает записи. В этом процессе количество найденных записей составляет более 80 тыс. Записей. Из-за этого, когда мы используем конечную точку отдыха как клиента, мы получаем ошибки тайм-аута.

Я попытался настроить асинхронные вызовы, используя приведенное ниже учебное пособие. Но, к сожалению, время ожидания остальных вызовов все еще истекло.

https://howtodoinjava.com/spring-boot2/enableasync-async-controller/

Контроллер

    @RequestMapping(value = "/v1/lr/fullpositionasync", produces = {APPLICATION_JSON_UTF8_VALUE},   method = RequestMethod.GET)
    @ResponseBody
    public CompletableFuture<List<Position>> retrieveTradePositionsFullAsync(HttpServletRequest request, HttpServletResponse response) throws ExecutionException, InterruptedException {

        CompletableFuture<List<Position>> positionList =null;
        try {
            positionList = positionService.getFullPosition();
        }
        catch(Exception e){
            log.info("Error Occurred in Controller is:"+e.getMessage());
        }
        CompletableFuture.allOf(positionList).join();
        log.info(String.valueOf(positionList.get()));
        return positionList;
    }

Услуги

@Service
@Slf4j
public class PositionServiceImpl implements PositionService {

    @Autowired
    private PositionDao positionDao;

    @Async("asyncExecutor")
    @Override
    public CompletableFuture<List<Position>> getFullPosition()  {

        List<Position> fullpositionList = null;
        log.info("Getting the full Position process started");
        fullpositionList = positionDao.retrieveData();
        log.info("Total Positions retrieved:"+fullpositionList.size());
        try {
            log.info("Thread is about to sleep 1000 milliseconds");
            Thread.sleep(1000);
        }catch(InterruptedException e){
            log.info(e.getMessage());
        }
        log.info("Full Positions retrieval completed");
        return CompletableFuture.completedFuture(fullpositionList);
    }


}

Конфигурация

@Configuration
@EnableAsync
@Slf4j
public class AsyncConfiguration
{
    @Bean(name = "asyncExecutor")
    public Executor asyncExecutor()
    {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(20);
        executor.setMaxPoolSize(1000);
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setThreadNamePrefix("AsynchThreadForEndPoint-");
        executor.initialize();
        log.info("Executor is :"+executor.toString());
        return executor;
    }
}

DAO

@Repository
public class PositionDaoImpl implements PositionDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    private static final String ALL_POSITION_QUERY = "call AllPositionProcedure()";


    public List<Position> retrieveData() {
        return jdbcTemplate.query(ALL_POSITION_QUERY, new BeanPropertyRowMapper(Position.class));
        //  List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql);

    }

Ответы [ 2 ]

0 голосов
/ 09 мая 2019

Для вашего случая использования лучший способ - преобразовать ваше приложение в Reactive Streams (Flux).

Flux - это издатель Reactive Streams. это полностью неблокирующая основа реактивного программирования для JVM с эффективным управлением запросами (в форме управления «противодавлением»). Он напрямую интегрируется с функциональными API-интерфейсами Java 8, в частности CompletableFuture, Stream и Duration. Он предлагает составные интерфейсы API асинхронной последовательности Flux (для элементов [N]) и Mono (для элементов [0 | 1]), широко реализуя спецификацию Reactive Streams .

это очень просто реализовать в существующем приложении. просто измените тип возвращаемого репозитория Flux вместо List или Future.

Для получения дополнительной информации, вы можете взять ссылку Здесь

0 голосов
/ 09 мая 2019

Вы не можете выполнять асинхронные операции над базой данных с помощью JDBC. JDBC блокирует, поэтому он будет блокировать ваш поток, пока не будут выполнены операции. Если вы хотите выполнять операции асинхронно, используйте R2DBC вместо JDBC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...