Cron işleri PHP ile çoklu iş parçacığı simultate için kullanılabilir mi?

3 Cevap php

Ben 1000 + kayıtları ile dolu bir MySQL veritabanı tablo var, 5000 kayıtları Diyelim ki. Her kayıt false (0) bir processed boolean bayrak, varsayılan vardır. Ne yapmak istiyorum cron'nun bir PHP komut dosyası çalıştırmak her dakika olması. Onun kodu böyle bir şey olacaktır:

<?php
process();

function process()
{
   $sql = "SELECT id FROM items WHERE processed = '0' ORDER BY id ASC LIMIT 1";
   $result = $this->db->query($sql);

   if (! $result->has_rows())
     die;

   $id = $result->getSingle('id');
   processItem($id); //Will set processed to 1 after processing is done
   process();
}
?>

Bu yukarıdaki kod, un işlenmiş olan bir sonraki kayıt için id alır bunu işler ve daha sonra artık kalmayana kadar bu işlemi tekrarlar tekrar hangi process() işlevini çağırır, ne çok açık olmalıdır yürütme durdurmak hangi noktada işlenecek öğeler.

Her dakika çalıştırmak için Cron'un bu senaryoyu koyarak, ben bu komut birden çok örneği aynı anda tüm öğeleri işleme çalışan, bu yüzden yerine bir defada tek bir öğe işleme için umut, 5-10 + öğeler aynı anda işleme almak olabilir.

1) Bu onu planlıyorum yol çalışması olacak mı? Dikkat etmeniz gereken iyileştirmeler / şeyler için herhangi bir öneriniz var mı?

2) Ben komut dosyası örneklerini çalışan sayısı için bir sayaç set var, bu yüzden bir cron işi başlar her 50 (?) Örnekleri bu işlem olmadan çıkmak istiyorum çalışıyorsa, bu, sayacı kontrol eder mi. Bu çok fazla bellek kullanan çok sayıda çalışan süreçleri alarak çökmesini sunucu tutabilir? Herhangi bir düşünce?

3 Cevap

Söyleyecek bir kaç şey var:

Öncelikle Birden fazla satır işlemek için özyineleme kullanıyor. Çok derin özyineleme bu sorunlara yol açabilir. Bunun yerine, basit bir döngü kullanmak.

Bu kod birden çok kez yürütülüyor yararlanabilir İkincisi, biliyor musunuz? Makine ise CPU başka bir iş parçacığı yarar olmayabilir bağlı. Ben birçok konuları en iyi nasıl çalışır elle kontrol etmenizi öneririz. Daha konuları her zaman işler daha hızlı yapmaz ve bazı durumlarda aslında her şeyi yavaşlatabilir.

Son olarak, ben kesinlikle aynı anda çalıştırabilirsiniz kaç Bu komut bir sınır koymak istiyorsunuz. Bu, her komut dosyası 5 dakika demek daha uzun süre çalışırsa sağlanarak basitçe elde edilebilir. Yoksa aktif komut sayısını tutmak ve bu benim ikinci öneri belirlenen maksimum sayıda gitmez sağlayabilirsiniz.

Edit: I've added some more information about the problem recursion can cause: Each time you recursively call a function extra space is used up on the stack. This space stores any local variables as well as the address of the function (allowing it to restore the state when the called function exits). The stack only has a finite amount of space so eventually your program will crash with a stack overflow. Try running this simple program:

function a($i) { 
   print $i . "\n"; 
   a($i + 1);
}
a(0);

Benim sistemde bu 608.739 tekrarlamadan sonra PHP çöker. Bu sayı, daha karmaşık bir fonksiyonu olarak bir çok daha küçük olabilir. Basit bir döngü bu nedenle bu sorun yok bu giderleri yoktur.

Yineleme tüm gerekli görünmüyor, ve bramp dediği gibi, sorunlara yol açabilir. Neden sadece

$sql = "SELECT id FROM items WHERE processed = '0' ORDER BY id ASC LIMIT 1";

while ( ($result = $this->db->query($sql) && $result->has_rows() ) {
   processItem( $result->getSingle('id') );
}

However, burada büyük sorunlar öngörüyoruz. Eğer bu komut dosyasını her dakika çalışıyor olacak iseniz, hala çalışıyor olabilir, daha önce yürütülen komut dosyalarını çalıştırmak durdurmak için yerinde hangi mekanizma var? Sen birden fazla kez aynı kimliği işleme sona erebilir.

Kesinlikle bir (sözde) çok dişli bir yaklaşım gerektirir, ben şu öneririm:

  1. , Bir seferde sadece tek bir dizi ya da işlenmemiş kimlikleri bütün tut.
  2. Fonksiyonların curl_multi_ ailesini kullanarak, gerçek işlem yapmak için başka bir komut için yukarıdaki sonuçları (n id yıllardan grupları) alt kümelerini geçmektedir.

Bu yöntem, tüm süreç üzerinde daha fazla kontrol sahibi olmanızı sağlar ve işlenmemiş kimlikleri almak için gereksiz tek sorgulama önler.

Ben tam olarak aynı sorunu çözmek için bir proje başlattı. Bu sürekli bir komut dosyasını çalıştırmak ve yüksek talep varsa paralel olarak daha fazla örneğini çalıştırabilirsiniz. Yapacak bir şey yok ise, o zaman komut dosyası bir örneğini çalıştırmadan önce, belirli bir aralığı bekleyecek.

Eğer ilgileniyorsanız sonra bazı kullanım durumları ile okuma var: www.4pmp.com/fatcontroller/