Как создать демон с подключением к БД MySQL

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

  1. получить все необходимые задания из очереди
  2. выполните задания
  3. спать в течение N секунд
  4. Гото 1

демон должен выжить прерванная служба с сервера БД MySQL и нарушение соединений с БД.

вы бы разработали демон для подключения к серверу БД один раз за цикл? т. е. подключение до 1. и разрыв между 2 и 3?

или вы хотите, чтобы демон поддерживал соединение открытым? В этом случае ему также необходимо a) определить, когда сервер или соединение не работает, b) отключить и повторно подключиться, и c) сделать это без накопления соединений DB, дескрипторов соединений dud или других мертвых ресурсы.

Если у вас есть предпочтения, почему?

плюсы и минусы?

факторы, которые входят в конструкцию?

какие-то другие подходы?

ответ здесь: mysql соединение от демона, написанного на php не говорит, Почему лучше держать соединение открытым. Я читал в другом месте, что накладные расходы на соединение в MySQL очень легкие. Поэтому не очевидно, почему постоянное использование одного подключения к серверу лучше, чем подключение/отключение каждые несколько секунд.

в моем случае демон написан на PHP.

3 ответов


Я на самом деле работаю над что-то очень близко к тому, что вы описали, но в моем случае демон не опрашивает событие, которое он получает асинхронно через XMPP (но это помимо точки).

вырезать среднего человека

Я думаю, что вместо хранения событий в базе данных и опроса их с MySQL вы, вероятно, могли бы использовать Gearman отправлять их с клиента асинхронно (пример).

Вывоз Мусора

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

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

Стат Кэш

другое дело, что важно работать clearstatcache время от времени. Поскольку ваш процесс PHP не перезапущен, важно сделать этот вызов вручную, чтобы предотвратить получение старых данных stat (которые могут или может не повлиять на вас). Согласно документация эти функции кэшируются.

затронутые функции включают stat(), lstat(), file_exists(), is_writable(), is_readable(), is_executable(), is_file(), is_dir(), is_link(), filectime(), fileatime(), filemtime(), fileinode(), filegroup(), fileowner(), filesize(), filetype () и fileperms ().

управление ресурсами

Если вы собираетесь использовать вещь как MySQL во время жизни вашего процесса, я бы предложил сделать одно соединение при запуске и сохранить его в живых. Даже если он может использовать больше ОЗУ на стороне MySQL, вы вырежете некоторую задержку и накладные расходы процессора, не подключаясь каждые 1 секунду.

нет запроса URL

Это может показаться очевидным, но с cli PHP нет информации о запросе URL. Некоторые библиотеки не написаны с учетом этого, и это может вызвать некоторые проблемы.

LooPHP

Я собираюсь вытащить бесстыдный плагин здесь для фреймворка, который я написал, чтобы помочь с управлением демонами PHP. LooPHP - это структура цикла выполнения, которая позволяет запланировать событие или создать прослушивает абстрактные источники (сокет, поток и т. д.). В моем случае у меня есть демон, делающий более 1 вещи, поэтому очень полезно, чтобы система отслеживала все таймеры для меня, чтобы я мог эффективно опрашивать stream_select для на подключения по протоколу XMPP.


Если вы хотите сделать надежный демон, вам нужно будет поймать ошибки/разъединения базы данных и снова подключиться в любом случае (отключение или оставаться на связи). Поскольку вам все равно нужно это сделать, вы можете повторно использовать одно соединение.

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

Итак, я считаю, что самым чистым способом было бы сохранить соединение. Но едва-едва.


Я думаю, что лучшее, что вы могли бы сделать, это измерить время, необходимое для подключения/отключения К/из базы данных. Затем попробуйте придумать какую-то вероятность того, что сервер базы данных станет недоступным. Определить стоимость постоянного подключения к серверу. И, наконец, попробуйте определить стоимость (в часах, раздражение или что-то еще) добавления кода, который имеет дело с проблемами подключения к базе данных. Если вы можете успешно определить эти числа и сравнить их, у вас есть ответ. Он мне трудно (и я предполагаю, что кто-то) придумать хорошие догадки для этих значений, но вывод, вероятно, будет заключаться в том, что это выбор между производительностью и осуществимостью (с точки зрения более низкой стоимости).