2012-02-21 17 views
7

Bardzo częstą potrzebą aplikacji jest uruchamianie skryptu co X minuty/godziny. Zasadniczo to nic skomplikowanego, tylko trochę kodu PHP i wpisu crontab.Cronjob - jak to zrobić we właściwy sposób?

Mimo że napisałem sporo takich cronjobów w ostatnich latach, nadal nie widziałem żadnych dobrych praktyk, przynajmniej nie tak wiele. Podobnie jak w przypadku każdego "przetwarzania w tle", tak wiele rzeczy może pójść nie tak, zwłaszcza w ustawieniach produkcyjnych.

Wśród nich:

  • wystąpił błąd podczas wykonywania cron i skrypt zmarł przetwarzanie połowie danych
  • zadanie crona został przypadkowo rozpoczął dwukrotnie przez inny proces/błędu użytkownika/cokolwiek
  • zadanie crona wziął sposób dłużej niż oczekiwano i skrypt nazywa się ponownie, chociaż jej nie odbywa się przetwarzanie danych
  • itp

Jakie są najlepsze wskazówki do pisania solidnych, solidnych skryptów cronjob? Zapisanie pliku blokady potwierdzającego, że działa tylko jedna instancja, obszerne rejestrowanie i monitorowanie w celu uniknięcia wysłania dziesięciu tysięcy duplikatów wiadomości e-mail? Jakie są twoje pomysły?

+0

Interesujące, że opublikowałeś to, ponieważ badałem i zastanawiałem się nad niektórymi z tych samych rzeczy. W moim przypadku naprawdę martwię się, jak skutecznie zaimplementować obsługę wyjątków w pisanym przeze mnie skrypcie powłoki. http: // stackoverflow.com/questions/6961389/exception-handling-in-shell-scripting ma dobre informacje na ten temat, jeśli jesteś ciekawy. Jestem przede wszystkim programistą Java i obsługa wyjątków jest bardzo solidna, ale wydaje się trudniejsza w kraju * nix. –

+0

to będzie zależało od każdego uruchomionego skryptu, nie ma ogólnych odpowiedzi, niektóre potrzebują bardzo solidnego sprawdzania błędów, których niektóre nie potrzebują ... –

+0

Założęłem to pytanie w oczekiwaniu na innowacyjne odpowiedzi ze szczegółowym uzasadnieniem ich zalet i wad, i jestem bardzo rozczarowany odpowiedziami "Oto co robię". – nickb

Odpowiedz

2

Osobiście sposób, w jaki radzę sobie z błędami, to po prostu wysłać STDERR do pliku logu, a następnie okresowo sprawdzać ten plik. Łatwym sposobem na to jest dodanie 2>/pathtolog do wpisu crontab.

Jeśli chodzi o duplikaty tego samego programu, wolę, aby skrypt próbował zablokować coś (plik lub lokalny port sieciowy). Jeśli nie uda się uzyskać tej blokady, skrypt nie działa. W ten sposób, jeśli istniejący skrypt jest uruchomiony, nowy nie może uzyskać identycznego zamka.

0

Istnieje wiele rzeczy, które możesz zrobić.

Ustaw swoje skrypty cron/pliki binarne (skrypty, jak sądzę, ponieważ wspomniałeś, że są napisane w PHP) do wykonania przez właściciela lub grupę w zależności od Twoich potrzeb.

Jeśli chcesz się upewnić, że są wykonywane tylko przez crona, utwórz użytkownika cron, który jest jedynym użytkownikiem, który może wykonać skrypt. Następnie ustaw tego użytkownika, aby uruchomił go w swoim wpisie crontab.

W twoim wyjściu skryptu cron znaczące rzeczy, które robi. Przygotuj dane wyjściowe za pomocą znacznika czasu/datownika (w zależności od częstotliwości uruchamiania). Ułatwia to grep na określone czasy w pliku dziennika.

Dołącz stdout skryptu do pliku dziennika, dodając >> /path/cron.log do wpisu crontab.

Można także wyprowadzić czas rozpoczęcia i czas zakończenia cronów, aby można było analizować dziennik co jakiś czas, aby upewnić się, że proces nie jest zbyt wolny.

plik dziennika może wyglądać następująco:

[ Tue Feb 20, 2012 ]: 
[ Tue Feb 20, 2012 ]: Executing mycron.php 
[ Tue Feb 20, 2012 ]: 
[ Tue Feb 20, 2012 ]: Running Query: ""SELECT SUM(`clicks`) FROM `matable`"" 
[ Tue Feb 20, 2012 ]: Running Query: ""INSERT INTO `History` (`date`, `total_clicks`) VALUES(CURDATE(), 12324123) 
[ Tue Feb 20, 2012 ]: 
[ Tue Feb 20, 2012 ]: Finished executing mycron.php. Time taken: 3.462 seconds 
[ Tue Feb 21, 2012 ]: 
[ Tue Feb 21, 2012 ]: Executing mycron.php 
[ Tue Feb 21, 2012 ]: 
[ Tue Feb 21, 2012 ]: Running Query: ""SELECT SUM(`clicks`) FROM `matable`"" 
[ Tue Feb 21, 2012 ]: Running Query: ""INSERT INTO `History` (`date`, `total_clicks`) VALUES(CURDATE(), 10376123) 
[ Tue Feb 21, 2012 ]: 
[ Tue Feb 21, 2012 ]: Finished executing mycron.php. Time taken: 2.998 seconds 

wyjątkiem robi cokolwiek robi zamiast tych dwóch przypadkowych zapytań, oczywiście.

+0

Cronjob, aby sprawdzić dziennik z innych cronjob, ale co jeśli ten się nie powiedzie? –

Powiązane problemy