![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 71 Pomógł: 1 Dołączył: 14.12.2004 Ostrzeżenie: (0%) ![]() ![]() |
Witam,
Mam skrypt do wysylki mailingu. Baza maili moich uzytkownikow liczy ponad 22 tysiace, wiec radze sobie tak: set_time_limit(300); pobierz 80 maili sposrod tych do ktorych jeszcze nie wyslano jezeli sa maile to w petli wyslij i zapisz, ze wyslano sleep(3); header(odswiezenie strony) jezeli nie ma juz maili header(strona glowna wysylki mailingu) I problem tkwi w tym, ze zawsze po ok 3 minutach (+/- 200 sekund) wywala mi w przegladarce: Kod Nieprawidłowe przekierowanie Firefox wykrył, że serwer przekierowuje żądanie tego zasobu w sposób uniemożliwiający jego ukończenie. Czy po przekierowaniu header czas wykonania skryptu nie liczony jest na nowo? |
|
|
![]()
Post
#2
|
|
![]() Grupa: Zarejestrowani Postów: 2 885 Pomógł: 463 Dołączył: 3.10.2009 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
Pokaż kod, zgaduję, że robisz przekierowanie do tego samego skryptu z tymi samymi warunkami, tym samym masz nieskończoną pętlę, a właściwie "zapętloną" logikę.
-------------------- Nie pomagam na pw, tylko forum.
|
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 71 Pomógł: 1 Dołączył: 14.12.2004 Ostrzeżenie: (0%) ![]() ![]() |
Skrypt jest przydlugawy,
ale jest jak mowisz, do tej samej strony z tymi samymi parametrami przekierowuje... 200 sekund dziala, ale jak zrobic zeby dzialalo tak dlugo dopoki nie wysle wszystkiego? jak zwiekszyc ten czas? |
|
|
![]()
Post
#4
|
|
![]() Grupa: Zarejestrowani Postów: 2 885 Pomógł: 463 Dołączył: 3.10.2009 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
set_time_limit ($nowy_czas_w_sekundach)
lub ini_set("max_execution_time", $nowy_czas_w_sekundach); Ten post edytował darko 5.12.2009, 16:11:21 -------------------- Nie pomagam na pw, tylko forum.
|
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 71 Pomógł: 1 Dołączył: 14.12.2004 Ostrzeżenie: (0%) ![]() ![]() |
wczesniej mialem
set_time_limit(600); ale nie dzialalo ustawilem set_time_limit(600); ini_set("max_execution_time", 600); ale pech chcial, ze zostalo na tyle malo maili do wysylki, ze zmiescily sie w ok 100 sekund... Przetestuje przy nastepnej wysylce, mam nadzieje ze pomoze ![]() Dzieki EDIT: niestety nadal to samo, ma ktos jakis inny pomysl? Ten post edytował andycole 18.12.2009, 00:23:30 |
|
|
![]()
Post
#6
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Ja robię to w sposób "oflagowany". Wybieram sobie pewną zmienną, którą traktuję jako flagę. Przykładowo może to być data ostatniego wysłania newslettera, ale może to być inny typ flagi. Z datą jest chyba jednak najbezpieczniej.
Zapytanie wyciąga paczkę rekordów, które mają ją niższą niż aktualna (ważne data w postaci rok-miesiąc-dzień, a nie timestamp) i ustawia im ją na aktualną oraz przetwarza, po czym wywołuje skrypt główny (oczywiście robię sleepa, by nie zajechać serwera i bazy). Gdy skrypt wykryje brak rekordów do przetworzenia - kończy działanie. Najważniejsze jest zapytanie. To ono decyduje, czy Twój skrypt będzie nieskończoną pętlą, czy nie. Dlatego musi za każdym razem modyfikować datę wysyłki ostatniego newslettera, nawet jeśli nic nie posłał bo brak było danych dla tego usera do posłania. Może i maila nie posłało, ale zmiana nastąpić musi, bo inaczej w puli zawsze Ci będą zostawały osoby ze starszą datą niż aktualna i skrypt się zapętli. Ten post edytował thek 18.12.2009, 09:49:54 -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#7
|
|
![]() Grupa: Zarejestrowani Postów: 1 590 Pomógł: 185 Dołączył: 19.04.2006 Skąd: Gdańsk Ostrzeżenie: (0%) ![]() ![]() |
A po co jakiś header, sleep itp. Nie prościej użyć crona? Prawie każdy hosting daje choćby protezę do uruchamiania skryptów PHP wg harmonogramu. Ustawiasz sobie, żeby skrypt się odpalał np. co 15 minut, wysyłał określoną ilość maili a do bazy trafia raport z wysyłki i tyle. Robienie tego w ten sposób to dla mnie amatorska prowizorka i strata czasu (w dodatku na większości hostingów są limity długości wykonywania się skryptów, a tutaj nawet przeglądarka się buntuje), w PA powinieneś tylko ustawić treść maila, do kogo ma być wysłany i np. o której godzinie rozpoczynasz wysyłkę. Potem przeglądasz logi i sprawdzasz, czy wysyłka postępuje bez przeszkód, ja tak np. wysyłam SMSy i nie wyobrażam sobie robić tego inaczej.
|
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 71 Pomógł: 1 Dołączył: 14.12.2004 Ostrzeżenie: (0%) ![]() ![]() |
Dzieki za konkretne odpowiedzi.
Co do flag, zamiast daty ja po prostu mam tabele w ktorej zapisuje numer_listu | numer_wysylki i pozniej wybierajac maile przy nastepnej iteracji wybieram te, ktorych nie ma w ww tabeli. Co do crona... Pilsner, jak z poziomu PHP wrzucic skrypt do crona zeby wykonywal sie co X minut? |
|
|
![]()
Post
#9
|
|
![]() Grupa: Zarejestrowani Postów: 1 590 Pomógł: 185 Dołączył: 19.04.2006 Skąd: Gdańsk Ostrzeżenie: (0%) ![]() ![]() |
Wszystko zależy od tego, czy Twój hosting daje Ci taką możliwość a potem oczywiście od tego, w jaki sposób zapewnia obsługę tego. Jeśli Twój hosting nie daje takiej możliwości możesz przygotować protezę i wywoływać co określony czas skrypt zdalnie przez protokół http. Możesz do tego użyć darmowego hostingu z obsługą crona, ale pewniej oczywiście walczyć o to na swoim hostingu. Więcej o cronie poczytasz w necie, jest masa artykułów, choćby tutaj:
http://pl.wikipedia.org/wiki/Crontab |
|
|
![]()
Post
#10
|
|
Grupa: Zarejestrowani Postów: 71 Pomógł: 1 Dołączył: 14.12.2004 Ostrzeżenie: (0%) ![]() ![]() |
Mam VPS'a,
|
|
|
![]()
Post
#11
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Pilsener... Pogadaj sobie o Cronie w sytuacji gdy masz limit skryptu 30 sekund + możliwość odpalania co 5 minut + setki tysięcy maili. Jeśli w ciągu 24h wyślesz wszystkim generowany indywidualnie mail to gratuluję
![]() 200*12(razy w ciągu godziny)*24(godziny)~=57.000 maili na dobę ![]() Jak Ty chcesz ominąć ten problem przy wysyłce choćby 60.000 maili? ![]() 1. Uruchamiasz skrypt co 5 minut niezależnie czy są zadania do zrobienia czy nie, mój odpala się raz i leci do upadłego. 2. Nie masz pewności czy posłało wszystkie maile, a w moim wypadku nawet jeśli serwer padł w trakcie wysyłki, to następnej nocy skrypt i tak "nadrobi" zaległości automatycznie. bez ingerencji z mojej strony. Dodatkowo mogę go odpalać ręcznie z przeglądarki i zamknąć ją bez obawy o zatrzymanie skryptu ( poczytaj nieco to znajdziesz o ignore user abort ) 3. Nie muszę ingerować w nic. A nawet jeśli obciążenie serwera będzie na tyle ogromne i skrypt zakończy się z powodu limitu czasu to śmiało wznawiam go kiedy chcę. Jest tak napisany, że podejmie pracę od miejsca przerwania. Czy zrobię to ręcznie czy napiszę w cronie by "na wszelki wypadek" robił to co X godzin jest nieistotne, bo nie wykona się jeśli nie ma nic do zrobienia. Potęga algorytmu nad prostym wklepaniem do harmonogramu: "Wykonuj co 5 minut". Bo wykonywanie skryptu z odstępem 20 sekund przez Y minut na serwerze z limitem czasu skrypty 30 sekund i cronem co 5 minut to zauważalny skok wydajności. Ty zrobisz 200 maili w cronie, a ja około 3000 w skrypcie. Widzisz różnicę czy nadal uważasz rozwiązanie za "prowizoryczną amatorszczyznę"? Ja znam tylko jeden serwis z cronem co minutę. Znasz jakiś, który posłałby kilkaset tysięcy generowanych indywidualnie maili (treść jest generowana na podstawie konfiguracji ustawianych przez usera z poziomu jego panelu newslettera) z cronem co 5 minut i limitem skryptu 30 sekund? To jest matematycznie niemożliwe do wykonania co Ci udowodniłem ciut wyżej w podliczeniu. Które podejście nadal uważasz za sensowniejsze? EDIT: Brak crona w przypadku serwisu też nie jest problemem. Ty proponujesz zdalne uruchamianie skryptu co ileś tam. Jest sens tego? Nie lepiej odpalić skrypt "raz a porządnie"? Ten post edytował thek 18.12.2009, 13:22:55 -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#12
|
|
![]() Grupa: Zarejestrowani Postów: 1 590 Pomógł: 185 Dołączył: 19.04.2006 Skąd: Gdańsk Ostrzeżenie: (0%) ![]() ![]() |
Ale przecież sam napisałeś
Cytat masz limit skryptu 30 sekund , więc jak odpalisz skrypt "raz a dobrze"? Przecież z pierwszego postu jasno wynika, że kolega stosuje ten sam mechanizm, lecz w inny sposób: porcjuje i odświeża bawiąc się w sleep i header, czym się to różni od użycia do tego celu crona? A jak połączenie z przeglądarką zostanie zawieszone czy zresetowane albo któryś etap wysyłki nie powiedzie się? Jak ponownie wywołasz skrypt? A jak jakiś błąd wyskoczy? Chyba, że czegoś nie rozumiem tutaj? Mówisz, że wyślę nie za dużo tych maili a czy ja muszę się ograniczać do uruchomienia tylko jednego skryptu? Mogę ich przecież odpalić równolegle nawet 100, wszystko zależy od moich potrzeb i możliwości serwera.Co do pozostałych uwag to na to jest także lekarstwo, bo wysyłkę łatwo zaprojektować tak, że maile będą wysyłane aż do skutku lub komunikatu błędu, nie widzę także przeszkód by zmodyfikować plik crontaba po zakończeniu wysyłki tak, aby już nie uruchamiał się co 5 minut. Samo 5 minut także jest przykładowe i zależy od naszych potrzeb/możliwości, dzielimy pracę na etapy by ją usprawnić a nie utrudnić. Za bardzo zbaczamy w stronę możliwości/konfiguracji serwera i szczegółów algorytmu, to, w jaki sposób skrypt realizuję samo wysyłanie ma tutaj imo znaczenie drugorzędne. Chodzi o sam fakt uruchomienia wysyłki w tle a tutaj moim zdaniem cron jest lepszym rozwiązaniem niż bawienie się w sleep + header - to rozwiązanie zastępcze i prowizoryczne, nie wyobrażam sobie za bardzo praktycznego podpięcia w PA tego i uruchomienia sprzężenia zwrotnego, jednak nie chcę brnąć dalej w dyskusję na temat wad/zalet takiej protezy, kiedyś eksperymentowałem ze sleep a nawet autorefreshem w JS, jednak gdy zacząłem korzystać z crona nie wyobrażam sobie inaczej i tak mi zawsze radzili bardziej doświadczeni koledzy. |
|
|
![]()
Post
#13
|
|
Grupa: Zarejestrowani Postów: 71 Pomógł: 1 Dołączył: 14.12.2004 Ostrzeżenie: (0%) ![]() ![]() |
Dajcie juz spokoj
![]() thek, powiedz mi lepiej jak przekierowanie dokladnie robisz, bo w tym lezy u mnie problem :/ |
|
|
![]()
Post
#14
|
|
![]() Grupa: Zarejestrowani Postów: 2 885 Pomógł: 463 Dołączył: 3.10.2009 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
Zawsze możesz zrobić jeszcze tak:
1. sprawdzić ile maili "poleciało" do przekroczenia czasu wykonania skryptu 2. wyciągać rekordy limit $start, $limit_ile_polcecialo - 10 (dla pewności można odjąć jeszcze więcej) W ten sposób etapowo, "na raty" można to wykonać. Rozwiązanie bardzo dalekie od ideału, ale przynajmniej nie musisz kombinować z cron Ten post edytował darko 19.12.2009, 03:06:17 -------------------- Nie pomagam na pw, tylko forum.
|
|
|
![]()
Post
#15
|
|
Grupa: Zarejestrowani Postów: 71 Pomógł: 1 Dołączył: 14.12.2004 Ostrzeżenie: (0%) ![]() ![]() |
1. sprawdzić ile maili "poleciało" do przekroczenia czasu wykonania skryptu Moglbys to szerzej wyjasnic bo niebardzo rozumiem? Jak pobierac rekordy to ja wiem, ale chodzi mi bardziej o sposob przekierowania, zeby bylo tak, ze po 1 kliknieciu maile wysylaja sie do skutku. Tak zebym nie musial co jakis czas znowu odswiezac strony ![]() A czy ten problem z czasem moze byc spowodowany przez firefoxa? ![]() |
|
|
![]()
Post
#16
|
|
![]() Grupa: Zarejestrowani Postów: 41 Pomógł: 9 Dołączył: 8.02.2009 Ostrzeżenie: (0%) ![]() ![]() |
A czy ten problem z czasem moze byc spowodowany przez firefoxa? ![]() Firefox wykrywa kiedy przekierowujesz stronę w nieskończoność (Przynajmniej w jej mniemaniu ![]() Nie wiem jak zadziała dodanie zmiennej typu get która by się zmieniała. Kiedy czytałem wasze wypowiedzi na temat crona czy przekierowań tkneła mnie myśl żeby wykorzystać technologię AJAX. Najpierw użytkownik przesyła dane formularzem do skryptu. Ten zapisuje treść maila do bazy danych i osoby do których należy wysłać. Wczytana strona zawiera w JavaScripcie informacje o ilości maili do wysłania i asynchronicznie wywołuje skrypt na serwerze który wysyła maile przez czas trochę krótszy od maksymalnego i zwraca liczbę wysłanych maili. Oczywiście osoby do których już wysłano zostały by usunięte z bazy danych. Oprawił bym to w ładny pasek postępu i elegancki przycisk anuluj ;P |
|
|
![]()
Post
#17
|
|
Grupa: Zarejestrowani Postów: 44 Pomógł: 5 Dołączył: 29.06.2005 Ostrzeżenie: (0%) ![]() ![]() |
Pamiętaj tylko że mailing takiej ilości wiadomości może zostać potraktowany przez serwery pocztowe jako SPAM, a wtedy cała praca jest bezcelowa.
-------------------- Kacper Szurek <--- http://www.kacka.pl
|
|
|
![]()
Post
#18
|
|
Grupa: Zarejestrowani Postów: 71 Pomógł: 1 Dołączył: 14.12.2004 Ostrzeżenie: (0%) ![]() ![]() |
|
|
|
![]()
Post
#19
|
|
![]() Grupa: Zarejestrowani Postów: 41 Pomógł: 9 Dołączył: 8.02.2009 Ostrzeżenie: (0%) ![]() ![]() |
|
|
|
![]()
Post
#20
|
|
![]() Grupa: Zarejestrowani Postów: 6 Pomógł: 1 Dołączył: 28.05.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Przeglądarki blokują powtarzające się polecenia przekierowania, po pierwsze aby uchronić klienta przed "wędrowaniem" po wielu stronach i zbieraniem różnego rodzaju śmieci (cookiesów), a także przed wpadnięciem w nieskończoną pętlę. Zamiast funkcji header po stronie serwera może użyj meta tagu w kodzie odpowiedzi:
Skrypt może wstawiać ten tag do nagłówka html'a tak długo, aż zostaną wysłane wszystkie maile. Można też użyć ajax, który będzie w pętli wywoływał skrypt tak długo, jak długo zwraca pewną ustaloną wartość: po wysłaniu wszystkich maili skrypt zwróci pusty tekst jako odpowiedź i pętla zostanie przerwana. Zaletą ajaksowego rozwiązania jest brak migotania strony w oknie przeglądarki i możliwość zrobienia ładnego, w pełni funkcjonalnego paska postępu (wykorzystaj jQuery). Załączam gotowca (efekt prokrastynacji, czyli poniedziałkowej niechęci do zaplanowanej pracy ![]() Aby sprawdzić działanie wystarczy: 1. umieścić na serwerze dwa pliki: sendmail.php i mailing.html (źródła poniżej), 2. do podkatalogu js wrzucić bibliotekę jQuery http://docs.jquery.com/Downloading_jQuery 3. utworzyć w bazie danych przykładową tabelę:
i wypełnić ją danymi, lub dodać pole `status` ENUM ('waiting','sent') do swojej tabeli. Skrypt działający "w tle", realizujący wysyłanie maili partiami, zwracający do klianta informacje o procentowym postępie, lub zakończeniu wysyłki, nazwa skryptu sendmail.php
Frontend dla klienta: nazwa pliku np. mailing.html (oczywiście może być wygenerowany przez php)
Ten post edytował za017 21.12.2009, 12:10:25 -------------------- Marcin
Moje ulubione: Linux; Apache + PHP + MySQL + jQuery; Java + Tomcat + Spring + Postgresql i oczywiście Eclipse + Subversion |
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 13.08.2025 - 22:15 |