Асинхронный обмен сообщениями в PHP / MySQL? - PullRequest
1 голос
/ 07 ноября 2011

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

  1. Самая простая реализация - позволить пользователям загружать файлы,затем индекс и эскиз, пока они ждут (медленная загрузка веб-страницы).Администратор может войти в систему, чтобы проиндексировать, а затем сделать миниатюру других файлов, которые были загружены вручную (медленная загрузка страницы, которая обновляется и может занять часы).

  2. Реализация, которую я сейчас имею, состоит в том, что пользовательские загрузки вызывают индексациюв то время как они ждут, а иногда (случайным образом) весь сайт индексируется в дополнение к обычной загрузке страницы (вызывает дополнительную предельную задержку для пользователя).Страницы на сайте ссылаются на URL, где должен быть эскиз, если он существует.Если пользователь запрашивает несуществующую миниатюру, он создается во время ожидания («ленивая миниатюра»).

Преимущество 2 состоит в том, что в многоядерной системе используются все ядра.Недостатком является то, что при первой загрузке страницы с новыми фотографиями требуется 30x50 МБ, а время ожидания страницы истекает, при этом некоторые изображения завершаются, а другие работают с нагрузками подзапроса.

ТАК ВОПРОС Как правильно реализовать обработку задач здесь?Бонусные баллы, если он масштабируется до нескольких серверов в общей базе данных.

Следует одна идея (может быть глупая) :

Я думал о создании таблицы заданий в БД:

id INT NOT NULL AUTO_INCREMENT, 
priority INT NOT NULL, 
worker INT, 
workstarted DATETIME, 
func CHAR(10) NOT NULL, 
args VARCHAR NOT NULL, 
PRIMARY KEY(id),
INDEX(priority),
UNIQUE(func,args) -- prevent duplicate jobs if user does F5

Затем, когда работа должна быть завершена, вставьте строку и создайте рабочий поток (если достаточное количество потоков еще не существует).Затем дождитесь ответа и продолжайте, если задание было успешно выполнено, или тайм-аут через 5 секунд.Если истекло время ожидания, используйте AJAX, чтобы передать контент пользователю, когда он будет доступен.

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

1 Ответ

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

Я предлагаю использовать ZeroMQ для вашей проблемы.

Это структура сокетов с привязками на нескольких языках (включая PHP). Вы можете разработать систему работников без использования базы данных и масштабировать работу по нескольким узлам (физические машины, которые выполняют эту работу).

Вот введение в 0MQ .

Вот документация с примерами PHP .

Вот руководство по 0MQ на github .

Субъективное мнение: просто потрясающе использовать 0MQ. Это невероятно быстро, и есть множество примеров в сочетании с отличным руководством.

...