大例外背后的真相

异常可能是最被滥用的Java语言功能。 这就是为什么

让我们打破一些神话。 没有牙仙子。 圣诞老人不是真实的。 TODO评论。 finalfinalversion-final.pdf。 无皂肥皂。 而且…例外实际上是例外。 后者可能需要更多说服力,但我们可以帮助您。

在这篇文章中,我们邀请经验丰富的系统架构师和博客的长期朋友(最重要的是, 毛茸茸的帽子的忠实拥护者)Avishai Ish-Shalom加入我们,以快速讨论Java应用程序中异常的当前状态。 。 这是我们发现的。

根据定义,异常与正常情况相去甚远

让我们从Java官方文档的引用开始:“异常是在程序执行期间发生的事件,破坏了正常的指令流程”。 诚实的披露:我们自己添加了上限。

实际上,在大多数应用程序中,正常的指令流充满了这些所谓的“正常”异常的“正常”重复,这些异常会导致“正常”中断。

exception-meme-300x259 @ 2x

在大多数应用程序中,噪声水平越来越高,抛出,记录,然后索引和分析的异常……大多数没有意义。

除了对系统造成不必要的压力外,这种操作噪音还会使您失去与真正重要的异常的联系。 想象一下一个电子商务应用程序发生了一个新的重要异常,该异常开始发生,表示出了点问题并受到影响,例如100个用户无法检出。 现在,用数千个无用的“正常”异常掩盖它,并尝试了解出了什么问题。

例如,大多数应用程序具有“正常”级别的错误事件。 在下面的屏幕截图中,我们可以看到每小时大约有4k个事件:

例外情况

Takipi的错误分析仪表板–错误趋势

如果我们“幸运”,那么一个新的错误会在图中显示为峰值,就像我们在这里一样,在凌晨1点(糟糕)发生IllegalStateException数十万次。 我们可以立即看到导致峰值的原因。

绿线表示事件总数,其余各行表示特定的异常和记录的错误/警告。

危险来自异常,只有很少,很小但致命的实例被掩埋在所谓的“正常”异常级别内。

您所说的这些“正常”例外是什么?

与需要更改代码才能解决的实际错误不同,当今的异常表明了很多其他情况,这些情况实际上并没有任何可行的见解。 他们只会减轻系统负担。 考虑任何有经验的开发人员可以预期的以下两种情况:

  1. 业务错误 –用户/数据可能会执行业务流程所不允许的任何事情。 像任何形式的表单验证一样,在电话号码表单字段中填写文本,用空购物车签出,等等。在内部,NumberFormatException 在我们的最新文章中也排名前10名,排名前 2位在生产环境中为1B 。
  2. 系统错误 –您从操作系统中询问的所有内容都可能说不,这是您无法控制的。 例如,尝试访问您没有权限的文件。

另一方面,真正的异常是您在编写代码时没有意识到的事情,例如OutOfMemoryException甚至是NullPointerException,它们使事情异常混乱。 需要您采取措施解决问题的问题。

Inconceviable-Exceptions-300x278 @ 2x

异常旨在崩溃和燃烧

未捕获的异常会杀死您的线程,甚至在重要线程死机而其余线程都在等待时,甚至可能使整个应用程序崩溃或使其处于某种“僵尸状态”。 有些应用程序知道如何处理,大多数却不知道。

Java中的异常的主要目的是帮助您捕获错误并解决它,而不是跨入应用程序逻辑领域。 它们旨在帮助调试,这就是为什么他们尝试从应用程序的角度包含尽可能多的信息。

这可能造成的另一个问题是状态不一致,当应用程序流变得……跳动时,甚至比goto语句还要糟糕。 它具有相同的缺点,但也有一些曲折:

  1. 它破坏了程序的流程
  2. 很难跟踪和理解下一步会发生什么
  3. 即使有finally块也很难清理
  4. 重量级,与“ goto”不同,它随身携带所有堆栈和其他额外数据

无例外地使用“错误”流程

