Как вы настраиваете пул соединений? - PullRequest
10 голосов
/ 07 ноября 2008

Как лучше всего настроить свой пул в отношении: -

  1. Когда вы создаете соединения?
  2. Когда вы закрываете соединения, и вы бы закрыли их все?
  3. У тебя тесты связи все еще хороши. Когда и как?
  4. Как узнать, какое число подходит для максимального количества соединений?
  5. Какой тип мониторинга используется для обеспечения хорошего поведения пользователей пула? Можете ли вы помешать одному плохому куску кода уничтожить все?
  6. Вы написали свой собственный пул или использовали стороннюю библиотеку?

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

Чтобы уточнить, я не собираюсь писать пул с нуля, этот вопрос больше о том, как настроить существующую библиотеку, которая выполняет пул.

Ответы [ 6 ]

6 голосов
/ 07 ноября 2008

Я написал пул соединений для базы данных на Java, когда это был просто шаблон проектирования, а не обычная библиотека. Теперь я использую тот, который встроен в Tomcat.

Я использовал поток для мониторинга нескольких аспектов пула и нескольких параметров для управления его поведением ...

  1. imumInPool = "3" ... Первые три создаются при запуске. Пул никогда не должен опускаться ниже трех.
  2. maximumIdleTimeBeforeRemoval = "60" ... Если соединение не используется в течение часа, затем отбросьте его и создайте новое. Время простоя, вероятно, означает, что в пуле только три.
  3. maximumInUseTimeBeforeRemoval = "30" ... Если данное соединение было проверено в течение более 30 минут, значит, что-то не так. Вспомни это и убей соединение.
  4. maximumTimeBeforeRemoval = "60" ... Удалите его, если ему более 60 минут.
  5. maximumUsageBeforeRemoval = "1000" ... Удалите его, если оно было извлечено более 1000 раз.
  6. monitorInterval = "15" ... Проверяйте вышеуказанные параметры каждые 15 минут.

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

Я использовал тонкие драйверы JDBC от Oracle и подключился к базе данных Oracle.

3 голосов
/ 07 ноября 2008

Вот обоснование, которое я использовал для недавней реализации.

  1. В вашем пуле соединений есть два вида соединений. Первый готов, то есть открыт, но не используется клиентом. Второй активен, то есть используется клиентом.

  2. Пул соединений должен поддерживать небольшое количество готовых соединений, минимум N и максимум M. N можно настроить в зависимости от пиковой скорости, с которой ваши клиенты запрашивают соединения. Если количество готовых соединений когда-либо падает до нуля, вам нужно больше N. Если число постоянно высокое (скажем, выше 10), вам нужно меньшее N.

  3. Когда клиент хочет установить соединение, дайте ему один из готовых (делая его активным), а затем немедленно откройте новый, если теперь готово меньше, чем N (но не заставляйте клиента ждать этого для завершения, или вы потеряете преимущество объединения). Это гарантирует, что всегда будет хотя бы N готовых соединений. Если никто не будет готов, когда клиент захочет, ему придется подождать, пока вы создадите новый.

  4. Когда клиент завершает работу с активным соединением, верните его в состояние готовности, если число подключений меньше M готово. В противном случае закройте его. Это предотвращает наличие более M готовых соединений.

  5. Периодически перерабатывайте готовые соединения, чтобы предотвратить устаревшие соединения. Если подключений больше N, просто закройте самое старое соединение. В противном случае закройте его и снова откройте другой.

Преимущество заключается в том, что в вашем пуле соединений достаточно готовых и юношеских соединений без перегрузки сервера.

2 голосов
/ 09 февраля 2009

Я согласен с Мэттом Б, что мы не должны изобретать велосипед.

Однако использование фонда ДБХП спорно на основе ответов этом и это вопросы. Там упоминаются лучшие альтернативы, такие как c3po или proxool .

Или вы можете использовать зависимый от rdbms механизм пула соединений.

2 голосов
/ 18 ноября 2008

