#php #mysql #cron #cpanel #server-load
#php #mysql #cron #cpanel #загрузка сервера
Вопрос:
Я надеюсь, что смогу получить несколько советов.
В моей системе PHP / MySQL есть бухгалтерские книги со счетами, которые периодически появляются в книге (для этого примера, скажем, раз в месяц). У меня также есть плата за просрочку, которую необходимо взимать после определенной даты. Дата «проводки» счета-фактуры, а также дата «это поздно» уже находятся в базе данных.
Мне интересно, какой метод лучше для запуска моего скрипта, который автоматически применяет элемент книги учета (раз в месяц) — и автоматически вводит плату за просрочку (также будет раз в месяц, если необходимо). Для всех пользователей системы эти даты разные — и, как я уже сказал, все они хранятся в БД. Мои варианты, на мой взгляд, следующие:
-
Есть задание CRON, которое выполняется один раз в день (т. Е. в 12: 00 каждый день) — и просматривает каждый элемент, выполняя работу, если соблюдены условия даты.
Я думаю, мне нравится этот метод, потому что он заботится обо всем сразу, в одно и то же время каждый день.
Я беспокоюсь об этом методе, потому что: (1) что, если мой сервер не работает, когда было запланировано мое задание CRON, теперь CPANEL полностью пропускает этот день? И (2) если у меня есть 100 тысяч или даже 100 миллионов записей для просеивания, будет ли это невыносимой нагрузкой на мой сервер всякий раз, когда это выполняется?
-
Вызывайте этот скрипт для «выполнения работы», если выполнены условия даты, только при входе соответствующего пользователя в систему.
Причина, по которой мне не так нравится этот метод, заключается в том, что становится все сложнее определить, сколько счетов-фактур нужно выставлять и сколько штрафов за просрочку платежа применять. Кроме того, у меня есть пользователь «администратор», который может видеть ВСЕ от ВСЕХ — у этого пользователя может быть не актуальная информация о бухгалтерской книге, если арендатор недостаточно недавно вошел в систему…
Причина, по которой мне нравится этот метод, заключается в том, что он, очевидно, обеспечивает меньшую нагрузку на сервер…
Возможно, я слишком много думаю. Не уверен… но совет был бы очень признателен. Спасибо.
Комментарии:
1. Что, если пользователь не будет входить в вашу систему в течение года — вы не будете отправлять ему счет?
2. Если вы делаете это ежедневно, вы действительно ожидаете, что у вас будет объем в 100 миллионов строк, которые нуждаются в обновлении? Для вашего второго случая я бы рекомендовал сделать 2 вещи. 1. Вычисление результатов, когда администратор видит конкретного пользователя. 2. Если у вас есть какая-либо статистика на странице, дайте администратору кнопку для синхронизации данных. Теперь, поскольку пользователи могут никогда не вернуться и поскольку ваш администратор может быть ленивым. Вы можете попробовать комбинацию обоих ваших методов. P.S. Насколько я знаю, если cronjob завершится неудачей. Это «пропущено».
3. @zerkms — Хотя я понимаю вашу точку зрения, факт в том, что я все еще хочу, чтобы код был в конечном итоге надежным … и прошло 2-3 месяца, прежде чем всерьез заняться сбором денег, что является обычным делом… @Khez — Я не буду обновлять 100 миллионов строк, но мне придется ПРОВЕРИТЬ 100 миллионов строк…
Ответ №1:
Я думаю, что лучше всего использовать вкладку cron для всех преимуществ, которые вы упомянули. Я бы добавил к этому, однако, что если вы используете таблицу, защищенную от транзакций, такую как INNODB, и регистрируете завершение работы вкладки cron, то в случае сбоя таблицы во время работы crontab изменения будут отменены, и вы можете проверить журнал, чтобы увидеть, в какие даты происходили сбои, чтобы вы могли вручную внести изменения. Фактически, если вы регистрируете завершение задачи crontab в таблице, вы можете использовать этот журнал (фиксируя, сколько дней назад скрипт запускался в последний раз) для автоматической обработки пропущенных дней.
Что касается загрузки сервера, у вас, вероятно, не возникнет особых проблем с одновременным обновлением многих записей. Дело в том, что при правильно структурированном запросе вы должны обновлять (или вставлять) только на основе записей, дата которых соответствует выбранным вами параметрам. На самом деле вам не нужно перебирать каждую запись в БД.
Комментарии:
1. что вы подразумеваете под таблицей «безопасности транзакций»? Я НЕ использовал
INNODB
, потому чтоmyisam
, насколько я понимаю, лучше для «тонны чтений»… (в моем решении намного больше операций чтения, чем записи). Далее мне все равно нужно будет перебирать каждую запись для проверки дат, верно? Я не могу уйти от этого. Конечно, мне нужно обновлять только там, где выполняются условия.
Ответ №2:
Я думаю, что задание cron — хорошая идея. Однако в любом случае вы, вероятно, захотите каким-то образом помечать элементы (строки?) как «обработанные». Ваше задание cron должно искать «необработанные» данные, а не по дате. Это, ИМХО, безопаснее и решит проблему, если задание по какой-либо причине не удастся выполнить.
У меня есть похожая функция в одном из моих приложений. Однако это больше похоже на стиль очереди. Задача ставится в очередь из любой части приложения. Рабочий (может быть запущен через cron) проходит через очередь, завершает задачу и помечает ее как «обработка», а затем обрабатывается. Если приходит следующий рабочий и обнаруживает задачу «обработка», он проверяет рабочего, чтобы убедиться, что это не зомби. Если это так, это отключает его, а затем перезапускает задачу. и т.д. и т.п. и т.п.
На самом деле у меня есть одна главная очередь, которая может содержать различные типы задач (уведомления по электронной почте, обновления файлов и т.д.), Затем рабочий обрабатывает главную очередь в очереди для конкретных заданий (одна для электронной почты и т.д.).