如果您尝试使用异常处理应由应用程序逻辑处理的可预测情况,那么您会遇到麻烦。 大多数Java应用程序都遇到同样的麻烦。

本书预计不会发生的问题并不是真正的例外。 一个有趣的解决方案来自Scala的Futures –毫无例外地处理错误。 来自官方scala文档的Scala示例:

import scala.util.{Success, Failure}val f: Future[List[String]] = Future {session.getRecentPosts
}f onComplete {case Success(posts) => for (post <- posts) println(post)case Failure(t) => println("An error has occured: " + t.getMessage)
}

将来在内部运行的代码可能会引发异常,但这些异常将被包含在内并且不会泄漏到外部。 Failure(t)分支明确表明了失败的可能性,并且很容易遵循代码执行。

在新的Java 8 CompletableFuture功能(我们最近才写过)中,我们可以使用completeExceptionally(),尽管它不那么漂亮。

使用API​​时情节变得更浓

假设我们有一个使用库进行数据库访问的系统,那么数据库库如何将其错误暴露给外界? 欢迎来到狂野的西部。 并且请记住,库可能仍然会引发一般错误,例如java.net.UnknownHostException或NullPointerException

一个现实的例子是如何解决这个问题的是包装JDBC的库,它只是抛出一个通用的DBException而没有给您机会让您知道出了什么问题。 也许一切都很好,并且只有连接错误,或者……您实际上需要更改一些代码。

常见的解决方案是使用基本异常(例如DBException)的数据库库,该库异常将从中继承。 这使库用户可以使用一个try块捕获所有库错误。 但是,可能导致库错误的系统错误呢? 常见的解决方案是将发生的任何异常包装起来。 因此,如果它无法解析DNS地址(更多是系统错误,然后是库错误),它将捕获该地址并抛出此更高级别的异常-库用户应该知道该异常。 尝试捕获恶梦,带有嵌套异常的提示包装了其他异常。

如果我们将Actors混合在一起,则控制流程甚至变得更加混乱。 带有异常的异步编程是一团糟。 它可以杀死一个Actor ,然后重新启动它,一条消息将以原始错误发送给其他Actor ,您将丢失堆栈。

所以你能对它做点啥?

从头开始并避免不必要的异常总是很容易,但是很可能并非如此。 使用现有的系统(例如使用5年的应用程序),您将需要进行大量的管道工作(如果幸运的话,并获得管理部门的批准以解决噪音问题)。

理想情况下,我们希望所有异常都是可操作的,也就是说,推动将阻止它们再次发生的操作,而不仅仅是承认有时会发生这些事情。

综上所述,不可操作的异常会引起很多混乱:

  • 性能
  • 稳定性
  • 监控/日志分析
  • 而且...隐藏您要查看并采取行动的真实异常

生活是痛苦768x432

解决方案是…进行艰苦的工作,以消除噪音并创建更有意义的控制流。 另一个创造性的解决方案是更改日志级别,如果这不是可行的异常,请不要将其记录为错误。 那只是一个装饰性的解决方案,但可以使您完成80%的工作。

归根结底,日志和仪表板只是装饰,需要解决该问题的核心并完全避免无法采取行动的异常。

在塔基皮(Takipi),我们最近发现,平均记录的错误中有97%来自前10个唯一错误 。 要检查应用程序中异常和已记录错误的当前状态,请附加Takipi代理,您将在几分钟内完全了解代码在生产环境中的行为方式(以及如何修复)。 检查一下 。

最后的想法

最重要的是,您是否有一个不会导致代码更改的异常? 您甚至不应该浪费时间查看它。

这篇文章是基于Avishai所说的“可操作的异常”的闪电演讲:

翻译自: https://www.javacodegeeks.com/2016/06/truth-behind-big-exceptions-lie.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/353704.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB里面的filter和filtfilt的C语言源代码

