2013-06-03 13 views
13

Ustawiłem kolejki w Laravel dla moich skryptów przetwarzania. Używam beanstalkd i superword. Istnieje 6 różnych rurek dla różnych rodzajów przetwarzania.Kolejki Artisan Laravel - użycie wysokiego cpu

Kwestia polega na tym, że dla każdej tuby rzemieślnik stale spawa pracowników co sekundę. Kod roboczy wydaje się spać przez 1 sekundę, a następnie wątek roboczy używa 7-15% procesora, pomnożyć to przez 6 lamp ... i chciałbym mieć wielu pracowników na probówkę .. mój procesor jest zjedzony.

Próbowałem zmienić 1 sekundę snu na 10 sekund. Pomaga to, ale wciąż istnieje ogromny skok procesora co 10 sekund, gdy pracownicy budzą się z powrotem. W tej chwili nie przetwarzam niczego, ponieważ kolejki są całkowicie puste, to po prostu pracownicy szukają czegoś do zrobienia.

Sprawdziłem także, czy użycie procesora laravel zostało odświeżone, gdy odświeżałem stronę w folderze, a było to około 10%. Znajduję się teraz na niskim poziomie instancji rackspace, co może wyjaśnić, ale wciąż ... Wydaje się, że pracownicy za każdym razem, gdy się budzą, uruchamiają instancję laravel.

Czy nie ma sposobu na rozwiązanie tego problemu? Czy muszę po prostu wpłacić dużo pieniędzy na droższy serwer, żeby móc posłuchać, czy praca jest gotowa?

EDIT:

znalazł rozwiązanie ... to było nie używać kolejki rzemieślnik: słuchacza lub kolejki: Prace zajrzałem do kodu kolejki i nie wydaje się być sposób wokół tego problemu wymaga ładowania za każdym razem, gdy pracownik sprawdza, czy jest więcej pracy do wykonania.

Zamiast tego napisałem własnego słuchacza, używając pheanstalk. Nadal używam programu laravel do przesyłania rzeczy do kolejki, a następnie niestandardowy program nasłuchujący analizuje dane kolejki, a następnie uruchamia polecenie rzemieślnika.

Teraz moje użycie procesora dla moich słuchaczy jest poniżej% 0, jedyny czas, w którym mój procesor strzela teraz, to kiedy faktycznie znajduje pracę do zrobienia, a następnie uruchamia polecenie, nic z tego.

+9

Czy mógłbyś podzielić się swoim kodem z niestandardowym słuchaczem? Mam ten sam problem. – greatwitenorth

+0

Jestem również zainteresowany, aby zobaczyć Twojego niestandardowego słuchacza! –

+0

Chciałbym również zobaczyć twoje rozwiązanie. –

Odpowiedz

5

Miałem ten sam problem.

Ale znalazłem inne rozwiązanie. Użyłem rzemieślnika tak jak jest, ale zmodyfikowałem czas "oglądania". Domyślnie (z laravel) ten czas jest zakodowany na zero, zmieniłem tę wartość na 600 (sekundy). Zobacz plik: 'vendor/laravel/framework/src/Illuminate/Kolejki/BeanstalkdQueue.php' i funkcji 'public function pop ($ kolejka = null)'

Więc teraz praca jest również słuchanie kolejka na 10 minut. Gdy nie ma pracy, kończy pracę, a przełożony ponownie ją uruchamia. Po otrzymaniu zadania wykonuje ją po tym, jak już istnieje, a przełożony ponownie go uruchamia.

==> Brak odpytywania!

Uwagi:

  • to nie działa dla iron.io kolejce lub innych.
  • może nie działać, jeśli chcesz, aby 1 pracownik akceptował zadania z więcej niż jednej kolejki.
+1

