专栏名称: ImportNew
伯乐在线旗下账号,专注Java技术分享,包括Java基础技术、进阶技能、架构设计和Java技术领域动态等。
目录
相关文章推荐
芋道源码  ·  一直傻傻分不清 count(*) ... ·  2 天前  
芋道源码  ·  Web 实时消息推送的 7 种实现方案 ·  2 天前  
芋道源码  ·  今年这情况。。大家多一手准备吧 ·  2 天前  
芋道源码  ·  为什么很多程序员讨厌低代码? ·  3 天前  
Java编程精选  ·  某华为od吐槽:我双非在华为OD觉得委屈想走 ... ·  4 天前  
51好读  ›  专栏  ›  ImportNew

高并发下的九死一生,一个不小心就掉入万丈深渊

ImportNew  · 公众号  · Java  · 2017-01-12 20:04

正文

(点击 上方公众号 ,可快速关注)


源:左潇龙,

www.cnblogs.com/zuoxiaolong/p/con1.html

如有好文章投稿,请点击 → 这里了解详情


引言


每次开篇LZ都会先说一下自己最近很忙,所以才没有时间写博客。这次这些话就不多说了,我们直入主题,尽管LZ依旧是非常的繁忙…


了解LZ的猿友应该都知道,LZ最近弄了一个hbase(不理解hbase的猿友可以把hbase当做与oracle,mysql,sqlserver等一样的数据库,并不影响阅读本文)的大数据平台,或许现在叫平台还有点名不副实,不过它很快就会发展到这个规模,LZ一直坚信着。在建立这个平台的过程中,LZ遇到过各种千奇百怪的问题,在这里LZ就分享一个非常简单,但却很奇葩的问题。


问题来源


问题的来源特别简单,LZ为了迎合模块化开发的思想,做了很多独立的模块,这些模块以jar包的形式协同工作,类似于spring当中的spring-core,spring-beans,spring-context等等。


在LZ的一个common包中,有这样的一个工具类,代码如下。(备注:LZ为了简单,去掉了很多跟本文无关的代码,但不影响阅读,因为这个类就是一些静态的工具类方法,主要用于处理日期)


public class DateUtil {

private DateUtil(){}

private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

public static Date parse(String date)  throws ParseException {

return DATE_FORMAT.parse(date);

}

}


这个类特别简单,相信有不少猿友都会觉得这个类没有多大问题。因为这段代码太简单了,当你的项目报错的时候,你很难想到这段代码就是错误的根源。很显然,LZ就在hbase的应用中使用了这个工具类,结果就导致了一个奇葩问题。


大致描述一下这个工具类使用的场景。LZ的hbase应用接收了来自于其它系统大量的日志信息,并会将这些日志信息存储在hbase当中,其实就是一个简单的日志保存功能。如果单纯从功能上来讲,就是一个简单的curd(增删改查)操作中的c(增)操作。唯一不同的是,由于存储的是来自很多系统的系统日志,webservice日志,mq日志,url访问日志,因此并发量会有点高,至少比LZ平时做的企业应用要高太多太多了。


这个工具类就是在解析日志信息中的日期字符串(比如日志的发生时间)时报的错,具体的错误信息如下。(备注:以下是真实的报错信息,显示的错误位置与上面的代码不符,不过各位猿友完全可以认为就是上面的方法报的错,因为事实上parseTimestamp这个方法就和上面方法的代码是一样的。)


java.lang.NumberFormatException: For input string: ""

at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)

at java.lang.Long.parseLong(Long.java:431)

at java.lang.Long.parseLong(Long.java:468)

at java.text.DigitList.getLong(DigitList.java:177)

at java.text.DecimalFormat.parse(DecimalFormat.java:1297)

at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1589)

at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1311)

at java.text.DateFormat.parse(DateFormat.java:335)

at com.xxxxxxx.core.common.util.DateUtil.parseTimestamp(DateUtil.java:95)

at com.xxxxxxx.core.common.util.DateUtil.parse(DateUtil.java:84)

at com.xxxxxxx.hbase.generator.LogRowKeyGenerator.generate(LogRowKeyGenerator.java:21)

... 22 more


问题分析


看到这个错误,大部分老道一点的程序猿一眼就能定位问题,肯定是传过来的日期格式不对,所以导致在解析的时候出错了。


LZ自认为还算老道吧(小小的自夸一下),自然也很快的意识到了问题的根源。于是最简单的方式,调试一下代码,看传过来的日志信息到底是什么样子。


LZ在catch块里加入了断点,当报出这个错误的时候,会进入调试(只能在catch块里捕捉,因为这个异常是时而出现的,而且毫无规律)。但是结果很意外,LZ仔细且认真的看了传送过来的日志信息,日期格式却明明是正确的。这时候LZ就傻眼了,格式明明是正确的,解析怎么可能报错呢?


LZ不相信这种奇怪的问题,于是LZ采用最简单的办法,希望印证心中所想,将代码改成如下的样子。


public class DateUtil {

private DateUtil(){}

private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");







请到「今天看啥」查看全文