Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [MySQL][PHP]Php mail() - limit wiadomości na serwerze
darney
post
Post #1





Grupa: Zarejestrowani
Postów: 124
Pomógł: 0
Dołączył: 21.08.2010
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


Witam. Posiadam swoją grupę mailingową. Z chwilą jej wielkości kiedy dobiłem do ponad 150 pojawił się problem z wysyłaniem hurtem jednej wiadomości. Na serwerze jest limit 100 maili na godzinę. Jak przebudować skrypt aby przygotował paczki odbiorców. 100 maili do jednej części osób i kolejne 100 do drugiej. Chciał bym także po wykonaniu skryptu nie martwić się już nim i zamknąć okno po ukazaniu się komunikatu o powodzeniu operacji. Czy jest to możliwe ?.

Mój skrypt to stary przebudowany książkowy.
  1. while ($row = mysqli_fetch_array($result)){
  2. $to = $row['mailer_email'];
  3. $mailer_imie = $row['mailer_imie'];
  4. $mailer_nazwisko = $row['mailer_nazwisko'];
  5. $msg = "Drogi $mailer_imie $mailer_nazwisko,\n$text";
  6. $from = 'From: "xxx@xxx.pl" <xxx@xxx.pl>' . PHP_EOL .
  7. //'Cc: "CC Display Name" <xxx@xxx.pl>' . PHP_EOL .
  8. 'X-Mailer: PHP-' . phpversion() . PHP_EOL;
  9. $from .= "Content-type: text/html; charset=utf-8\n";
  10. //$from .= "Content-Transfer-Encoding: 8bit\n";
  11.  
  12. mail($to, $subject, $txt_mail, $from);
  13. echo 'Wysłano wiadomość pod adres: ' . $to . '<br />';
  14.  
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 19)
Wilu88
post
Post #2





Grupa: Zarejestrowani
Postów: 158
Pomógł: 6
Dołączył: 7.03.2010

Ostrzeżenie: (0%)
-----


Sam właśnie piszę taki moduł do swojego cms'a i jedyne wg mnie sensowne wyjście to:

1. Przy tworzeniu nowej wiadomości stworzyć tabele w której zapiszesz oczekujące na wysyłkę maile w tabeli znajdzie się id maila z listy mailingowej oraz id wiadomości która będzie zapisana w innej tabeli.

Następnie w cronie napisać skrypt wykonujący się co godzinę a w nim:

pętla powiedzmy 50 przebiegową (w razie czego) która z tabeli oczekującej na wysyłkę pobierze maila i wiadomość wyśle ją a następnie usunie ten rekord jeśli pójdzie wszystko w porządku.

To mój pomysł może ktoś ma inny
Go to the top of the page
+Quote Post
peter13135
post
Post #3





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

Ostrzeżenie: (0%)
-----


można ewentualnie zamiast crona użyć wejścia userów na stronę i sprawdzać po dacie.
Go to the top of the page
+Quote Post
thek
post
Post #4





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Też kiedyś się zmagałem z tym problemem i rozwiązalem podobnie do Wilu88. Pisze mailing i ustalam mu datę wysyłki (dziś lub przyszłość). Jeśli przyszłość to działa skrypt, ktory raz na dobę, przed północa sprawdza daty wysyłek maili i jeśli napotka taki, który ma wysyłke na dzień kolejny, dodaje maile dla jego adresatów do kolejki. Jesli wysyłka na dziś, to od razu wrzucam do kolejki. Skrytp wysyłający odpalany z crona co kilka minut. W konfigu ustalam wielkość paczki jako:
( limit_serwera - margines_bezpieczeństwa ) / ilość uruchomień_na_godzinę
czyli dla przypuśćmy 100/h dałbym 90-95/h (trzeba zostawić margines na rejestracje, odzyskiwanie haseł, zapytania mailowe itp). Jeśli odpalanie co 6 minut to 90/10 = 9 i tyle wynosiła by wielkość paczki u mnie by było OK. Poza tym przemyśl jeszcze możliwość zatrzymania i/lub wznowienia mailingu lub co zrobić jeśli mailing ruszył, a Ty aktualizowałeś treść mailingu po zauważeniu błędów. Do tego kontrola działania mailingu (ilość wysłanych, ilość prób błędnych) czy jego statystyki. Wiele osób o takich rzeczach nawet nie myśli lub nie wie jak zaimplementować, choć przynajmniej część powinna być.

