문제

정기적으로 스크립트를 실행하는 예정된 작업이 있습니다 (매 시간마다). 이 스크립트는 데이터베이스 및 파일 시스템과 크게 상호 작용하며 정기적으로 실행하는 데 몇 분이 걸립니다. 문제는 스크립트가 실행되는 동안 서버의 CPU 사용이 급증하고 정상 작업을 속도로 느리게한다는 것입니다. 이 프로세스가 더 오래 걸리지 만 자원을 많이 소비하지 않도록 스로틀을 스로틀하는 방법이 있습니까?

PHP에 대한 다양한 구성 옵션을 살펴 보았지만 내 요구에 맞는 것은없는 것으로 보입니다.

php.ini의 memory_limit를 더 낮은 것으로 설정하면 내 데이터 객체가 오버플로가 매우 쉽게 넘쳐납니다.

스크립트의 특정 지점에서 사람들이 Sleep ()를 사용하는 유사한 게시물을 보았지만 스크립트가 서버를 스파이크하는 것을 방해하지는 않습니다.

최적의 솔루션은 램프 (이 경우 WAMP) 스택을 10% 최대 CPU 사용 만 사용하도록 지시하는 방법입니다. 나는 런타임에 대해 전혀 걱정하지 않으며 초당 CPU 사이클을 저장하는 경우 더 오래 걸리는 것을 선호합니다. 대체 솔루션은 데이터베이스 복제를 사용하여 다른 서버를 설정하여 CRON이 다른 모든 것을 늦추지 않고 마을로 갈 수 있도록하는 것입니다.

환경 : Windows Server 2K3, Apache 2.2.11, PHP 5.2.9, MySQL 5.1

이 상황에 대한 통찰력에 감사드립니다.

편집하다: 나는 모든 답, 심지어 *nix에 따른 답변에 감사합니다. 내 상황에서 호스팅 환경을 바꿀만큼 여전히 초기입니다. 이 질문이 OS에 관계없이 다른 사람들에게 도움이되기를 바랍니다.

도움이 되었습니까?

해결책

이것은 까다로운 문제입니다. 명령 줄을 통해 PHP 스크립트를 실행하는 경우 프로세스의 스케줄링 우선 순위를 LOW로 설정할 수 있습니다 (start /low php.exe myscript.php 나는 믿는다). PHP 스크립트 자체가 실제로 CPU를 섭취하는 대부분의 처리를 수행하는 경우 효과가있을 수 있습니다. 그러나이 솔루션은 도움이되지 않는 몇 가지 무거운 데이터베이스 및 파일 시스템 상호 작용을하고 있다고 말했습니다. 삽입 및 업데이트 쿼리를위한 MySQL 힌트 "Low_Priority"가있는 것처럼 보이지만 시도하지는 않았습니다.

다른 팁

Windows의 프로세스를 최우선 과제로 설정할 수 있습니다. 프로세스가 어떻게 시작되는지 잘 모르겠지만 프로세스가 우선 순위가 낮다고 설정하면 우선 순위를 실제로 낮게 설정하면 CPU 리소스가 원하는 것이 무엇이든 얻을 수 있습니다.

~ 안에 유닉스 (램프) 루프를 계속하기 전에 서버의 부하를 확인하여 문제를 해결했습니다.

function get_server_load($windows = 0) {
    $os = strtolower(PHP_OS);
    if(strpos($os, "win") === false) {
        if(file_exists("/proc/loadavg")) {
         $load = file_get_contents("/proc/loadavg");
         $load = explode(' ', $load);
         return $load;
        }
        elseif(function_exists("shell_exec")) {
         $load = explode(' ', `uptime`);
         return $load;
        }
        else {
         return "";
        }
    }
}

for(... ... ...){
    $data = get_server_load(); 
    if($data[0] < 0.2){
     // continue
    }else{
        sleep(1);
    }
}

이 기능은 Windows에서도 작동하지만 보장 할 수는 없습니다. Linux에서는 마지막 1 분, 5 분, 15 분의 하중으로 배열을 다시 제공합니다.