Rozwiązanie, które opublikowałem na moim pierwszym blogu, działa jak na razie doskonale. Pomyślałem o modyfikacji pliku, który powiedziałeś, ale wolałbym nie modyfikować plików dostawców/rdzenia, szczególnie, że nie zatwierdzam tych katalogów, jest to część mojego procesu budowania, aby dynamicznie generować te katalogi na serwerze na żywo. Dzięki za pomoc! – bsparacino

+1

Uważam, że jest to najlepsze rozwiązanie pod względem wydajności. Nowe zatwierdzenie w Laravel, które dodaje parametr uśpienia, jest nieco problematyczne, ponieważ podczas procesu snu nie będzie szukać żadnych nowych zadań. Zauważyłem również, że nadal ma pewne problemy z wykorzystaniem procesora. Powyższe rozwiązanie zmniejszyło procesor do 1%, a także stale sprawdza miejsca pracy. – greatwitenorth

+1

@greatwitenorth, czy mógłbyś coś zrobić, aby poprawić swoją reputację tutaj na SO? dzięki. – karelv

2

Według tego commit można teraz ustawić nową opcję queue:listen "--sleep={int}" który pozwoli Ci dostosować ile czasu oczekiwania przed odpytywania nowych miejsc pracy.
Domyślnie ustawiono na 3 zamiast 1.

+0

W dokumentacji nie ma nawet jasności co do tego, co właściwie robi ten "sen". Czy spanie raz na początku, a następnie rozpoczyna się polling (szybko)? Powinien spać tak długo między każdą ankietą? Czy śpi tylko wtedy, gdy nie znalazła wiadomości podczas odpytywania? W moich 5.1 próbach mogę powiedzieć, że nie jest to żaden z powyższych, więc jaki jest jego cel, całkowicie mi umyka. – Jason

+0

Odpowiedziałeś na własne pytanie: śpi między każdą ankietą i tylko wtedy, gdy nie znaleziono wiadomości, jak powiedział w http://laravel.com/docs/5.1/queues. To dla mnie bardzo jasne :) czy w swoich testach używasz synchronizacji jako trybu kolejki? – younes0

+0

"liczba sekund oczekiwania przed sondowaniem dla nowych zadań" - być może jest to dla mnie niejednoznaczne sformułowanie. Liczba sekund oczekiwania * między każdą próbą podczas odpytywania * będzie bardziej wyraźna. "przed odpytywaniem" to czas pomiędzy rozpoczęciem procesu a uruchomieniem pętli odpytywania, a * wydaje się, że * jest tym, co zostało zaimplementowane. W każdym razie, nie widziałem opcji uśpienia działającej na L5.1 - sondowanie przebiega pełną prędkością bez zastosowania okresu snu. – Jason

11

Problem wysokiego CPU jest spowodowany, ponieważ pracownik ładuje kompletną strukturę za każdym razem, gdy sprawdza pracę w kolejce. W laravel 4.2 możesz użyć php artisan queue:work --daemon. Spowoduje to załadowanie struktury jeden raz i sprawdzenie/przetworzenie zadań nastąpi wewnątrz pętli while, która pozwoli procesorowi na łatwe oddychanie. Więcej informacji na temat pracownika demona można znaleźć w oficjalnej dokumentacji: http://laravel.com/docs/queues#daemon-queue-worker.

Jednak ta korzyść ma swoją wadę - podczas wdrażania kodu należy zachować szczególną ostrożność i należy dbać o połączenia z bazą danych. Zwykle długie połączenia z bazą danych są odłączone.

+1

dzięki za aktualizację. dobrze wiedzieć, że w końcu to popierają. Używam beanstalkd od ponad roku i jest wspaniale, musiałem dbać o połączenia z bazami danych, o czym wspomniałeś. – bsparacino

+0

Tak, oficjalnie zalecamy uruchomienie 'DB :: reconnect()' przed przetworzeniem każdego zadania, aby upewnić się, że połączenie jest dostępne. Metoda 'reconnect()' rozłącza już ustanowione połączenie i łączy je ponownie. – MohitMamoria

+0

Tak, właśnie to robię, działa świetnie – bsparacino

Powiązane problemy