I uwierz, że się da to czego chcesz, ale trzeba nieraz pokombinować z cronem lub uruchamianiem skryptu w CLI jesli serwis to umożliwia i nieskończone wywoływanie skryptu przez samego siebie, z dobrze napisanym warunkiem stop. To drugie to nie tak pewna metoda i nie zawsze możliwa do zastosowania. Nie polecam jednak jej nikomu, kto nie ma większej wiedzy bo można serwer załatwić.
Go to the top of the page
+Quote Post
Wilu88
post
Post #5





Grupa: Zarejestrowani
Postów: 158
Pomógł: 6
Dołączył: 7.03.2010

Ostrzeżenie: (0%)
-----


Jeśli chodzi o zmianę treści maili w czasie wysyłki no to przecież i tak nic już nie zrobisz z mailami które zostaną wysłane. A skoro w tabeli z oczekującymi mailami masz podane tylko id wiadomości zapisanej w innej tabeli to gdy tam zmienisz jej treść, to przy wysyłaniu maila pobierze już nową treść.

Jedyne co można było by jeszcze przemyśleć to jakieś zabezpieczenie związane z porównywaniem daty edycji wiadomości a datą wysyłki maila, czyli nie usuwać rekordu po wysłaniu a dodawać tylko datę wysyłki i jeżeli zostanie zmieniona wiadomość to wysłać jeszcze raz maile, które mają datę mniejszą od daty edycji wiadomości.
Go to the top of the page
+Quote Post
thek
post
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




Zebyś Ty widział jak niektórzy piszą systemy mailingu to byś się zdzwił. Poza tym chyba nie bierzesz pod uwage jednego: mailing to nie zawsze "Bierz WYSIWYG i pisz całą treść mailingu" (IMG:style_emoticons/default/smile.gif) Powiedziałbym, że ze względu na głupotę piszących takie coś to najgorszy sposób przechowywania mailingu do wysyłki. Musi obowiązywać pewien stały szablon. User powinien mieć możliwość eduycji jedynie wąskiego wycinka maila. Reszta powinna być niezmienna. W takim wypadku w bazie trzymany jest jedynie fragment i chyba nie powiesz mi, że przy każdym przejściu pętli lub co uruchomienie kolejnego cyklu crona byś go na nowo generował? Jeśli w moim skrypcie daje userowi 2 pola do uzupełnienia i opcjonalnie checkboxy do włączenia ewentualnych elementów dodatkowych + resztę layoutu maila generuję z automatu to niestety, ale srednio mi się to nada, zwłaszcza w chwili gdy pewne elementy maila zawierają jeszcze szablon do zmiany z użyciem preg_replace w stylu {username}, a dodatkowo może się nałożyć jednoczesna wysyłka kilku mailingów w jednym przebiegu cron-a, z czym też nie każdy skrypt sobie dobrze radzi.

Dobrze przemyslany skrypt wysyłający jest niewrażliwy na edycję mailingu, ponieważ go generuje w zasadzie tylko raz, gdy zaczyna wysyłkę, a jeśli zmiana następuje w trakcie wysyłki to ów wygenerowany usuwa i skrypt powinien sam sobie poradzić z jego ponownym utworzeniem. Odpada masa IFow, kombinowania z datami i zapychaniem bazy nadmiarowymi informacjami (IMG:style_emoticons/default/smile.gif)

