Apache Emailで発生したスレッド解放の遅い問題
インターンシップでは、システムのメール送信機能を作る必要があります.グループ送信なので、会社に1500人以上送信する必要があります.公告を確立した後、公告の重要性を判断し、重要であればグループメールを送信する必要があります.そのため、同期で実現することはできません.非同期で送信するしかありません.1通のメールを同時に1500人に送信するのは現実的ではありません.各メールを200人に送信し、マルチスレッド同時で8つのスレッドを起動して8つのメールを送信します.次のコードがあります.
スレッドスタックを表示すると、スレッドは常にRunnable状態であり、次のコードが表示されます.
スレッドはずっとRunnable状態が10数分続いていて、長い間振り回されて問題が発見されず、その間にHibernateのキャッシュがメール送信の時間遅延を招いたのではないかと疑ったことがあります.
その後、何気なくテストし、6通のメールを送信し、1通ごとに次のコードを送信しました.
このとき、メールの送信が速く、待ち時間がほとんど見えず、猫がメールの送信人数に隠れていることに気づいた.
推測:1通のメールが200人を送信する時、スレッドが起動した後、ずっとRunnableで、1通のメールが200人に送信された可能性があります.メールサーバーは戻ってこないので、ゆっくりと実行して、メールを送信するしかありません.200通のメールが送信されるまで、スレッドはソースを解放します.
その後、コードを1通1通の送信に変更し、1回の群発の速度は、メールサーバに大きく依存します.オンライン・スレッド・プールは20前提で、1500通のメールを送るのに1時間もかかりません...
private static ExecutorService executorService = Executors.newFixedThreadPool(3);
// 6 , 200
@org.junit.Test
public void test01() throws Exception {
//
final HtmlEmail email = new HtmlEmail();
email.setSocketTimeout(30000);
email.setSocketConnectionTimeout(30000);
email.setCharset("UTF-8");
email.setHostName("smtp.xxxx.com");
email.setSmtpPort(25);
//
email.setFrom("[email protected]", "111");
email.setAuthentication("[email protected]", "xxx");
email.setSubject(" ");
email.setMsg(" ");
// 6 、 6 , 200
for (int k = 0; k < 6; k++) {
for (int i = 0; i < 200; i++) {
email.addTo("[email protected]", "222");
}
executorService.execute(new Runnable() {
@Override
public void run() {
try {
email.send();
} catch (EmailException e) {
e.printStackTrace();
}
}
});
}
//
}
スレッドスタックを表示すると、スレッドは常にRunnable状態であり、次のコードが表示されます.
"pool-2-thread-2@20561" prio=5 tid=0x86f nid=NA runnable
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(SocketInputStream.java:-1)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:79)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
- locked <0x52e4> (a java.io.BufferedInputStream)
at com.sun.mail.util.LineInputStream.readLine(LineInputStream.java:57)
at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:1070)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:986)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:197)
at javax.mail.Service.connect(Service.java:274)
at javax.mail.Service.connect(Service.java:91)
at javax.mail.Service.connect(Service.java:76)
at com.sun.mail.smtp.SMTPTransport.connect(SMTPTransport.java:104)
- locked <0x52e5> (a com.sun.mail.smtp.SMTPTransport)
at javax.mail.Transport.send(Transport.java:94)
at javax.mail.Transport.send(Transport.java:48)
at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1411)
at org.apache.commons.mail.Email.send(Email.java:1448)
......
......
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
スレッドはずっとRunnable状態が10数分続いていて、長い間振り回されて問題が発見されず、その間にHibernateのキャッシュがメール送信の時間遅延を招いたのではないかと疑ったことがあります.
その後、何気なくテストし、6通のメールを送信し、1通ごとに次のコードを送信しました.
// 6 , 1
@org.junit.Test
public void test02() throws Exception {
final HtmlEmail email = new HtmlEmail();
email.setSocketTimeout(30000);
email.setSocketConnectionTimeout(30000);
email.setCharset("UTF-8");
email.setHostName("smtp.xxxx.com");
email.setSmtpPort(25);
//
email.setFrom("[email protected]", "111");
email.setAuthentication("[email protected]", "xxx");
email.setSubject(" ");
email.setMsg(" ");
// 6 、 6 , 200
for (int k = 0; k < 6; k++) {
email.addTo("[email protected]", "222");
executorService.execute(new Runnable() {
@Override
public void run() {
try {
email.send();
} catch (EmailException e) {
e.printStackTrace();
}
}
});
}
//
}
このとき、メールの送信が速く、待ち時間がほとんど見えず、猫がメールの送信人数に隠れていることに気づいた.
推測:1通のメールが200人を送信する時、スレッドが起動した後、ずっとRunnableで、1通のメールが200人に送信された可能性があります.メールサーバーは戻ってこないので、ゆっくりと実行して、メールを送信するしかありません.200通のメールが送信されるまで、スレッドはソースを解放します.
その後、コードを1通1通の送信に変更し、1回の群発の速度は、メールサーバに大きく依存します.オンライン・スレッド・プールは20前提で、1500通のメールを送るのに1時間もかかりません...