Джакарта Commons DBCP уже делает все, что вы перечислили:

  • создает необходимые подключения и управляет ими в пуле
  • может закрывать соединения, если они не использовались в течение определенного периода времени
  • он может выполнить запрос к соединению перед его раздачей, и в случае ошибки соединение отбрасывается и создается новое. Во время простоя соединения также можно периодически проверять.
  • Вы можете установить ограничение на количество соединений, которые будут созданы, а также на минимальное количество соединений, которые будут готовы. Предел, конечно, во многом зависит от вашего приложения.
  • Я не знаю, как, но DBCP знает, когда соединение не закрывается, и закрывает его для вас, создавая исключение, чтобы вы знали, что произошло, когда вы видите свой журнал.
  • DBCP имеет параметр тайм-аута, который очень полезен. Если все соединения в пуле используются, он будет ожидать в течение этого периода времени, пока соединение не будет возвращено в пул, и если по достижении лимита не будет доступных, вы получите ошибку.

Вы можете точно настроить свой пул, играя с минимальным количеством подключений, максимальным числом создаваемых подключений и временем ожидания. Более длительное время ожидания позволит вам иметь более низкий предел количества подключений, в то время как более короткое время ожидания, вероятно, потребует большего числа. Это сильно зависит от того, что делает ваше приложение и как оно использует соединения.

2 голосов
/ 07 ноября 2008

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

Я использую SQL-сервер в качестве бэкэнда и использую с ним комбинацию кэширования для повышения производительности. Моя практика заключается в том, чтобы поддерживать соединение открытым, только если оно мне действительно нужно, и не объединять соединения, чтобы они сразу очищались, и я могу видеть в мониторе SQL Activity, что именно активно, а что нет. Каждое соединение занимает память, поэтому приятно держать его в унылом реве, когда оно не нужно.

Прежде чем ответить на вопрос об открытом и закрытом соединении, позвольте мне сказать, что кэширование действительно важно. Извлечение объекта из кэша сэкономит вам массу времени. В некоторых из моих приложений asp.net, когда в dev включено кэширование, я обнаружил, что с трудом могу измерить задержку, тогда как при вызове БД для завершения вызова может потребоваться от 15 мс до 45 мс, и это даже не учитывает другие задержки факторы или нагрузка. Другой метод, который я использую, - это хорошая структура объектов для моих данных, поэтому я могу обновлять БД только в случае каких-либо изменений. Я реализовал несколько методов на своем объекте, чтобы убедиться, что я выполняю как можно меньше операций ввода-вывода.

При этом все мы знаем, что в какой-то момент нам нужен доступ и запись в нашу БД, поэтому я следую двум принципам:

  1. Держите двери и окна закрытыми для экономии энергии. Открытое соединение в одном месте означает, что оно недоступно в другом (или память и другие ресурсы более ограничены). Мы отключили объединение, потому что это привело к повышению производительности для нас.

  2. Я делаю как много, так и сразу, когда могу, когда соединение открыто. Это немного сложнее, поэтому позвольте мне объяснить.

    • один из методов, который я использовал, - это передача объектов подключения по каналу, чтобы все объекты могли использовать один объект подключения. Это приводит к открытию и закрытию одного соединения вместо 10 или более, в зависимости от вашего приложения. Хорошим примером этого является одна из наших моделей закупок, которая использует возможности сервера SQL для сбора статистики и хеширования сложных шаблонов заказов. Не имеет смысла продолжать открывать и закрывать соединение, когда вы выполняете поиск по базе данных объемом более 200 КБ или для приложений, для которых они предназначены. Другая часть этого заключается в том, что когда я использую объект, я пытаюсь связать свои обновления, чтобы сократить время, в течение которого я оставляю соединение открытым. Таким образом, выполнение scope_identity для вызова вставки позволило мне позаботиться как о вставке, так и о поиске уникального идентификатора, добавляемого в мой объект перед его кэшированием. В тот день, когда я впервые разрабатывал asp-приложения, я фактически открыл соединение, как только страница начала загружаться, а затем закрыл его. Я не рекомендую делать это больше. Теперь у такого рода абстракций и уровней есть большое преимущество, к которому я бы порекомендовал любой начинающий программист.

Мои два цента:

Кэшируйте ваши данные! Кэшируйте ваши данные! Кэшируйте ваши данные! Делайте как можно меньше доступа к БД, когда вы не можете кешировать, а затем кешируйте свои данные!

1 голос
/ 07 ноября 2008

Зачем изобретать велосипед?

Кто-то, возможно, уже решил проблему, и лучше.

Если вы находитесь в мире Java, вы можете использовать Commons DBCP .

...