Viele verschiedene E-Mails an unterschiedliche Empfänger schnell versenden?

Bergtroll

Bekanntes Mitglied
Hallo mal wieder, liebes Forum,

ich stehe gerade vor der Frage, wie ich für unser aktuelles Projekt den Mailversand organisiere. Ich habe mit JavaMail und meinem Mailaccount gespielt und das hat auch geklappt, allerdings dauert der Versandprozess 2 Sekunden, was viel zu lange den Thread blockiert. Größter Teil davon ist so das Drumherumreden der Protokolle und Verbindungsaufbau. Klar der läuft in eigenem Prozess, der Mailinput kommt asynchron per ZeroMQ. Aber ich frage mich trotzdem, ob das so lange dauer muss, schließlich sollen eine ganze Menge Mails versandt werden...

Ich dachte jetzt, vielleicht wirds schneller, wenn man nen lokalen Exim oder so installiert der erstmal sammelt. Aber muss nicht auch lokal ne Verbindung aufgebaut werden, was dann genauso lange dauert? Gibts einen Low Level weg die E-Mails an Exim zu geben? Denke ich zu kompliziert? Oder doch lieber Amazon Cloud Simple Mail Service? Ganz was anderes? Wie ist denn bei euch der Mailversand in größeren Mengen realisiert?

Viele Grüße,

Bergtroll
 
I

irgendjemand

Gast
interessant wäre vielleicht mal der code mit dem du deine mails versendest ..
wenn du schon selbst sagst das es prob mail 2 sec dauert und das viel außenrum geschiet ... würde ich fast vermuten das du die static methode Transport.send(Message) callst ...
der api ist zu entnehmen das diese methode selbstständig alle verbindungs-daten handelt ... also auch jedesmal ne verbindung aufbaut ... die mail sendet ... und die verbindung wieder abbaut ...

alternativ kann es auch daran liegen wie du den content zusammenbaust und wie viel es überhaupt pro mail ist ...

ein sehr einfaches tutorial : E-Mails mit JavaMail versenden @ tutorials.de: Tutorials, Forum & Hilfe

wie hier zu sehen ist wird die verbindung VOR dem senden aufgebaut ... dann die mail versendet ... und dann die verbindung erst abgebaut ...

angenommen die mails sind vorher schon zusammengebaut ... brauchst du nur noch Transport.sendMessage(Message, Address[]) in einem loop zu callen

alternativ kannst du auch mehrere empfänger gleichzeitig angeben ... sendest also nur eine mail und dein provider erledigt den rest ...

aber wie gesgt : ohne code kann man dem problem nicht auf die spur kommen
 

homer65

Top Contributor
Die Frage ist auch über wen du deine Mails versenden willst.
Wenn du kostenlose Anbieter nutzt, wirst du mit diversen Einschränkungen leben müssen.
Es könnte durchaus sein, das der Anbieter den du nutzt absichtlich den Verbindungsaufbau verzögert.
 

Bergtroll

Bekanntes Mitglied
Guten Morgen, erst einmal vielen Dank für die Antworten. Also ich versende über Googlemail, wollte ja erstmal nur testen. Für den Produktiveinsatz überlegen ich entweder einen Mailserver aufzusetzen. Davor habe ich aber gehörigen Respekt, weil man offensichtlich viel falsch machen kann und schnell geblacklistet wird. Oder eben einen Service zu nutzen. Aber erstmal würde ich halt ganz gerne auf meiner Seite sicherstellen, dass schnelle viele Mails rausgegeben werden können. Ich hatte auch gedacht, man könne ja vielleicht eine Verbindung dauerhaft offenhalten, aber entweder habe ich das falsch verstanden oder SMTP sieht das nicht vor? Jetzt erstmal der Testcode. Nicht über das DEBUG Flag wundern, damit dauerts sogar noch länger aber so sieht man wenigstens was passiert:

Java:
import java.util.Properties;

import javax.mail.Address;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;

import com.sun.mail.smtp.SMTPMessage;

public class SendMailTest {

	private static final String SMTP_HOST_NAME = "smtp.gmail.com";
	private static final int SMTP_HOST_PORT = 465;
	private static final String SMTP_AUTH_USER = "myaddress@gmail.com";
	private static final String SMTP_AUTH_PWD = "mypassword";

	private final Session session;
	private final Transport transport;

	public SendMailTest() {
		this.session = this.createSession();
		this.transport = this.createTransport();
	}

	private Session createSession() {
		Properties properties = this.createProperties();
		Session session = Session.getDefaultInstance(properties);
		session.setDebug(true);
		return session;
	}

	private Properties createProperties() {
		Properties properties = new Properties();
		properties.put("mail.transport.protocol", "smtps");
		properties.put("mail.smtps.host", SMTP_HOST_NAME);
		properties.put("mail.smtps.auth", "true");
		properties.put("mail.smtp.from", SMTP_AUTH_USER);
		return properties;
	}

	private Transport createTransport() {
		Transport transport = null;
		try {
			transport = this.session.getTransport();
		} catch (NoSuchProviderException e) {
			e.printStackTrace();
		}
		return transport;
	}