Przykładowo gdy u mnie w skrypcie rusza mailing to sprawdzam czy istnieje już wygenerowany w bazie o tym id. Jesli tak - korzystam, jeśli nie - tworzę i wrzucam do bazy jako cache oraz w skrypcie do tablicy z indeksem równym id. Jeśli w trakcie wysyłki nadpisze mailing to usuwam ów wygenerowany z bazy a dodatkowo sprawdzam czy nie zmieniła mi się grupa docelowa adresatów (mam skrypt gdzie mogę to określać) i modyfikuję kolejkę tak, by uwzględniło zmiany dla userów, którym jeszcze nie wysłało maila. Ogólnie jest więcej zabawy niż myślisz bo skrypt jest bardziej rozbudowany niż "napisz mailing i wysyłaj wszystkim". Jeśli dochodzą do tego grupy uzytkowników, szablony, wysyłki cykliczne, statystyki, obsługa newslettera dynamiczna (wstrzymywanie, wznawianie i edycja w locie) i trochę innych bajerów to mailing przestaje być banalnym skryptem.
Go to the top of the page
+Quote Post
Wilu88
post
Post #7





Grupa: Zarejestrowani
Postów: 158
Pomógł: 6
Dołączył: 7.03.2010

Ostrzeżenie: (0%)
-----


Zgodzę się z Tobą że to nie jest prosta sprawa. Z drugiej strony ja piszę mailing na jakieś 100-200 maili nie podejrzewam aby kiedykolwiek było więcej, poza tym będzie wykorzystywany w naszej firmie, wiec odchodzi kwestia martwienia się o użytkownika.

Poza tym planuje ustawić crona aby wysyłał maile tylko w nocy aby nie obciążać serwera, tym samym zmian w treści w trakcie wysyłania raczej nie będzie (IMG:style_emoticons/default/biggrin.gif)

Co do statystyk to też takie ubogie trochę zrobiłem za pomocą str_replace zamieniam linki występujące w treści na takie aby przechodziły przez skrypt przekierowujący na własnym serwerze, tym samym wiem ile było odwiedzin bezpośrednio z maili.

Wiadomo lepiej zrobić raz a porządnie aby służył i w serwisach z małą listą mailingową jak i w dużych serwisach, ale aktualnie moje umiejętności mi na to nie pozwalają (IMG:style_emoticons/default/biggrin.gif)

Ten post edytował Wilu88 27.07.2011, 13:25:38
Go to the top of the page
+Quote Post
thek
post
Post #8





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Ja także nie pisze kolosów (IMG:style_emoticons/default/smile.gif) najwieksze mailingi, które na tym chodzą, mają góra kilkuset userów po stronie newslettera samego i może kilka tysięcy od strony wstrzykniętego serwisu. Mimo że brak na VPS z reguły limitów na wysyłke i w teorii można puścić od razu całoś, to nie robie tego. Czemu? Spamlisty (IMG:style_emoticons/default/smile.gif) Jeśli serwer docelowy dostanie z jednego serwera dla różnych userów mail w bardzo krótkim czasie, to od pewnej ilości łapie Cię na spamlistę. A potem się tłumacz userom, czemu Twój newsletter muszą szukać w spamie (IMG:style_emoticons/default/wink.gif)
Go to the top of the page
+Quote Post
darney
post
Post #9





Grupa: Zarejestrowani
Postów: 124
Pomógł: 0
Dołączył: 21.08.2010
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


co myślicie o tym może to by miało jakieś zastosowanie w zaistniałym problemie ?
http://email.about.com/od/emailprogramming...hentication.htm

A może znacie jakieś gotowe systemy bo nie wiem czy mam zbytnio aktualnie czas żeby pisać od zera taki mailing. Widzę że to nie łatwe wyzwanie.

