Пул соединений Hikari — медленное, блокирующее, соединение недоступно: SpringBoot

#java #spring-boot #jdbc #hikaricp

#java #весенняя загрузка #jdbc #hikaricp

Вопрос:

Проблема:

У меня есть приложение springboot, в котором настроен hikari (автоматически). Я получаю сообщение об ошибке

Соединение недоступно, время ожидания запроса истекло через 30113 мс

когда я просто выполняю операцию вставки в базу данных, и поток выглядит как Контроллер> Служба> Репозиторий> сохранить (сущность), также не используя @Transactional в репозитории, но результат тот же, если я его использую.

  1. Во время нагрузочного теста 50 запросов / 1 сек к этой службе последовательно выполняются для 20-30 запросов? оставшийся сбой с приведенным ниже исключением.

     2019-03-28 20:58:29.507 ERROR 90260 --- [http-nio-8080-exec-234] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection] with root cause
    
    java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30113ms.
        at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:697) ~[HikariCP-3.3.1.jar:na]
      

    Я провожу своего рода нагрузочное тестирование как запуск 50req / 1sec и наполовину получаю успех или неудачу. Также включено обнаружение утечек, но в журнале нет следов.

  2. Я переусердствовал с конфигурациями для этого теста или мне нужно настроить соединения с пулом? или он поддерживает только это?

  3. Также подключение hikari getconnection после 2-го запроса и последующих запросов занимает почти увеличенные 5 секунд (блоки), почему? Почему это не параллельно? Пожалуйста, помогите мне или укажите, сколько мне нужно настроить, чтобы принимать примерно 200 запросов за 1 минуту.

application.yml

 spring:
  application:
    name: demo
  datasource:
    hikari:
      connection-timeout: 20000
      minimum-idle: 5
      maximum-pool-size: 50
      idle-timeout: 300000
      max-lifetime: 1200000
      auto-commit: true
      driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
      jdbc-url:: jdbc:sqlserver://ip:port;databaseName=sample
      username: username
      leak-detection-threshold: 30000
  

BootApplication.java

 @SpringBootApplication
public class Sample{
public static void main(String[] args) {
        SpringApplication.run(Sample.class, args);
    }

@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari")
    public DataSource dataSource() {
     HikariDataSource dataSource=new HikariDataSource();
          //configuring pass from vault
        return dataSource;
    }
}
  

SampleService.java

 @Service
public class SampleService implements SampleService {
    @Autowired
    private SampleRepository sampleRepository;

    @Override
    public List<String> getAll() {
        return (List<String>) sampleRepository.findAll();
    }

    @Override
    public String saveOrUpdate(Sample obj) {
        return sampleRepository.save(obj);
    }
}
  

Комментарии:

1. Сколько времени занимают запросы, которые выполняются успешно? Если у вас в вашем пуле не более 50 подключений, но запрос занимает больше 1 секунды, то выполнение 50 запросов в секунду, конечно, приведет к истощению пула, потому что новые запросы поступают, когда старые запросы все еще выполняются…

2. обычно выполнение запроса занимает постоянно 6 секунд.

3. Тогда вам нужно либо найти способ быстрее освобождать соединения, либо увеличить размер вашего пула как минимум до 300 (и убедиться, что конфигурация вашей базы данных допускает такое количество подключений!). Или вам нужно протестировать с более реалистичными числами. Если ваше требование составляет 200 запросов в минуту, почему вы тестируете с 50 запросами в секунду (или 3000 в минуту)?

4. как мне быстрее разорвать соединение при загрузке spring, класс репозитория jpa использует соединение. Есть ли способ сделать это? Но тогда я не могу определить 10 секунд, потому что предстоящему запросу требуется 2 и более секунд, чтобы перехватить соединение. Также я пробовал теперь, как каждые 10 секунд запрашивать 20. Но это не удалось в диапазоне 5 минут. постоянно требуется время для подключения hikari, что приводит к этому исключению.

5. Под более быстрым выпуском я имел в виду, что вам нужно найти способ повысить производительность, чтобы вы не поддерживали соединение в течение 6 секунд.