	public static void main(String[] args) {
		SendMailTest mailer = new SendMailTest();
		InternetAddress mailto;
		try {
			mailto = new InternetAddress("recipient@example.com");
			mailer.sendMail(mailto, "SSL Test", "This is an SMTPS SSL connection testmail");
		} catch (AddressException e) {
			e.printStackTrace();
		}
	}

	public void sendMail(Address toAddress, String subject, String content) {
		SMTPMessage message = createMessage(subject, content);
		System.out.println("EMAIL TEST: " + message.toString());
		try {
			transport.connect(SMTP_HOST_NAME, SMTP_HOST_PORT, SMTP_AUTH_USER,
					SMTP_AUTH_PWD);
			transport.sendMessage(message, new Address[] { toAddress });
		} catch (MessagingException e) {
			e.printStackTrace();
		}
	}

	private SMTPMessage createMessage(String subject, String content) {
		SMTPMessage message = new SMTPMessage(session);
		try {
			message.setSubject(subject);
			message.setContent(content, "text/plain");
		} catch (MessagingException e) {
			e.printStackTrace();
		}
		return message;
	}
}
 
I

irgendjemand

Gast
mal davon abgesehen das in deinem beispiel das Transport.close() vollständig fehlt hast du meinen post scheinbar nicht ganz verstanden

dein problem ist das du jedes mal bevor du eine mail sendest eine neue verbindung aufbaust ...

wenn du viele mails nach ein ander senden willst musst du aber unabhängig von deiner sendMail-methode die verbindung manager ... also von außen noch zwei methoden ala open() und close() und diese um den for()-loop legen der die mails rausjagd

wenn ich meinen code von tut.de entsprechend verändere

Java:
transport.connect(host, port, user, pass);
for(int i=0; i<mails.length; i++)
{
	transport.sendMessage(mails[i].getMessage(), mails[i].getAddresses());
	System.out.println("SEND");
}
transport.close();

kann ich mit g-mail locker 100 mails an einem stück versenden ohne das ich ich die verbindung jedes mal neu aufbauen muss ...

mails[] ist hierbei ein array der klasse Mail welche mir über zwei getter einmal die Message und zum anderen das Address[] array liefert um mails und adressen synchron zu halten ... müsstest du eventuell selbst bauen ...

da ich nur relativ geringen upload habe *384kBit/s* dauern 100 mails natürlich etwas ... aber wenn ich die zeit durch 100 teile komme ich auf unter 2sec / mail ...

von daher bestätigt sich hier nur meine anfangsvermutung : ansatt EINE verbindung für alle mails zu nutzen baust du jedes mal für eine neue mail auch eine neue verbindung auf ...
 

Bergtroll

Bekanntes Mitglied
Erst einmal vielen Dank für das Feedback, habe die Schleife eingebaut und bei mir funktionierts jetzt auch besser... Bis auf, dass E-Mails von googlemail nicht bei web.de ankommen...

mal davon abgesehen das in deinem beispiel das Transport.close() vollständig fehlt (...)

Oh danke, das scheine ich beim refaktorieren aus Versehen gekillt zu haben. Das kommt davon, wen man sich beim Ausprobieren kein Unit tests schreibt, die schauen, ob alles sauber geschlossen wird :(. Ich werde mich besser!!!


hast du meinen post scheinbar nicht ganz verstanden. dein problem ist das du jedes mal bevor du eine mail sendest eine neue verbindung aufbaust ...

Doch ich hatte deinen Post schon verstanden, aber ich hatte ein Problem mit dem Protokoll. Ich habe z.B. den Wiki Artikel gelesen Simple Mail Transfer Protocol ? Wikipedia und die ersten paar RFCs zumindest quergelesen. Überall sieht SMTP so aus, als wäre es wie HTTP ein Ablauf der immer aus

Code:
CONNECT -> DATENAUSTAUSCH -> DISCONNECT

besteht. Und zwar für jede E-Mail einzeln. Soweit ich das gelesen habe, habe ich nicht gesehen, dass in SMTP so etwas definiert ist:

Code:
CONNECT -> DATENAUSTAUSCH MAIL 1 -> ... -> DATENAUSTAUSCH MAIL N  -> DISCONNECT.

Aber damit wäre ja das Verhalten, mit JavaMail die Connection offen zu halten, undefiniert und ich könnte mich nicht darauf verlassen, dass es immer läuft? Oder verstehe ich das ganze falsch? Hat SMTP vielleicht garnix mit dem Connection Aufbau an sich zu tun?
 
I

irgendjemand

Gast
ich weis zwar nicht welche RFCs du dir angesehen hast ... oder welche teile davon ... aber du hast da irgendwas missverstanden ...

wenn du nach meinem beispiel oben eine verbindung zum SMTP-server aufbaust ... dich authtifizierst ... dann wartet der SMTP server auf befehle ... und zwar so lange du ihn nicht per ausdrücklichem befehl dazu veranlasst die verbindung zu trennen ...
heißt also : so lange du den server hintereinander weg mit send-mail-commandos fütterst ... so lange nimmt er auch die e-mails an und speichert sie erstmal zwischen ...

wann und wie der SMTP-server die e-mails aus deinem konto weiter an die empfänger leitest kannst du als client nicht beeinflussen ...

aber anzunehmen das du für jede e-mail immer wieder eine neue verbindung brauchen würdest ... das stimmt nicht ... du kannst eine verbindung für mehrere e-mails verwenden ...

genau wie beim abrufen von mails mit POP3 ... da hast du auch eine verbindung für mehr als eine e-mail ...


ob die mails überhaupt von deinem rechner bei google ankommen kannst du bei google irgendwo unter postausgang oder gesendet oder so nachsehen ... dort sollten die e-mails die du via SMTP verschickt hast noch mal als kopie auftauchen ...

das es aber dauert von googlemail zu anderen providern zu schicken liegt daran das google die e-mails erstmal als kopie auf seine server zieht ... steht auch irgendwo in den AGB das die das ganz legal machen ... es kann auch sein wenn du zu viele mails an einen bestimmten empfänger schicken willst das das n timelimit hat ... auch kann es sein das web.de das ganze blockt ... vllt mal im spam-ordner nachgucken ...


was aber auf jeden geht : mit hilfe von g-mail mehrere mails über EINE verbindung an web.de zu schicken *selbst getestet*
 

Bergtroll

Bekanntes Mitglied
Cool, vielen lieben Dank für die Klarstellung, dann habe ich den Teil tatsächlich falsch verstanden. D.H. ich kann mir eine Verbindung offen halten, die zum Beispiel erst dicht macht, wenn 2 Minuten nix mehr Neues kommt oder so :toll: :).