Nie rozumiem też jednej rzeczy. Jak ustawić skrypt aby wysyłał coś poza moją obecnością? Pakuje wiadomość do bazy do userów i wysyła już potem sam? przecież skrypt nie może się wykonywać dłużej niż 30 sek. Moja główka jeszcze tego nie ogarnia. Proszę o wyrozumiałość i wyjaśnienia:)
Proszę o opisanie mi drogi jak to ma wyglądać. Skrypt wysyła do bazy ->wiadomość-> poczekalnia w bazie -> co dalej ? czegoś nie rozumiem. SQL ma wysłać to (IMG:style_emoticons/default/tongue.gif) ?
Też nie rozumiem co to jest ten cron. Ide czytać na google (IMG:style_emoticons/default/wink.gif)

Ten post edytował darney 28.07.2011, 12:08:14
Go to the top of the page
+Quote Post
thek
post
Post #10





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




CRON to unixowy demon chodzący w tle i co określony czas wywołujący zdefiniowane polecenia, czyli przykładowo uruchamiający skrypt wysyłający maile. Ustawiasz, że ma co ileś minut odpalić skrypt wysyłki i zapominasz (IMG:style_emoticons/default/wink.gif)

Inna wariacja to napisac skrypt, który odpala sam siebie. Ale to już ciutkę wyższa szkoła jazdy bo można zapętlić go tak, że będziesz miał problem z zatrzymaniem (IMG:style_emoticons/default/wink.gif)
Go to the top of the page
+Quote Post
darney
post
Post #11





Grupa: Zarejestrowani
Postów: 124
Pomógł: 0
Dołączył: 21.08.2010
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


hehehe (IMG:style_emoticons/default/smile.gif) Wtedy hulaj dusza admin netart piekła niema:) Powiedz mi co sądzisz o linku wyżej który dałem. Gdzieś odpowiedzieli że problem limitu mail() na serwerze można ominąć tym. Czy to prawda ? (wypowiedź wyżej - link)
Go to the top of the page
+Quote Post
Wilu88
post
Post #12





Grupa: Zarejestrowani
Postów: 158
Pomógł: 6
Dołączył: 7.03.2010

Ostrzeżenie: (0%)
-----


Coś nie chce mi się wierzyć ale to thek jest tutaj specem. Co do tego hulaj dusza to też radziłbym uważać żeby za pomocą crona za bardzo nie obciążyć serwera wykonując masę skryptów w krótkich odstępach czasu (IMG:style_emoticons/default/wink.gif)
Go to the top of the page
+Quote Post
thek
post
Post #13





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Można tak rozwiązywać, ale różne SMTP też mają swoje limity i moga Ci uwalić wysyłkę gdy zaczniesz przesadzać. Aby tego uniknąć najczęściej się stosuje rotowanie serwerów, czyli bierzesz kilka conajmniej SMTP i wysyłasz raz jednym, raz innym. Najprościej uzyć przygotowanych pod takie działania skryptów/bibliotek w stylu Swift Mailer.

Co do netart, to tam z CRONem jest kiepskawo o ile pamiętam... Można tylko raz na godzinę odpalać skrypt, no chyba że zrobisz kilka regułek do tego samego skryptu.
Go to the top of the page
+Quote Post
darney
post
Post #14





Grupa: Zarejestrowani
Postów: 124
Pomógł: 0
Dołączył: 21.08.2010
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


Zgadza się jak narazie mój mailing liczy 150 osób tylko 2 wykonania skryptu 2 razy dziennie. W tygodniu 1x (IMG:style_emoticons/default/tongue.gif) Musze poważnie obmyślić plan jak to napisać i ustawić w bazie. Moja programistyczna główka dopiero się rozwija. (IMG:style_emoticons/default/smile.gif)

PIERWSZY ETAP
Widział bym to tak. Skrypt ma ustawione
Sprawdzam czy w bazie nie ma wiadomości które trafiły do TABELI "OCZEKUJĄCE"
Jeżeli PRAWDA to wysyłam 1-50 ID z oczekujących.

