jedis中的空指针异常

null pointer exception in jedis

我的日志中充满了来自 Jedis 的异常, 即使那是日志级别信息我也不能忽略它

load technicians buffer took 2942 miliseconds : java.lang.NullPointerException at redis.clients.jedis.BinaryJedis.ping(BinaryJedis.java:187) at redis.clients.jedis.JedisFactory.validateObject(JedisFactory.java:152) at org.apache.commons.pool2.impl.GenericObjectPool.returnObject(GenericObjectPool.java:534) at redis.clients.jedis.util.Pool.returnResourceObject(Pool.java:68) at redis.clients.jedis.JedisPool.returnResource(JedisPool.java:251) at redis.clients.jedis.Jedis.close(Jedis.java:3505) at com.puls.availability.services.AvailabilityServiceImpl.getAvailabilityBufferPerVertical(AvailabilityServiceImpl.java:360) at java.base/java.lang.Thread.run(Thread.java:834) java.lang.NullPointerException at redis.clients.jedis.BinaryJedis.quit(BinaryJedis.java:255) at redis.clients.jedis.JedisFactory.destroyObject(JedisFactory.java:99) at org.apache.commons.pool2.impl.GenericObjectPool.destroy(GenericObjectPool.java:927) at org.apache.commons.pool2.impl.GenericObjectPool.evict(GenericObjectPool.java:768) at org.apache.commons.pool2.impl.BaseGenericObjectPool$Evictor.run(BaseGenericObjectPool.java:1138) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:834) java.lang.NullPointerException at redis.clients.jedis.BinaryJedis.quit(BinaryJedis.java:255) at redis.clients.jedis.JedisFactory.destroyObject(JedisFactory.java:99) at org.apache.commons.pool2.impl.GenericObjectPool.destroy(GenericObjectPool.java:927) at org.apache.commons.pool2.impl.GenericObjectPool.evict(GenericObjectPool.java:768) at org.apache.commons.pool2.impl.BaseGenericObjectPool$Evictor.run(BaseGenericObjectPool.java:1138) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:834) java.lang.NullPointerException at redis.clients.jedis.BinaryJedis.quit(BinaryJedis.java:255) at redis.clients.jedis.JedisFactory.destroyObject(JedisFactory.java:99) at org.apache.commons.pool2.impl.GenericObjectPool.destroy(GenericObjectPool.java:927) at org.apache.commons.pool2.impl.GenericObjectPool.evict(GenericObjectPool.java:768) at org.apache.commons.pool2.impl.BaseGenericObjectPool$Evictor.run(BaseGenericObjectPool.java:1138) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:834)

我的池配置是:

    final JedisPoolConfig poolConfig = new JedisPoolConfig();
    poolConfig.setMaxTotal(128);
    poolConfig.setMaxIdle(128);
    poolConfig.setMinIdle(16);
    poolConfig.setTestOnBorrow(true);
    poolConfig.setTestOnReturn(true);
    poolConfig.setTestWhileIdle(true);
    poolConfig.setMinEvictableIdleTimeMillis(Duration.ofSeconds(60).toMillis());
    poolConfig.setTimeBetweenEvictionRunsMillis(Duration.ofSeconds(30).toMillis());
    poolConfig.setNumTestsPerEvictionRun(3);

这是我的 jedispool 创建:

new JedisPool(poolConfig, host, port, 1000);

它来自哪里?

让这个问题难以解决的是异常的隐藏部分,

异常应如下所示:

load technicians buffer took 2942 miliseconds : java.lang.NullPointerException 
at co.elastic.apm.agent.redis.RedisSpanUtils.createRedisSpan(RedisSpanUtils.java:xxx)
at redis.clients.jedis.BinaryJedis.ping(BinaryJedis.java:187) 
at redis.clients.jedis.JedisFactory.validateObject(JedisFactory.java:152) 
at org.apache.commons.pool2.impl.GenericObjectPool.returnObject(GenericObjectPool.java:534) 
at redis.clients.jedis.util.Pool.returnResourceObject(Pool.java:68) 
at redis.clients.jedis.JedisPool.returnResource(JedisPool.java:251) 
at redis.clients.jedis.Jedis.close(Jedis.java:3505) 
at .....

原始异常中缺少此行:co.elastic.apm.agent.redis.RedisSpanUtils.createRedisSpan(RedisSpanUtils.java:xxx)

异常发生在Elastic的javaAPM代理中,但是由于代理使用的是Java的InstrumentationAPI,所以没有追踪到异常。

在等待 Elastic 修复问题期间,您可以禁用代理监听 Redis 请求。