Нужно сделать паузу между выполнением скрипта

Discussion in 'PHP' started by wmFest123, 20 Aug 2013.

  1. wmFest123

    wmFest123 Banned

    Joined:
    31 Aug 2011
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0
    раньше было так:
    PHP:
    $tm time();
    if (
    $tm file_get_contents("time.txt") <= 3) {
        exit();
    }
    file_put_contents("time.txt"$tm);

    в целях оптимизации изменил так:
    PHP:
     $mytime apache_getenv("mytime");
    if (
    $mytime && $tm $mytime <= 3) {
        exit();
    }
    apache_setenv("mytime"$tm);
    будет ли настолько же надежно? и будет ли это оптимизированнее?
    этот код должен сделать возможным выполнение скрипта не чаще 1 раза в 3 секунды

    ЗЫ: походу setenv не то. тогда как посоветуете решить задачу наименее ресурсозатратно?
     
    #1 wmFest123, 20 Aug 2013
    Last edited: 20 Aug 2013
  2. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    http://php.net/manual/ru/function.sleep.php ???
     
    _________________________
  3. wmFest123

    wmFest123 Banned

    Joined:
    31 Aug 2011
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0
    нет, вы не так поняли. не во время выполнения скрипта сделать паузу, а между запросами
     
  4. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    Между какими запросами?

    file_get_contents("http://ya.ru");
    sleep(10);
    file_get_contents("http://ya.ru");

    ^ пауза между запросами 10 секунд...
     
    _________________________
  5. FunOfGun

    FunOfGun Elder - Старейшина

    Joined:
    5 Sep 2012
    Messages:
    388
    Likes Received:
    72
    Reputations:
    124
    2Gar|k, ТСу нужна гарантия, что между двумя запусками его скрипта пройдет не меньше 3 секунд
     
  6. wmFest123

    wmFest123 Banned

    Joined:
    31 Aug 2011
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0
    FunOfGun, верно
     
  7. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    wmFest123 ваш первый вариант не надежен. Атомарность проверки и изменения - не гарантируется.

    Зачем вам вообще это понадобилось? Скорее всего просто ваш подход сам по себе не верен.
     
    _________________________
  8. wmFest123

    wmFest123 Banned

    Joined:
    31 Aug 2011
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0
    Gifts, да, атомарности нет. можно решить с помощью flock думаю.
    суть в том, что на скрипт постоянно идет много запросов. по 1-5 в секунду.
    а скрипт выполняет сложный запрос в большую бд. запрос этот секунды 3 выполняется.
    таким образом если пытаться обработать всех, то будет ддос. таким образом нужно распределить так, чтобы в 1 момент времени только 1 запрос в бд обрабатывался, остальным же выдавалось "обратитесь позже"
     
  9. barnaki

    barnaki Elder - Старейшина

    Joined:
    2 Nov 2008
    Messages:
    676
    Likes Received:
    140
    Reputations:
    4
    Так задержка будет только для этого выполнения. все кто будет выполнять скрипт точно так же будут начинать запрос. скорее всего вам нужна какая то временая переменая в базе которая будет проверятся при начале запроса . и обнулятся после его выполнения. так же советую explain запроса и попробывать оптимизировать
     
  10. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    wmFest123, ну блин вспомни тему синхронизации потоков - критические секции, мьютексы, семафоры.

    А так же тему блокировки таблиц в БД - http://habrahabr.ru/post/46542/

    По поводу мьютексов, аналогом может быть блокирование файлов - http://php.net/manual/ru/function.flock.php.
     
    _________________________
  11. wmFest123

    wmFest123 Banned

    Joined:
    31 Aug 2011
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0
    barnaki, так ведь начинать то будут, но сразу их будет обрывать командой exit(). в скрипте тот код, что я привел идет первыми строчками. таким образом запросов на скрипт будет действительно много, но все они будут отсекаться, не дойдя до тяжеловесного кода.

    Gar|k, да, так и есть - верно подмечено насчет синхронизации. в общем сделаю так:
    PHP:
    // атомарность за счет flock, аналог крит секций
    $fp fopen("cr_sec""r+");
    flock($fpLOCK_EX);
    $tm time(); 
    if (
    $tm file_get_contents("time.txt") <= 3) {
        
    // дабы избежать дедлока (хотя его и так не будет, ибо видимо блокировка снимается при выходе из скрипта)
        
    flock($fpLOCK_UN);
        
    fclose($fp);
        exit(); 

    file_put_contents("time.txt"$tm);
    flock($fpLOCK_UN);
    fclose($fp);
     
  12. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    2 wmFest123, ну а вообще Gifts правильно сказал - если у тебя возникает такая ситуация возможно ты неверно подошел к проблеме.

    http://habrahabr.ru/post/41968/ - оптимизация mySQL запросов
    про различие InnoDB и MyISAM в прошлой статье хорошо описывалось (ссылку давал), так же там в комментариях дельные советы по оптимизации, например "если поле часто обновляется - стоит вынести его в другую таблицу".

    Интерфейс mysqli вроде как быстрей чем устаревший mysql http://php.net/manual/ru/mysqli.multi-query.php - выполнение сразу нескольких запросов за один запрос.
     
    _________________________
  13. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    С вашим кодом тоже будет dos, или вы не понимаете, что надпись - обратитесь позже - тоже отказ в обслуживании?

    Откройте для себя кеширование, благо с мемкешедом пхп умеет работать. Ну или если хочется извращений используйте для синхронизации бд. Одиночный апдейт - атомарен плюс используйте функцию _affected_rows, чтобы узнать, что запрос прошел

    И вообще - 3 секунды на запрос - это Вы сортировку пузырьком что ли сделали на базе.
     
    _________________________
  14. wmFest123

    wmFest123 Banned

    Joined:
    31 Aug 2011
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0
    ага, это все понятно насчет оптимизации. но у меня скрипт обновляет бд в 100 тысяч записей. клиент шлет запрос, какие строки обновить.
    >> или вы не понимаете, что надпись - обратитесь позже - тоже отказ в обслуживании?
    в моем случае нет. к скрипту будут обращаться не люди, а другие скрипты, и если они получают надпись обратитесь позже, обращаются позже. упор тут именно на обновление бд, а не работу с клиентами
    >> http://habrahabr.ru/post/41968/
    ага, спасибо, статью уже читал.

    оптимизация это все хорошо, но в моем случае нужно обрабатывать огромную бд тяжелыми запросами в обновление по 1к строк за раз, и никак иначе не представляется возможным.
    поэтому делать это раз в 3 секунды - вполне разумно в моем случае.
    и собственно вопрос то мой не в том, как бы мне оптимизировать скрипт - он как ни крути будет несколько секунд делаться, а в том как наиболее оптимизированно эту проверку на "раз в 3 секунды" сделать
     
    #14 wmFest123, 23 Aug 2013
    Last edited by a moderator: 24 Aug 2013
  15. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    опять общей картины не имею... но допустим есть скрипт update.php есть скрипт init.php который долбит нечто типа system("php update.php") или file_get_contents("http://site.ru/update.php");
    тогда получается так

    $res=false;
    while($res != true) { $res=(bool)file_get_contents("...update.php"); sleep(3); }

    в update если файл заблокирован - возвращаем exit('0'); если запрос прошел успешно и данные обновились exit('1');
     
    _________________________
  16. wmFest123

    wmFest123 Banned

    Joined:
    31 Aug 2011
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0
    ну да, как-то так. только еще скрипт init.php не один, а их много
     
  17. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    In memory table http://dev.mysql.com/doc/refman/5.0/en/memory-storage-engine.html

    И код типа следующего:

    PHP:
    $conn->query('REPLACE table SET curtime=time() WHERE curative <= time() - 3*60 AND id=1');
    if (
    $conn->affected_rows == 0) die('Come later');

    Other code
    Сорри, что сообщение испортил
     
    _________________________
    #17 Gifts, 24 Aug 2013
    Last edited: 24 Aug 2013
  18. wmFest123

    wmFest123 Banned

    Joined:
    31 Aug 2011
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0
    хорошее решение, спасибо. работа с памятью будет оптимизированнее, чем с файлом