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

Posted Java技术栈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了注意:阿里Druid连接池监控的两个坑相关的知识,希望对你有一定的参考价值。

点击上方蓝色文字关注↑↑↑↑↑


阿里的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. public static String 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监控,就关闭此功能;

https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_%E9%85%8D%E7%BD%AEWebStatFilter

 
   
   
 
  1. <init-param>

  2.  <param-name>sessionStatEnable</param-name>

  3.  <param-value>false</param-value>

  4. </init-param>

2、修改源码,如果有多段IP,截取第一段,并修改记录访问IP(256位)的长度;

作者去看了阿里最新的包,此问题还存在。

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

并且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监控的坑

无力吐槽。。

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

for循环里面重复定义Map,可能在别的地方有元素变动,导致发生ConcurrentModificationException异常。

所以,最后关闭了session监控。

很好奇,阿里工程师都这种水平吗? 还是为了偷懒?

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

推荐:

推荐:

推荐:

长按关注,更多精彩!

戳原文,更多技术干货!

以上是关于注意:阿里Druid连接池监控的两个坑的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot2.0 基础案例(07):集成Druid连接池,配置监控界面

spring boot整合Druid连接池

阿里druid连接池监控配置

数据库连接池之Druid

阿里巴巴连接池Druid简单使用

真难!通过源码告诉你阿里的数据库连接池Druid为啥如此牛逼!