Tomcat 7.0.42 объединение, hibernate 4.2, решение для решения сложных задач mysql rock

Я прочитал много сообщений о проблемах с автоматическим повторным подключением к mysql из сеанса hibernate. Другие упоминают увеличение mysql wait_timeout (не мой любимый), используя autoReconnect = true (не рекомендуется), тестирование соединения e.t.c. В настоящее время я пытаюсь несколько вариантов, но я хотел бы спросить, есть ли у кого-то твердое решение с использованием пула соединений tomcat (а не hibernate c3po). Я смотрю на самые надежные настройки jndi, даже если они не соответствуют лучшей производительности.

Большое спасибо,

Привет

Ответ 1

Отличный вопрос. Я использую для борьбы с этим вопросом. Самый общий ответ на stackoverflow - "Это зависит..." для практически каждой проблемы. Я ненавижу говорить об этом, но нет, где это более важно, чем настройка вашего пула соединений. Это действительно игра спроса и предложения, в которой ваши запросы на подключение являются спросом, а предложение - количеством подключений MySQL. Это действительно сводится к тому, что ваша основная проблема заключается в предотвращении возврата устаревших подключений из пула или же ваша забота об обеспечении того, чтобы MySQL не перегружался простыми соединениями, потому что вы не убивали их достаточно быстро. Большинство людей щели посередине где-то.

Если вы действительно понимаете, почему кто-то выбирает конфигурацию одного пула соединений, тогда поверьте мне, вы перестанете искать настройку "Rocket Solid", потому что вы будете знать, что это похоже на поиск в бизнес-плане в вашем магазине; Это полностью связано с количеством запросов на соединение и количеством постоянных соединений, которые вы готовы предоставить. Ниже приводятся примеры того, почему вы используете определенные настройки. Я ссылаюсь на переменные, которые вам придется изменить внутри тега "Ресурс" тега "Контекст" вашего файла Context.xml. Полную конфигурацию образца можно увидеть в самом низу.

Низкий трафик

В этой ситуации у вас мало запросов к вашему приложению, поэтому есть хорошая вероятность, что ВСЕ соединения в пуле подключений будут устаревать, а первый запрос вашего приложения устаревшим соединением вызовет ошибку. (В зависимости от драйвера MySQL, который вы используете, ошибка может объяснить, что последний успешный полученный пакет превысил настройку wait_timeout базы данных). Таким образом, ваша стратегия пула соединений заключается в предотвращении возврата мертвого соединения. Следующие два варианта имеют небольшой побочный эффект для сайта с низким трафиком.

  • Подождите дольше, чем удалять соединения. Это можно сделать, изменив значение wait_timeout в вашей конфигурации MySQL. В Workbench MYSQL вы можете легко найти этот параметр в Admnin > Конфигурационный файл > Networking. Для сайта с большим количеством трафика это часто не рекомендуется, потому что это может привести к тому, что пул всегда будет заполнен много простоя соединений. Но помните, что это низкий трафик сценарий.

  • Проверить каждое соединение. Вы можете сделать это, установив testOnBorrow = true и validationQuery= "SELECT 1". Как насчет производительности? В этой ситуации у вас низкий трафик. Тестирование каждого соединения, возвращаемого из пула, не является проблемой. Все это означает, что к каждой транзакции MySQL, которую вы выполняете в одном соединении, добавляется дополнительный запрос. На сайте с низким трафиком это действительно то, о чем вы будете беспокоиться? Проблема ваших соединений, которые мертвы в пуле, потому что они не используются, - это ваш основной фокус.

Средний трафик

  • Периодически проверяйте все подключения. Если вы не хотите проверять каждое соединение каждый раз, когда оно используется, или продлить время ожидания ожидания, то вы можете периодически проверять все подключения по умолчанию или пользовательский запрос по вашему выбору. Например, установите validationQuery = "SELECT 1", testWhileIdle = "true" и timeBetweenEvictionRunsMillis = "3600" или любой другой интервал, который вы хотите. Для очень низкого трафика это абсолютно требуя больше работы. Думаю об этом. Если у вас есть 30 соединения в пуле и через 1 час вызывается только 4 вызова, тогда вы могли бы легко проверить все 4 соединения по каждому запросу, используя предыдущий подход testOnBorrow с небольшим успехом. Но если вместо этого вы выполняете подход "Проверить все каждый час", вы делаете 30 запросов для проверки всех подключений, когда только 4.

Высокий трафик

  • Убейте дружественных соединений быстрее. Это та ситуация, в которой все говорят, что вы не должны расширять wait_timeout, а вы не должны проверять каждое соединение. Это не идеальная модель для каждой ситуации. Когда у вас есть значительный трафик каждое соединение в пуле будет использовано и ваша фактическая проблема увеличит количество доступных подключений, пока фактически сокращая длину вашего wait_time, чтобы вы не закончили много свободных соединений в БД. Вот пример беседы о том, как он имеет до 10 000 бесплатных подключений в день для загруженного сайта, поэтому он хочет снизить wait_timeout Понижение wait_timeout для занятого сайта

Конфигурация примера Context.xml

<Context>   

<Resource name="jdbc/TestDB"
          auth="Container"
          type="javax.sql.DataSource"
          factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
          testWhileIdle="true"
          testOnBorrow="true"
          testOnReturn="false"
          validationQuery="SELECT 1"
          validationInterval="30000"
          timeBetweenEvictionRunsMillis="30000"
          maxActive="100"
          minIdle="10"
          maxWait="10000"
          initialSize="10"
          removeAbandonedTimeout="60"
          removeAbandoned="true"
          logAbandoned="true"
          minEvictableIdleTimeMillis="30000"
          jmxEnabled="true"
          jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
            org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
          username="root"
          password="password"
          driverClassName="com.mysql.jdbc.Driver"
          url="jdbc:mysql://localhost:3306/mysql"/>
</Context>

Пример конфигурации web.xml

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">
  <description>MySQL Test App</description>
  <resource-ref>
      <description>DB Connection</description>
      <res-ref-name>jdbc/TestDB</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
  </resource-ref>
</web-app>

Документация по свойствам Tomcat Pool для настройки Tomcat Pool