MATLAB里面的filter和filtfilt的C语言源代码 嗯&#xff0c;算法非常简单&#xff0c;就是网上搜不到C代码实现。filter是个很万能的数字滤波器函数&#xff0c;只要有滤波器的差分方程系数&#xff0c;IIR呀FIR呀都能通过它实现。在MATLAB里面&#xff0c;filter最常用的格式是…

20172302『Java程序设计』课程 结对编程练习_四则运算第二周阶段总结

一.结对对象 姓名&#xff1a;周亚杰学号&#xff1a;20172302担任角色&#xff1a;驾驶员&#xff08;周亚杰&#xff09;伙伴第二周博客地址二.本周内容 (一)继续编写上周未完成代码 1.本周继续编写代码&#xff0c;使代码支持分数类计算 2.相关过程截图 a.下图是上周编写的生…

实践中的弹性基础架构

几周前&#xff0c;我获得了一个难得的机会&#xff0c;可以在基础设施领域弄脏双手。 在JVM内部的深入了解下&#xff0c;我每天的工作经历发生了有趣的变化&#xff0c;我想与您分享动机和成果。 希望它可以启发类似的问题类别。 背景 我将从解释需要解决方案的上下文开始。…

notepad++插件实现json、xml格式化

notepad比较出色的免费的数据编辑、格式化工具。。。 现在json、xml文件很流行、格式化也是必须的&#xff0c;方便查看关键信息&#xff01; 01、下载notepad及相关插件 npp_7.5.5-x86&#xff1a; https://files.cnblogs.com/files/xiaochina/npp_7.5.5-x86.zip npp-json:…

ActiveMQ 5.x中的消息持久性

我被问了很多关于ActiveMQ如何存储消息&#xff08;或在某些情况下不存储&#xff09;的基本知识。 这是它的高级解释。 注意&#xff0c;上下文在JMS中。 如果您使用ActiveMQ的非JMS客户端&#xff08;即STOMP&#xff0c;AMQP&#xff0c;MQTT等&#xff09;&#xff0c;则在…

一个select元素自定义设计的新思路:appearance: none之后利用符号制造小箭头

最近工作时解决了一个前端小问题&#xff08;如下图所示&#xff09;&#xff1a;在Safari中&#xff0c;select的控件之上有不和谐的灰色部分。 刚开始时我以为是backgrand或是border设置不当之类产生的问题&#xff0c;在搜索了很久之后终于找到了问题所在&#xff1a;这个灰…

调整HashMap的大小:未来的危险

最近&#xff0c;我偶然发现了一个错误&#xff0c;该错误是由于多个线程对java.util.HashMap的使用不当引起的。 该错误是抽象泄漏的一个很好的例子。 只有了解数据结构的实现级别详细信息&#xff0c;才能帮助我解决当前的问题。 因此&#xff0c;我希望分享我所面临的问题将…

别的程序员是怎么读你的简历的

别的程序员是怎么读你的简历的 2009年11月9日 陈皓 下面这个图片来源国外&#xff0c;是一个关于程序员面试时的简历&#xff0c;被人事部门和程序员本身评审的角度不同的图片。当然&#xff0c;这是一个从国外面试的视角制作的图片&#xff0c;不过&#xff0c;可以看出&#…

Zabbix linux agent 安装

系统&#xff1a;Linux Centos 7.3 x64 服务&#xff1a;Zabbix_agent 3.0.16 一.安装Zabbix_agent 服务 1.安装zabbix 3.0 yum源 rpm -ivh http://repo.zabbix.com/zabbix/3.0/rhel/7/x86_64/zabbix-release-3.0-1.el7.noarch.rpm 2.安装Zabbix_agent yum install zabbix-agen…

直接在apk中添加资源的研究

原文 http://blog.votzone.com/2018/05/12/apk-merge.html 之前接手过一个sdk的开发工作&#xff0c;在开发过程中有一个很重要的点就是尽量使用代码来创建控件&#xff0c;资源文件最好放到assets目录下&#xff0c;如果必须使用res资源&#xff0c;需要通过 getResources().g…

JavaFX实际应用程序:SkedPal

