리눅스 Crontab(크론탭) 초단위로 실행하기 위한 꼼수 공개
이번 프로젝트에서는 초단위로 시세 API 를 호출해서 DB에 시세 데이터를 넣어야 하는 일이 생겼습니다.
뭐 생각나는것이라곤 크론탭(Crontab) 밖에 없었습니다.
하지만 크론탭은 최소 분단위까지만 허용이 됩니다.
그래서 결국 데몬 프로그램을 만들수 밖에 없었습니다.
데몬 프로그램 소스코드는 대략 아래와 같습니다.
_cron_start.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | while(TRUE) { $sql = "SELECT value FROM cb_config WHERE name = 'cron_start'"; $result = mysql_query($sql); $cron_start = mysql_fetch_assoc($result); $cron_start = $cron_start['value']; if($cron_start == "ok") { include "_cron.php"; sleep(20); } else { break; } } | cs |
데몬은 php 로 작성하였으며, DB에 특정값이 "ok" 가 떨어질 동안 20초 간격으로 계속 _cron.php 파일을 실행합니다.
_cron.php 파일안에 초단위 시세 API 를 수집하는 프로그램이 작동중입니다.
여기까지 제작을 하고, 욕심이 더 생겼습니다.
관리자 페이지에서 이 데몬을 ON/OFF 를 제어하고 싶었습니다.
그래서 웹 관리자 페이지에 특정 버튼을 누르면 아래와 같이 exec 로 위 데몬을 작동하게끔 하였습니다.
exec('crontab _cron_start.php');
뭐 작동은 잘됩니다.
버튼 하나로 제가 만든 데몬이 실행되는 것이지요.
다만 문제가 발생했습니다.
데몬 소스가 조건절에 의한 무한루프 소스다보니, 관리자페이지에서 데몬을 실행하면, 관리자 페이지가 뻗어버리는 증상이 발생했습니다.
데몬이 돌아가는 메모리를 고스란히 웹관리자가 먹는것 같았습니다.
그래서 고민한 끝에 한가지 꼼수를 생각해냈습니다.
크론탭으로 데몬을 실행하고, 크론탭을 바로 지워버리면? 데몬을 실행하는건 크론탭이기 때문에 웹관리자가 영향을 안 받지 않을까?
결과는 성공적이었습니다.
크론탭 실행은 아래와 같습니다.
_cron_script.php 파일
* * * * * php /home/proejct/_cron_start.php
1분에 1번 데몬을 실행하는 크론탭 명령을 _cron_script.php 파일에 넣어뒀습니다.
그리고 exec 를 다시 수정했습니다.
exec('crontab _cron_script.php');
정상적으로 웹관리자는 뻗지않고, _cron_start.php 다 실행이 됨이 확인되었습니다.(DB에 데이터가 잘 들어감이 확인)
자 이제 마지막으로 crontab 을 제거해 줘야 합니다.
_cron_start.php 파일
exec("crontab -r");
위와같이 크론을 바로 제거해 줌으로써, 데몬소스가 한번만 실행되고 종료가 되게 하였습니다.
실행된 데몬 소스는 한번만 실행되었지만, while 안에서 조건문에 걸리지 않는 이상 20초마다 수집프로그램을 가동시킵니다.
하루동안 삽질해서 얻은 결과였습니다.
순서 정리합니다.
1. 웹관리자에서 크론실행버튼 클릭
2. exec('crontab _cron_script.php'); 으로 _cron_script.php 크론이 실행됨. 크론명령어(* * * * * php /home/proejct/_cron_start.php)
3. 데몬파일이 실행됨. - _cron_start.php
4. 데몬파일안에서 크론명령을 지움. - exec("crontab -r");
5. 데몬이 설정된 초단위만큼 주기적으로 데이터 수집을 함.
개발은 꼼수다.