自从运维引入了Pinpoint这个链路跟踪开源工具,钉钉告警一直在响,搞得人都快崩溃了。自己检查了代码也没有什么问题,该抛出的异常该处理的异常都处理了啊,检查了线上的日志,发现一个NullPointerException的提示。但是这个是try{}catch之后打印的错误日志。Pinpoint在A方法调用B方法的过程中,B方法出现了异常,A中虽然try{}catch住处理了,但是Pinpoint还是会告警。
A方法代码:
protected PandaCrawlerTask getCrawlerTask(UUID taskId) {
PandaCrawlerTask crawlerTask = null;
try {
crawlerTask = workerTaskRedisHandler.getCrawlerTask(taskId);
} catch (Exception e) {
log.error("action=getCrawlerTask, task_id:{} get task from redis occur exception", taskId, e);
}
return crawlerTask;
}
B方法代码:
@Override
public PandaCrawlerTask getCrawlerTask(UUID taskId) throws MoxieCrawlerException {
if (taskId == null) {
throw new MoxieCrawlerException(CrawlerInternalError.BAD_TASKID, "任务ID不存在");
}
String redisKey = String.format("%s%s", PandaRedisKeyUtils.getTaskConfigKey(crawlerServiceProperties.getServiceType()), taskId);
JedisCommands commands = null;
try {
commands = JedisUtils.getJedisCommands(jedisCluster, jedisPool);
String crawlerTask = commands.get(redisKey);
return objectMapper.readValue(crawlerTask, PandaCrawlerTask.class);
} catch (JedisException e) {
log.error("action=getCrawlerTask, task_id={}, get task task failed", taskId, e);
throw new MoxieCrawlerException(CrawlerInternalError.REDIS_FAILED, e);
} catch (IOException e) {
log.error("action=getCrawlerTask, task_id={}, serialize task failed", taskId, e);
throw new MoxieCrawlerException(CrawlerInternalError.CONVERT_ERROR, e);
} finally {
JedisUtils.releaseJedisConnection(commands);
}
return null;
}
产生的空指针的原因:
由于任务处理超时会从redis队列中移除,然后String crawlerTask = commands.get(redisKey)
获取到的是null,再使用ObjectMapper把json字符串(此时为空)转化为对象就出现了异常。B方法虽然没有catch空指针的异常,但是A方法catch住了。
网友评论