Das bei Web.de nix ankommt, scheint irgendein anderes Problem zu sein. Habe festgestellt, dass nicht mal E-Mails, die ich manuell über Weboberfläche abschicke, dort ankommen... auch nicht im SPAM... komisch...

Schönes Wochenende :D
 
I

irgendjemand

Gast
so stimmt das auch nicht ...
also ein gewisses timeout hat die verbindung natürlich auch ...
irgendwann ist die warterei dem smtp-server auch zu viel und er beendet die verbindung ...

also einfach verbindung offenhalt nur um dann mal alle paar minuten ne mail zu senden ... das geht so leider auch nicht ...

du kannst aber , wenn du bereits mehrere mails generiert und zwischengespeichert hast , diese über eine verbindung hintereinander weg senden ... und solltest danach aber die verbindung auch wieder schließen

das du von g-mail gar keine mails empfängst ist komisch ...

wenn ich das ganze als beispiel mit 1 mail mache ... und diese auch wie JavaMail von web.de abholen will ist diese nach knapp 10sec-20sec da ... keine probleme ...

musst mal in web.de unter EINSTELLUNGEN und dann sowas wie REGELN *habs nich genau im kopf* nach sehen ... dort stehen deine ganze blockier und sonst-was listen ... vllt steckt da der fehler ...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
P Socket Viele Clients bedienen mit Vert.x Netzwerkprogrammierung 9
F SSL-Zertifikate für viele Nutzer? Netzwerkprogrammierung 8
R viele HttpRequests - Adapter überlastet? Netzwerkprogrammierung 11
R Viele Clients ein Server Netzwerkprogrammierung 8
E TCP-Server soll viele offene Verbindungen verwalten Netzwerkprogrammierung 12
F GSON wenn das Json verschiedene Klassen enthält Netzwerkprogrammierung 1
S User im Chatprogramm verschiedene Farben Netzwerkprogrammierung 1
S Socket Verschiedene Exceptions beim Übertragen von Bildern über Socket Netzwerkprogrammierung 20
A Socket Server: Message an verschiedene Clients senden Netzwerkprogrammierung 4
F Socket Daten über verschiedene IP's schicken Netzwerkprogrammierung 5
B verschiedene Serialisierte Objekte identifizieren? Netzwerkprogrammierung 5
F Verschiedene Datentypen senden Netzwerkprogrammierung 4
T Inputstream -> verschiedene Objekte lesen Netzwerkprogrammierung 3
W RMI Verschiedene Unterobjekte trotz selbem Remote Object Netzwerkprogrammierung 2
P Verschiedene Daten über einen Stream Netzwerkprogrammierung 4
Luma Verschiedene Frage zu nem Netzwerkprog Netzwerkprogrammierung 6
B Verbindung über verschiedene IPs Netzwerkprogrammierung 3
M Mit Java Mail Mails an Webmailer schicken Netzwerkprogrammierung 1
M Mails abrufen mit IMAP Netzwerkprogrammierung 2
H HTML-Mails mit JavaMail API Netzwerkprogrammierung 3
L JavaMail: Versenden von mails funktioniert nicht Netzwerkprogrammierung 7
S E-Mails versenden. Netzwerkprogrammierung 10

Ähnliche Java Themen

Neue Themen


Oben