Bir PHP komut dosyası kısma için Öneriler / hileci

8 Cevap php

Ben düzenli olarak bir komut dosyası (her saat) çalışan bir zamanlanmış görev var. Bu script veritabanı ve dosya sistemi ile bazı ağır etkileşim yapar ve düzenli olarak çalıştırmak için birkaç dakika sürer. Sorun, sunucunun CPU kullanımı ani komut çalışırken ve normal işlemleri yavaşlatır. Uzun sürer ama çok kaynak tüketen değil ki bu işlem azaltmak için bir yolu var mı?

Ben PHP için farklı konfigürasyon seçenekleri baktım ama benim ihtiyaçlarına uygun herhangi olacaksa görünmüyor.

Alt şey php.ini içinde memory_limit ayarlama benim veri nesneleri oldukça kolay taşmasına neden olur.

Ben insanların komut belirli noktalarda () uyku kullanılmasını önerdi ama bu sunucuyu spike gelen komut engellemez benzer mesajlar gördüm.

Optimal çözüm% 10 max cpu kullanımını kullanmak yalnızca (bu durumda Wamp) yığın Lamba anlatmak için bir yol olacaktır. Ben de bütün çalışma zamanı hakkında endişeli değilim ve o saniyede cpu döngüsü tasarrufu demektir eğer uzun sürer tercih ederim. Cron aşağı her şeyi yavaşlama olmadan şehre gidebiliriz yüzden benim alternatif çözümü kurulum veritabanı çoğaltması ile farklı bir sunucu olacaktır.

Ortamı: Windows Server 2k3, Apache 2.2.11, PHP 5.2.9, MySQL 5.1

Ben bu duruma herhangi bir fikir takdir.

EDIT: Ben tüm cevapları, nix özgü * bile olanları takdir ediyorum. Bu barındırma ortamı değiştirmek için benim durum yeterince erken hala. Umarım bu soru ne olursa olsun işletim başkalarına yardımcı olacaktır.

8 Cevap

Bu zor bir sorundur. Eğer komut satırı üzerinden PHP komut dosyası çalıştırarak ediyorsanız, (start /low php.exe myscript.php inanıyorum) düşük, sürecin zamanlama önceliğini ayarlayabilirsiniz. PHP komut kendisi aslında CPU yiyor işleme en yapıyorsa, bu işe yarayabilir. Ancak, bu çözüm yardımcı olmaz bazı ağır veritabanı ve dosya sistemi etkileşim yapıyorsun, dedi. Orada size yardımcı olabilir INSERT ve UPDATE sorguları için MySQL ipucu "LOW_PRIORITY" var gibi görünüyor, ama ben bu denemedim.

You can set processes in Windows to be a lower priority. Ben süreci başladı ediliyor nasıl emin değilim, ama siz ayarlarsanız süreç gerçekten düşük olduğu öncelik ayarlarsanız CPU kaynakları onları alacak istediğini, düşük öncelikli olmak.

Eğer kullanarak komut başlatmak için cron giriş değiştirebilir nice?

Not a good idea müşterilerine hizmet için bir sunucu kullanmak ve verileri analiz etmek.

Yani nihai bir çözüm arıyorsanız, uygulamanın bir kaç yeniden tasarımını yapmak ve bu göreve adanmış bir başka sisteme Frontenflerin ve canlı veritabanından veri analizi boşaltması.

Başarıyla analizörü kısma bile, bu kullanıcılara hizmet aksi durumda mevcut olacaktır değerli kaynaklarını kullanmak istiyorsunuz.

UNIX (LAMP) Ben döngü devam etmeden önce sunucu yükü kontrol ederek sorunu çözmek için başardı

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);
	}
}

Bu fonksiyon pencerelerde de çalışır ama bunu garanti edemez. Linux üzerinde size son 1 dakika, 5 dakika ve 15 dakika yük ile bir dizi geri verir

Ayrıca, (Linux, "güzel" kullanın) (CLI tarafından ise) daha düşük bir öncelik ile komut başlatmak için düşünün

Ayrıca (eğer httpd.conf MOD_STATUS etkin eğer sayfa 127.0.0.1/server_status? Oto ayrıştırmak) Apache etkin işlemlerin sayısı gibi, döngü devam etmeden önce diğer değerleri kullanmak, ya da MySQL durum (Etkin bağlantıları olabilir ?)

Bu zor bir değişiklik olabilir ama buna değer Yineleyicilerin içine veri yapıları üstlenmeden olabilir. Ayrıca, sizin kod dairesel referanslar varsa, bu nesneleri seçeneği kaldırır clearReferences gibi bir yöntemi () sağlar. Bu arada PHP 5.3 ile çözülecek bir sorundur.

Eğer var ise:

class Row
{
    protected $_table;

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

class Table
{
    protected $_row;

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

: Bir clearReferences (Satır sınıfa) yöntemi ekle

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

Ben şu an için gelip hepsi bu.

Ben güzel kullanarak benzer bir şekilde cron çalıştırmak komut bir grup var:

0 **** güzel-n19 php myscript.php

Bu, (sadece o yapabilir komut yazılır biçimini değiştirerek) RAM kullanımını yardımcı olmaz, ama sadece başka türlü boşta olacak CPU kullanır.

EDIT: soru üzgünüm ... aynı sorunu olan herhangi bir * nix kullanıcıları için bu bırakarak, bir Windows ortamına dahil olduğunu görmedim ..

Belki de ne script basitçe, bir kerede çok fazla hepsini yapmaya çalışıyor. Üç kez bir saat koştum eğer az yapmak istiyorsunuz?

Başka bir çözüm kurulum için sadece backend 'işleme bu tür çalışan için ek bir sunucu olabilir. Bu, veritabanında sadece web sunucusu aşırı yük koyarak değilse bu özellikle etkili olur.

Bakmak için başka bir yaklaşım işi farklı bir yöne ayrılabilir var olup olmadığıdır. Dizelerin Bu tür genellikle küçük SQL tabloların bir sürü oluşturmak için kullanılan sonuçlar üretmek birkaç büyük SQL ifadeleri var. Ikincisi yere bir kenara koymak olabilir, bunlar bir sonraki adım olarak veritabanı karşı çalıştırılabilir. Böyle bir yaklaşım, aynı zamanda PHP kodu tarafından bellek tüketimi önemli ölçüde kısmak olabilir ön-işleme veri getirmek için bir tampon sorgu kullanmasına izin olabilir.