javamail的bug

背景: 前天线上的tomcat突然挂了,一看原来网络连接超过了操作系统的限制

其实tomcat的压力也不大,并发也就20-30,怎么会造成这种情况,仔细观察发现好多

TCP连接Close_Wait, 这些连接都指向我们邮件中的附件资源,原来是我们发送带附件的邮件造成的

我们在发送邮件的程序中使用了URLDataSource,我在本地测试的时候也发现,在使用URLDataSource的情况下,确实会造成连接不关闭。

通过查看javamail的源代码,发现javamail也并非完全不关闭连接,在使用URLDataSource的时候会打开资源地址请求类型,也会通过流打开真正的资源,javamail获取资源后通过关闭流也关闭了资源的连接,但是获取资源类型的时候并未关闭连接

看看URLDataSource的源代码

  1. publicStringgetContentType(){
  2. Stringtype=null;
  3. try{
  4. if(url_conn==null)
  5. url_conn=url.openConnection();
  6. }catch(IOExceptione){}
  7. if(url_conn!=null)
  8. type=url_conn.getContentType();
  9. if(type==null)
  10. type="application/octet-stream";
  11. returntype;
  12. }

URLDataSource并没有关闭类型连接的接口,所以一旦getContentType就没法关闭了,还好

javamail 的URLDataSource还是很好扩展的,解决办法如下
  1. publicclassXXURLDataSourceextendsURLDataSource{
  2. publicXXURLDataSource(URLarg0){
  3. super(arg0);
  4. //TODOAuto-generatedconstructorstub
  5. }
  6. publicStringgetContentType(){
  7. Stringtype=null;
  8. java.net.HttpURLConnectionurl_conn=null;
  9. try{
  10. //if(url_conn==null)
  11. url_conn=(java.net.HttpURLConnection)this
  12. .getURL().openConnection();
  13. }catch(IOExceptione){
  14. }
  15. if(url_conn!=null){
  16. type=url_conn.getContentType();
  17. url_conn.disconnect();
  18. }
  19. if(type==null)
  20. type="application/octet-stream";
  21. returntype;
  22. }
  23. }

(这段程序仅支持

http 的资源类型,其他类型资源请自行解决)

产生一个类,继承URLDataSource ,并覆盖getContentType函数,然后在调用的地方把

URLDataSource 变为XXURLDataSource即可,本地测试没有问题,然后放在线上测试

发了3000封带附件的程序,系统fd一度高达3100+,后来在半小时内,fd逐渐回收,fd降到数百的正常水平,改造算是基本成功了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值