- Поисковые системы
- Практика оптимизации
- Трафик для сайтов
- Монетизация сайтов
- Сайтостроение
- Социальный Маркетинг
- Общение профессионалов
- Биржа и продажа
- Финансовые объявления
- Работа на постоянной основе
- Сайты - покупка, продажа
- Соцсети: страницы, группы, приложения
- Сайты без доменов
- Трафик, тизерная и баннерная реклама
- Продажа, оценка, регистрация доменов
- Ссылки - обмен, покупка, продажа
- Программы и скрипты
- Размещение статей
- Инфопродукты
- Прочие цифровые товары
- Работа и услуги для вебмастера
- Оптимизация, продвижение и аудит
- Ведение рекламных кампаний
- Услуги в области SMM
- Программирование
- Администрирование серверов и сайтов
- Прокси, ВПН, анонимайзеры, IP
- Платное обучение, вебинары
- Регистрация в каталогах
- Копирайтинг, переводы
- Дизайн
- Usability: консультации и аудит
- Изготовление сайтов
- Наполнение сайтов
- Прочие услуги
- Не про работу
Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий
Есть скрипт парсера, структура примерно такая
Лимит 20 подобран примерно чтобы успеть с гарантией отработать за минуту. Скрипт запускается по крону раз в минуту. Но чтобы еще себя обезопасить от дублей я всем выбранным записям ставлю SET `sid` = '2' чтобы если вдруг скрипт все же будет выполняться более 1 минуты следующий заход по крону не запросил опять эти же данные.
В итоге я получаю более 20% данных в таблице в которых пустые поля и `sid` = '2' и я не могу объяснить как такое может произойти.
Т.е. скрипт начал выполняться, запись получила `sid` = '2' но до конца до строки
тут в самом низу запрос на UPDATE `table` и там же SET `sid` = '1'
почему-то работа не дошла.
Причем если заново взять и тем записям у которых в базе остался `sid` = '2' поставить `sid` = '0' и заново по ним пройтись - то опять 80-90% из них обработает нормально. Т.е. проблема не в конкретных записях, косяк где-то в логике, но я не могу понять где?
В нормальных условиях ставят файл-локер, который проверяет, отработал ли предыдущий скрипт и, если отработал и файла нет, то запускается, а если он есть - то не запускается. А эти вот "гарантированно вложиться в минуту" - никакой гарантии не дают. Зачем себя так мучать то?
А можно подробнее про локер, как это делается? А то я говнокодер новичок, что пришло первое в голову то и реализовал
А можно подробнее про локер, как это делается? А то я говнокодер новичок, что пришло первое в голову то и реализовал
Ну уж точно не новичок )
При старте скрипта проверяется, есть ли в наличие файл-локер, любое имя, в любом удобном месте. Просто пустой файл, главное - это его наличие или отсутствие. Если он уже есть, то запуск скрипта не производится, банальный die(). Если же файла нет, то сначала создается этот файл-локер и дальше запускается скрипт. Когда скрипт закончил свое выполнение, то файл-локер просто удаляется. Таким образом две копии одного скрипта не будут запущены одновременно. И не нужно городить огороды.
Скрипт - это маркер, что предыдущая копия этого скрипта еще не отработала, т.е. этот запуск требуется пропустить.
--
Есть файл? -> Нет -> Создать файл -> Работа скрипта -> Удалить файл
Есть файл? -> Да -> Выход
зачем пачками парсить?
парсим по одному разу.
скрипт отвалился. а где у вас set_time_limit, ignore_user_abort?
файл локер нужно от крвого крона кторый может запустится не раз как вы предположили а 2 или даже 3
Локер подойдет да, правда иногда бывают неточности с одновременными блокировками, но это не про ваш случай, с такой частотой вызовов вероятность мала.
Помню писал скрипт, к которому 20-30 человек обращаются практически одновременно, так как скрипт не в режиме демона, то на каждый запрос по процессу. Первые несколько запросов стабильно выполнялись одновременно. Решил проблему созданием локера-переменной в Memcached, отрабатывает в 100% случаев правильно (веду журналы). Будь это поточный демон, конечно бы использовал мьютексы.
Что касается темы разговора, очень важно чтобы скрипт вел журнал.
Напишите простой класс логгера, который просто будет записывать время и описывать событие, записывать значение переменных, которые у вас теряются, выделите самые важные места в программе и добавьте туда журналирование. Пожалуй, это самое первое с чего нужно начинать любую программу. Иначе можно годы гадать на кофейной гуще и приделывать костыли.
При старте скрипта проверяется, есть ли в наличие файл-локер, любое имя, в любом удобном месте. Просто пустой файл, главное - это его наличие или отсутствие. Если он уже есть, то запуск скрипта не производится, банальный die().
На самом деле надо в файл-локер писать pid запустившего его процесса.
При новом запуске считываем из локера pid и проверяем существует ли этот процесс. Если да, то умираем. А если нет - то запускаемся и перетираем локер.
файл-локер
Вот это реально велосипед 😀 я когда в 2000 начинал сайты делать и то лучше способ был. А сейчас есть паттерн singleton один экземпляр класса и не надо никакого файла-локера 😁
Хороший способ положить сервис совсем :)
На самом деле надо в файл-локер писать pid запустившего его процесса.
При новом запуске считываем из локера pid и проверяем существует ли этот процесс. Если да, то умираем. А если нет - то запускаемся и перетираем локер.
Нельзя юзать PID, об этом написано в мануале:
https://www.php.net/manual/ru/function.getmypid.php
Вот это реально велосипед 😀 я когда в 2000 начинал сайты делать и то лучше способ был. А сейчас есть паттерн singleton один экземпляр класса и не надо никакого файла-локера 😁
Вместо хвастовства, ТС-у бы ответили на его вопрос.
Если проблема именно в блокировке и в том, что скрипт запускается в нескольких экземплярах из-за крона, то поставьте на сервере flock
и запускайте скрипты примерно так:
*/1 * * * * /usr/bin/flock -n /tmp/ert.textphp.lockfile /usr/bin/php /path/to/file/test.php
Flock будет сам отпускать локфайл, когда скрипт завершится. Это несколько лучше, чем внутренний для скрипта обработчик локеров.