exec ('command args>/log/file &');을 사용하는 PHP 스크립트가 있습니다. 루프 내에서 동시에 실행되는 여러 하위 스크립트를 만들 수 있습니다. 기본적으로 상위 스크립트는 데이터베이스에서 사용자 정보를 가져와 병렬로 실행되는 하위 스크립트를 만든 다음 하위 스크립트는 단일 사용자에게 보낼 전자 메일을 만듭니다. 이것은 약 50,000 번 발생합니다.PHP에서 exec는 자동으로 많은 exec 명령을 호출 할 때 실패하지만 나중에 동일한 명령을 실행하면 나중에 작동합니다.
동시에 실행중인 프로세스를 50,000 개 생성하지 않으려면 현재 실행중인 프로세스를 추적하는 데이터베이스 테이블이 있고 새 프로세스를 만들기 전에 부모 프로세스는 현재 자식 수를 확인하고 현재 25 명의 자식이 활성 상태 인 경우 절전 모드가됩니다. 자식은 작업을 완료하면 테이블에서 행을 삭제하여 부모가 더 많은 자식을 만들 수있게합니다.
문제는 약 10 %의 exec 명령이 자동으로 실패하고 겉으로보기에는 아무 이유도없는 것입니다. 상위 스크립트를 다시 실행할 수 있습니다 (동일한 사용자를 두 번 이메일하지 않는 것이 현명합니다). 그리고 마지막으로 실패한 동일한 exec 명령을 사용하여 90 %의 시간이 다시 작동합니다. 스크립트를 5 ~ 6 번 연속 실행하면 모든 사람에게 이메일을 보냅니다.
임원 직후에 잠을 둠으로써 성공률을 약 95 %까지 높일 수 있습니다.
왜 같은 명령이 나중에 작동하면 exec가 실패할까요? 완료 될 때까지 스크립트를 반복해서 보관할 수는 있지만 exec 문제를 해결하는 편이 낫습니다.
일부 매우 단순화 된 예제 코드 :부모 스크립트 :
do {
//get user, group, and supergroup information for users that haven't
//been emailed yet
foreach ($users as $userArray) {
$processId = insertIntoProcessQueue($userArray);
$cmd = 'sudo php -q ./childScript.php ' . cliArg($userArray) . ' ' .
cliArg($groupArray) . ' ' . cliArg($supergroupArray)
' ' . $proccessId . ' > file.log &';
exec($cmd);
do {
if (numChildren() >= 25) {
sleep(1);
$waiting = true;
}
} while ($waiting);
}
$incomplete = moreUsersToEmail() > 0 ? true : false;
} while ($incomplete);
function cliArg($array) {
return escapeshellarg(json_encode($arg));
}
아이 스크립트 : 스크립트가 완료 될 때
ignore_user_abort(true);
$user = json_decode($argv[1]);
$group = json_decode($argv[2]);
$supergroup = json_decode($argv[3]);
print_r($user);
$email = createEmail($user, $group, $supergroup);
$email->sendEmail();
removeFromProcessQueue($argv[4]);
flush();
exit;
는에서 print_r은 로그 파일에 표시됩니다 I 절대 오류가 발생하지 않으므로 실패 이유에 대한 데이터를 얻을 수 없습니다. 이를 추가하기 위해 모든 사용자가 일관되게 실패하지 않으며 한 번에 한 명의 사용자 만 실행할 수 있으므로 모든 사람을 통해 스크립트를 실행하고 45,000 개의 오류를 잡아야합니다. 제대로 작동합니다. 그리고 부모와 자식은 부모를 넘어서서는 결코 의사 소통을 할 수 없으므로 자식이 실패 할 때 (부모로부터) 발견 할 수 없습니다 (그렇지 않으면 부모에게 재실행하는 대신 실패한 자식을 다시 시도하고 시작할 수 있습니다.).
편집 : 따라서 동적으로 생성 된 스크립트가 사용되며 (사용 이유를 묻지 않습니다.) 스크립트가 생겨난 프로세스를 병렬로 실행하면서 경쟁 조건을 만듭니다. 실패.
불행히도 시간을 낭비 해 주셔서 감사합니다.
'exec '의 반환 값을 확인하려고 했습니까? – Dave
(네트워크를 병목 현상으로 처리하기 때문에 루프를 건너 뛰어도 프로세스가 복잡해집니다.) – Dave
호스트의 메일 시스템에 너무 많은 것을 넣었습니까? 한 번에? 스레드 수를 2와 같이 매우 정상적인 값으로 낮추면 사망률이 여전히 높습니까? –