DRUGI ETAP - Godzinę póżniej (IMG:style_emoticons/default/tongue.gif)
Sprawdzam czy w tabeli oczekujące nie ma jakiś maili
Jeżeli PRAWDA to wysyłam 50-100.

TRZECI ETAP - Godzinę póżniej (IMG:style_emoticons/default/tongue.gif)
Sprawdzam czy w tabeli oczekujące nie ma jakiś maili
Jeżeli PRAWDA to wysyłam 100-150.

CZWARTY ETAP
Sprawdzam.........
FAŁSZ brak maili powyżej 150
nic nie robię i idę się nawalić (IMG:style_emoticons/default/smile.gif) -> np. Informuje o tym admina serwisu (IMG:style_emoticons/default/tongue.gif) mail to (admin@serwis.pl)

Czy dobrze myślę ?


Jak by miała pętla przykładowa sprawdzająca wyglądać ?


Go to the top of the page
+Quote Post
Wilu88
post
Post #15





Grupa: Zarejestrowani
Postów: 158
Pomógł: 6
Dołączył: 7.03.2010

Ostrzeżenie: (0%)
-----


No nie możesz iść po id i założyć że od 1-50 od 50-100 itd. Dlatego że nei przekazujesz id pomiędzy etapami. Najprościej chyba usuwać wysłane z listy oczekujących. A kod powinien wyglądać tak:


1. Pobierz 50 rekordów z tabeli sortując ID od najmniejszego do największego.

2. W pętli wykonaj wysłanie maila, jeśli wyśle poprawnie usuń rekord z tabli oczekującej

Go to the top of the page
+Quote Post
darney
post
Post #16





Grupa: Zarejestrowani
Postów: 124
Pomógł: 0
Dołączył: 21.08.2010
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


a drugie powtórzenie skryptu wywołanego CRONEM ? Jak będzie sprawdzać te 1-50 czy są puste ?
Go to the top of the page
+Quote Post
Wilu88
post
Post #17





Grupa: Zarejestrowani
Postów: 158
Pomógł: 6
Dołączył: 7.03.2010

Ostrzeżenie: (0%)
-----


Po prostu ich już w bazie nei będzie. Powiedzmy masz w tabli oczekujących 150 maili do wysyłki z ID od 1 do 150.

Pierwszy etap:

Pobierz 50 maili sortując rosnąco (czyli pobiera maile od 1 do 49)

Wyślij maila i usuń rekord

Na końcu etapu zostaje ci w tabeli id od 50 do 150

Drugi etap:

Pobierz 50 maili sortując rosnąco (czyli pobiera maile od 50 do 100)

Wyślij maila i usuń rekord

Na końcu etapu zostaje ci w tabeli id od 101 do 150

Trzeci etap:

Pobierz 50 maili sortując rosnąco (czyli pobiera maile od 101 do 150)

Wyślij maila i usuń rekord

Na końcu etapu zostaje ci pusta tabela


Czwarty etap:

Pobierz 50 maili sortując rosnąco (Brak jakichkolwiek maili reszta kodu nie wykonuje się)


Go to the top of the page
+Quote Post
thek
post
Post #18





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Wilu... Zależy od tego jak podejdzie do problemu maili. Tak jak napisałeś jest ok, ale co jeśli maili więcej jest i osiągasz "masę krytyczną" czyli liczba wiadomości nie wysłana z powodu błędów osiąga wielkość określoną w zapytaniu przy LIMIT? Blokujesz cała kolejkę wysyłania, bo czekające błedne nie dopuszczą do przeskoczenia na możliwe do wysyłki (IMG:style_emoticons/default/wink.gif) To też trzeba rozpatrzyć. Oczywiście w sytuacji gdy przewidujesz sprawdzanie czy mail został wysłany, a nie że walisz wysyłke i nawet nie sprawdzasz czy wszystko jest cacy. Mi się już zdarzały różne hece gdy warstwa transportowa skryptu się burzyła, że za żadne skarby nie pośle, bo mu serwer poczty docelowej adresata się nie podoba. Dlatego teraz zazwyczaj daje każdemu adresowi 3 próby i dopiero potem daję ignorowanie w kolejce, oczywiście statystyki mnie informują, że taki a taki mail nie załapał i tam mam szukać winowajcy potencjalnego.
Go to the top of the page
+Quote Post
Wilu88
post
Post #19





