一个在大厂作高级Java开发的程序猿
前端
关注微信公众号:IT 老哥java
回复:Java实战项目视频教程:便可获取200G,27套实战项目视频教程程序员
回复:Java 学习路线,便可获取最新最全的一份学习路线图web
回复:Java 电子书,便可领取 13 本顶级程序员必读书籍spring
回复:Java 全套教程,便可领取:Java 基础、Java web、JavaEE 所有的教程,包括 spring boot 等数据库
回复:简历模板,便可获取 100 份精美简历api
你们应该都经历过双十一
吧,那个流量大的恐怖
吧,那个并发高的吓人
吧。那么在一个高并发的系统里,有哪些点是影响系统性能的呢,今天咱们来说其中一个点:自定义异常
微信
首先给你们看一段JDK
的Throwable
源码markdown
public synchronized Throwable fillInStackTrace() {
if (stackTrace != null ||
backtrace != null /* Out of protocol state */ ) {
fillInStackTrace(0);
stackTrace = UNASSIGNED_STACK;
}
return this;
}
复制代码
上面这段JDK
的源码就是抛出异常时会调用的方法,这段方法暴露出两个问题并发
synchronized
修饰整个异常方法JVM
和线程
)这些是咱们自定义的、能够预知的异常,抛出这种异常并不表示系统出了问题,而是正常业务逻辑上的须要,例如用户名密码错误、参数错误等。
每每是运行时异常,好比数据库链接失败、IO 失败、空指针等,这种异常的产生多数表示系统存在问题,须要人工排查定位。
相信你们都接触过异常,对于业务异常,咱们只须要简单的知道一个描述问题的字符串便可,栈追踪信息对咱们的意义并不大。而对于系统异常,追踪信息才是排查错误不可或缺的参考。
你们试想,若是前端传的参数错了,系统里就抛出一个异常,那么在双十一的状况下一秒钟得抛出多少个异常呢?
建立普通 Java 对象 (CustomObject extends HashMap)
建立普通 Java 异常对象(CustomException extends Exception)
建立改进的 Java 业务异常对象 (CustomException extends Exception,覆写 fillInStackTrace 方法,而且去掉同步)
(运行环境:xen 虚拟机,5.5G 内存,8 核;jdk1.6.0_18)
(10 个线程,建立 10000000 个对象所需时间)
45284 MS
205482 MS
16731 MS
你们能够看到正常抛出 Exception 的和覆写了 fillInStackTrace 的 Exception,性能差距了不少倍,若是高并发的系统里,就像雪球同样越滚越大。影响系统的并发量。
咱们来看看很是 NB 的kafka源码
是如何优化的。
/* avoid the expensive and useless stack trace for api exceptions */
/* 翻译:避免对api异常进行昂贵且无用的堆栈跟踪 */
@Override
public Throwable fillInStackTrace() {
return this;
}
复制代码
不少开源框架都是这样处理,避免没必要要的性能浪费。
什么是匠人精神,就是将一件事情作到极致。优化永无止境,且行且珍惜。