Apache Email 遇到的线程释放慢问题
2016-01-07 20:02
716 查看
在实习中,需要做一个系统的发送邮件功能,因为是群发,需要发送给公司1500多人,因为是建立公告后,判断公告的重要性,重要则发送群邮,因此不能通过同步来实现,只能通过异步发送,一封邮件同时发给1500个人是不太现实的,所以开始的时候,将每封邮件发送给200个人,通过多线程并发,启动8个线程发送这8封邮件。如下代码:
查看线程栈可以发现,线程一直是Runnable状态,如下代码:
线程一直是Runnable状态持续10几分钟,折腾了很长时间没有发现出问题,期间有怀疑过是否是Hibernate的缓存导致邮件发送的时间延迟,后来无意中测试了,发送6封邮件,每封发一个人,如下代码:
这时,邮件发送很快,等待时间基本看不到,才发觉,猫腻藏在邮件发送的人数上。
猜测:一封邮件发送200个人的时候,线程启动后,一直在Runnable,可能是一封邮件发送给200个人,邮件服务器应付不回来,只能慢慢运行、发送邮件,直到200封邮件发送出去后,线程才释放资源。
后来才将代码改为一封一封的发送,一次群发的速度,很大一部分取决于邮件服务器。在线程池限制在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("111@qq.com", "111"); email.setAuthentication("111@qq.com", "xxx"); email.setSubject("主题"); email.setMsg("内容"); //循环6次、发送6封邮件,每封邮件发200人 for (int k = 0; k < 6; k++) { for (int i = 0; i < 200; i++) { email.addTo("222@qq.com", "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封邮件,每封发一个人,如下代码:
//发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("111@qq.com", "111"); email.setAuthentication("111@qq.com", "xxx"); email.setSubject("主题"); email.setMsg("内容"); //循环6次、发送6封邮件,每封邮件发200人 for (int k = 0; k < 6; k++) { email.addTo("222@qq.com", "222"); executorService.execute(new Runnable() { @Override public void run() { try { email.send(); } catch (EmailException e) { e.printStackTrace(); } } }); } //将邮件信息插入数据库 }
这时,邮件发送很快,等待时间基本看不到,才发觉,猫腻藏在邮件发送的人数上。
猜测:一封邮件发送200个人的时候,线程启动后,一直在Runnable,可能是一封邮件发送给200个人,邮件服务器应付不回来,只能慢慢运行、发送邮件,直到200封邮件发送出去后,线程才释放资源。
后来才将代码改为一封一封的发送,一次群发的速度,很大一部分取决于邮件服务器。在线程池限制在20个前提下,发了1500封邮件差不多要1个小时。。。。
相关文章推荐
- Apache+mod_cluster+jboss EAP5.1搭建详解
- 关于apache的日志配置和模板格式分析
- apache目录的访问控制
- linux服务器 Apache服务的源码安装与基本配置
- Linux 安装apache
- SNMP 原理及配置简述 net-snmp-utils net-snmp 第2版基于SNMP 群体名(community name) 第3版引入了安全性更高的访问控制方法 SNMP协议操作只有4种 Apache的php_snmp 模块
- Apache以及PHP的默认编码问题解决(详解)
- 安装apache遇到的问题总结
- Linux Ubuntu 下 apache 配置
- org.apache.catalina.Lifecycle
- Storm Caused by: org.apache.thrift7.transport.TTransportException
- 阿里云Linux之CentOS从0配置APACHE+MYSQL+PHP
- Apache配置压缩优化时报错——undefined symbol: inflateEnd
- Apache Thrift之java入门例子
- 使用Apache Benchmark给自己的网站进行测试
- What are the differences between Apache Kafka and RabbitMQ?
- apache poi导出Excel或Pdf文件
- Apache静态缓存配置
- wampserver部署笔记 设置apache使得外网可以访问
- apache服务器