Grupa: Zarejestrowani
Postów: 158
Pomógł: 6
Dołączył: 7.03.2010

Ostrzeżenie: (0%)
-----


Cytat(thek @ 28.07.2011, 15:09:30 ) *
Wilu... Zależy od tego jak podejdzie do problemu maili. Tak jak napisałeś jest ok, ale co jeśli maili więcej jest i osiągasz "masę krytyczną" czyli liczba wiadomości nie wysłana z powodu błędów osiąga wielkość określoną w zapytaniu przy LIMIT? Blokujesz cała kolejkę wysyłania, bo czekające błedne nie dopuszczą do przeskoczenia na możliwe do wysyłki (IMG:style_emoticons/default/wink.gif) To też trzeba rozpatrzyć. Oczywiście w sytuacji gdy przewidujesz sprawdzanie czy mail został wysłany, a nie że walisz wysyłke i nawet nie sprawdzasz czy wszystko jest cacy. Mi się już zdarzały różne hece gdy warstwa transportowa skryptu się burzyła, że za żadne skarby nie pośle, bo mu serwer poczty docelowej adresata się nie podoba. Dlatego teraz zazwyczaj daje każdemu adresowi 3 próby i dopiero potem daję ignorowanie w kolejce, oczywiście statystyki mnie informują, że taki a taki mail nie załapał i tam mam szukać winowajcy potencjalnego.



Oczywiście że tak. To taki przykład tylko dla zobrazowania dzielenia na etapy. A to jak podejdziesz do sprawdzania czy maile przeszły do sprawa indywidualna. Osobiści skłaniam się ku dodatkowemu polu w którym będzie zapisany status wysyłki.
Go to the top of the page
+Quote Post
darney
post
Post #20





Grupa: Zarejestrowani
Postów: 124
Pomógł: 0
Dołączył: 21.08.2010
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


Cytat(darney @ 27.07.2011, 10:10:22 ) *
  1. while ($row = mysqli_fetch_array($result)){
  2. $to = $row['mailer_email'];
  3. $mailer_imie = $row['mailer_imie'];
  4. $mailer_nazwisko = $row['mailer_nazwisko'];
  5. $msg = "Drogi $mailer_imie $mailer_nazwisko,\n$text";
  6. $from = 'From: "xxx@xxx.pl" <xxx@xxx.pl>' . PHP_EOL .
  7. //'Cc: "CC Display Name" <xxx@xxx.pl>' . PHP_EOL .
  8. 'X-Mailer: PHP-' . phpversion() . PHP_EOL;
  9. $from .= "Content-type: text/html; charset=utf-8\n";
  10. //$from .= "Content-Transfer-Encoding: 8bit\n";
  11.  
  12. mail($to, $subject, $txt_mail, $from);
  13. echo 'Wysłano wiadomość pod adres: ' . $to . '<br />';
  14.  


słuchajcie a jak ustawić pętle żeby ten skrypt wysłał do ludzi o ID zaczynających się od 50-100 np ?
Póki co zrobię sobie osobne skrypty tzn.
Link do skryptu1 wysyłam od 1-50
Link do sktyptu2 wysyłam od 50-100
i wtedy tylko kopiuj wklej pośle list o newsach. Na razie ich dużo nie mam więc tyle mi starczy lecz wiedzę którą tu poruszyliście sobie zapisze (IMG:style_emoticons/default/tongue.gif)

Póki rozwijam swój serwis to tyle mi wystarczy. jak będę dobijał do 1000 osób to wtedy zacznę zmartwienia co dalej.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 23.08.2025 - 01:53