또한 우선 순위가 낮은 스크립트 (CLI에 의해)를 시작하는 것을 고려하십시오 (Linux에서는 "nice"를 사용).

Apache 활성 프로세스 수와 같이 루프를 계속하기 전에 다른 값을 사용할 수도 있습니다 (httpd.conf에서 mod_status를 활성화 한 경우 127.0.0.1/server_status?auto 페이지를 구문 분석 할 수 있습니다. ?)

CRON 항목을 변경하여 사용하여 스크립트를 시작할 수 있습니까? 멋진?

좋은 생각이 아닙니다 클라이언트에 서비스를 제공하고 데이터를 분석하기 위해 서버를 사용합니다.

따라서 최종 솔루션을 찾고 있다면 애플리케이션을 몇 가지 재 설계하고 Frontends 및 Live 데이터베이스 에서이 작업 전용 다른 시스템으로 데이터 분석을 오프로드하십시오.

분석기를 성공적으로 스로틀 할 수 있더라도 소중한 리소스를 사용하여 사용자에게 서비스를 제공 할 수 있습니다.

이것은 어려운 변화 일지 모르지만 데이터 구조를 반복자로 리팩토링 할 가치가 있습니다. 또한 코드에 원형 참조가있는 경우 이러한 개체를 해제하는 ClearReferences ()와 같은 메소드를 제공하십시오. 그런데 PHP 5.3에서 해결되는 문제입니다.

그래서 당신이 가지고 있다면 :

class Row
{
    protected $_table;

    public function __construct($table)
    {
        $this->_table = $table;
    }
}

class Table
{
    protected $_row;

    public function __construct()
    {
        $this->_row = new Row($this);
    }
}

행 클래스에 ClearReferences () 메소드를 추가하십시오.

class Row
{
    public function clearReferences()
    {
        $this->_table = null;
    }
}

그게 내가 지금 생각 해낼 수있는 전부입니다.

Cron에서 실행하는 스크립트가 니스를 사용하여 비슷한 방식으로 있습니다.

0 * * * * nice -n19 php myscript.php

이것은 RAM 이용에 도움이되지는 않지만 (스크립트가 작성되는 방식 만 변경하면 그렇게 할 수 있습니다), 그렇지 않으면 유휴 상태 인 CPU 만 사용합니다.

편집 :이 질문에 Windows 환경이 포함 된 것을 보지 못했습니다. 죄송합니다 ... 동일한 문제가있는 *닉스 사용자에게 이것을 남겨두고 있습니다.

아마도 스크립트가 단순히 한 번에 너무 많은 일을하려고하는 것일 것입니다. 한 시간에 세 번 실행되면 더 적게할까요?

또 다른 솔루션은 이러한 종류의 '백엔드'처리를 실행하기위한 추가 서버를 설정하는 것일 수 있습니다. 이것은 데이터베이스에 과도한로드를하지 않으면 웹 서버만으로도 효과적입니다.

그러나 또 다른 접근 방식은 작업이 다른 방향으로 나눌 수 있는지 여부입니다. 이러한 종류의 스크립트에는 종종 작은 SQL 문을 생성하는 데 사용되는 결과를 생성하는 몇 가지 큰 SQL 문이 있습니다. 후자가 어딘가에 제쳐 놓을 수 있다면 나중에 데이터베이스에 대해 실행할 수 있습니다. 이러한 접근 방식을 사용하면 Unfuflered Query를 사용하여 PHP 코드에 의해 메모리 소비를 크게 줄일 수있는 사전 처리 데이터를 가져올 수 있습니다.

서비스로 실행중인 경우 (Apache)가있는 경우 Win Control Center /Services에서 우선 순위 설정을 변경할 수 있습니다. CPU 사용량은 어쨌든 급등하지만 다른 프로그램은 스케줄러가 선호합니다. 또한 데이터베이스/서버를 응용 프로그램과 다른 HD에 배치하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top