“真实世界的应用程序”系列中的一个新条目。 这次是SkedPal &#xff0c;这是一个用于智能管理忙人生活的应用程序。 我一直在咨询SkedPal团队有关JavaFX的事宜&#xff0c;并且在他们决定开始使用我的CalendarFX框架来满足他们的日历要求时&#xff0c;我也在咨询他们。 在下…

chromium之histogram.h

histogram不知道是干啥的 // Histogram is an object that aggregates statistics, and can summarize them in // various forms, including ASCII graphical, HTML, and numerically (as a // vector of numbers corresponding to each of the aggregating buckets). google翻…

viewobject_只读ViewObject和声明性SQL模式

viewobject介绍 声明式SQL模式被认为是基于实体的视图对象的最有价值的优点之一。 在这种模式下&#xff0c;根据UI中显示的属性在运行时生成VOSQL。 例如&#xff0c;如果某个页面包含一个只有两列EmployeeId和FirstName的表&#xff0c;则查询将生成为“从Employees中选择Emp…

MyEclipse6.0 安装axis2插件, 调用加密的SAP webservice

MyEclipse6.0 安装axis2插件, 调用加密的SAP webservice 6人收藏此文章, 我要收藏 发表于1个月前(2013-06-06 09:41) , 已有116次阅读 &#xff0c;共0个评论 首先鄙视一下自己&#xff0c;还在用myeclipse,竟然还是6.0版本&#xff0c;没办法&#xff0c;用习惯了&#xff0c…

Eclipse中要导出jar包中引用了第三方jar包怎么办

Eclipse中要导出jar包中引用了第三方jar包怎么办 (2009-07-20 15:28:44) 转载▼标签&#xff1a; it 分类&#xff1a; Eclipse 今天做个小的java程序&#xff0c;想要先将其导出成一个可执行的jar包&#xff01;向往常一样&#xff0c;单击菜单栏中的 File -> export,弹出…

拖动滑块拼图背景图没显示_计划B? 那是计划N…没什么。 拼图于2015年问世

拖动滑块拼图背景图没显示真是一天 当典型的欧洲人逐渐破产时&#xff0c;美国的人们开始喝咖啡。 这就是为什么我在Mark Reinhold最近的新闻中睡个好觉的原因。 他在题为“ Project Jigsaw&#xff1a;火车晚点 ”的帖子中建议将Project Jigsaw推迟到下一个版本Java 9。 在最近…

java keytool证书工具使用小结

Keytool 是一个Java数据证书的管理工具 ,Keytool将密钥&#xff08;key&#xff09;和证书&#xff08;certificates&#xff09;存在一个称为keystore的文件中在keystore里&#xff0c;包含两种数据:密钥实体&#xff08;Key entity&#xff09;-密钥&#xff08;secret key&a…

在Kafka中发布订阅模型

这是第四个柱中的一系列关于同步客户端集成与异步系统&#xff08; 1&#xff0c; 2&#xff0c; 3 &#xff09;。 在这里&#xff0c;我们将尝试了解Kafka的工作方式&#xff0c;以便正确利用其发布-订阅实现。 卡夫卡概念 根据官方文件 &#xff1a; Kafka是一种分布式的&…

深入理解C++中的mutable关键字

2006-12-16 05:00 来源&#xff1a;BLOG 作者&#xff1a;寒星轩 责任编辑&#xff1a;方舟yesky 评论(32)推荐&#xff1a;经典教程专区mutalbe的中文意思是“可变的&#xff0c;易变的”&#xff0c;跟constant&#xff08;既C中的const&#xff09;是反义词。在C中&…

使用Boxfuse为您的REST API设置https

在我的上 一篇 文章中&#xff0c;我展示了在Boxfuse的帮助下&#xff0c;基于Spring Boot框架建立REST API并在AWS上运行非常容易 。 下一步是利用SSL与API进行通信。 通过使用SSL&#xff0c;我们确保在REST API服务器和API客户端之间的传输过程中保存了数据 。 要为Spring B…