• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

注意:阿里Druid连接池监控的两个坑

技术杂谈 勤劳的小蚂蚁 3个月前 (01-18) 96次浏览 已收录 0个评论 扫描二维码

阿里的Druid大家都知道是最好的连接池,其强大的监控功能是我们追求的重要特性。但在实际情况中也有不少坑,说下最近遇到的一个坑吧!

问题1:不断打印error级别的错误日志

session ip change too many
下面是其报错的关键源码
com.alibaba.druid.support.http.stat.WebSessionStat#addRemoteAddress
  1. public void addRemoteAddress(String ip){
  2.    if(remoteAddresses ==null){
  3.        this.remoteAddresses = ip;
  4.        return;
  5.    }
  6.    if(remoteAddresses.contains(ip)){
  7.        return;
  8.    }
  9.    if(remoteAddresses.length()>256){
  10.        LOG.error("session ip change too many");
  11.        return;
  12.    }
  13.    remoteAddresses +=';'+ ip;
  14. }
再来看看Druid连接池获取IP的方式
com.alibaba.druid.util.DruidWebUtils
  1. publicstaticString getRemoteAddr(HttpServletRequest request){
  2.    String ip = request.getHeader("x-forwarded-for");
  3.    if(ip ==null|| ip.length()==0||"unknown".equalsIgnoreCase(ip)){
  4.        ip = request.getHeader("Proxy-Client-IP");
  5.    }
  6.    if(ip ==null|| ip.length()==0||"unknown".equalsIgnoreCase(ip)){
  7.        ip = request.getHeader("WL-Proxy-Client-IP");
  8.    }
  9.    if(ip ==null|| ip.length()==0||"unknown".equalsIgnoreCase(ip)){
  10.        ip = request.getRemoteAddr();
  11.    }
  12.    return ip;
  13. }
分析其源码
这是阿里Druid连接池的session监控功能,会记录同一个会话ID的所有访问IP记录,当超过256个字符长度时就会打印这个错误日志,但实际功能不受影响。
看了下Druid session监控的页面,同一个会话请求次数并不多,但记录的IP却有问题,一个请求最多的会保存多级代理形成的多段IP(如192.168.1.2,192.168.1.3,192.168.1.4),这样一来5、6次请求就会使访问IP超出256长度从而打印这个错误。
解决方案
1、如果用不到session监控,就关闭此功能;
  1. <init-param>
  2.  <param-name>sessionStatEnable</param-name>
  3.  <param-value>false</param-value>
  4. </init-param>
2、修改源码,如果有多段IP,截取第一段,并修改记录访问IP(256位)的长度;
作者去看了阿里最新的包,此问题还存在。
并且Github上的Druid官方错误申报里面也有同样的问题,阿里也没有修复的意思,所以我们已暂时关闭session监控功能。

问题2:DruidStatView类异常

  1. java.util.ConcurrentModificationException
  2.    at java.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:394)
  3.    at java.util.LinkedHashMap$ValueIterator.next(LinkedHashMap.java:409)
  4.    at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1067)
  5.    at com.alibaba.druid.support.http.stat.WebAppStat.getSessionStatDataList(WebAppStat.java:504)
  6.    at com.alibaba.druid.support.http.stat.WebAppStatUtils.getSessionStatDataList(WebAppStatUtils.java:64)
  7.    at com.alibaba.druid.support.http.stat.WebAppStatManager.getSessionStatData(WebAppStatManager.java:100)
  8.    at com.alibaba.druid.stat.DruidStatService.getWebSessionStatDataList(DruidStatService.java:205)
  9.    at com.alibaba.druid.stat.DruidStatService.service(DruidStatService.java:161)
  10.    at com.alibaba.druid.support.http.StatViewServlet.process(StatViewServlet.java:162)
  11.    at com.alibaba.druid.support.http.ResourceServlet.service(ResourceServlet.java:253)
看源码,发现又是session监控的坑
无力吐槽。。
for循环里面重复定义Map,可能在别的地方有元素变动,导致发生ConcurrentModificationException异常。
所以,最后关闭了session监控。
很好奇,阿里工程师都这种水平吗? 还是为了偷懒?

丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:注意:阿里Druid连接池监控的两个坑
喜欢 (0)
[247507792@qq.com]
分享 (0)
勤劳的小蚂蚁
关于作者:
温馨提示:本文来源于网络,转载文章皆标明了出处,如果您发现侵权文章,请及时向站长反馈删除。

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00