plsql例外_大例外背后的真相
plsql例外
異常可能是最被濫用的Java語言功能。 這就是為什么
讓我們打破一些神話。 沒有牙仙子。 圣誕老人不是真實(shí)的。 TODO評論。 finalfinalversion-final.pdf。 無皂肥皂。 而且…例外實(shí)際上是例外。 后者可能需要更多說服力,但是我們可以幫助您。
在這篇文章中,我們請經(jīng)驗(yàn)豐富的系統(tǒng)架構(gòu)師和博客的長期朋友(最重要的是, 毛茸茸的帽子的忠實(shí)擁護(hù)者)Avishai Ish-Shalom加入我們,以快速討論Java應(yīng)用程序中異常的當(dāng)前狀態(tài)。 。 這是我們發(fā)現(xiàn)的。
根據(jù)定義,異常與正常情況相去甚遠(yuǎn)
讓我們從Java官方文檔的引用開始:“異常是在程序執(zhí)行期間發(fā)生的事件,破壞了正常的指令流程”。 誠實(shí)的披露:我們自己添加了上限。
實(shí)際上,在大多數(shù)應(yīng)用程序中,正常的指令流充滿了這些所謂的“正?!碑惓5摹罢!敝貜?fù),這些異常會導(dǎo)致“正常”中斷。
在大多數(shù)應(yīng)用程序中,噪聲水平越來越高,拋出,記錄,然后索引和分析的異?!蠖鄶?shù)沒有意義。
除了對系統(tǒng)造成不必要的壓力外,這種操作噪音還會使您失去與真正重要的異常的聯(lián)系。 想象一下一個(gè)電子商務(wù)應(yīng)用程序發(fā)生了一個(gè)新的重要異常,該異常開始發(fā)生時(shí),表明出現(xiàn)了問題并受到影響,例如100個(gè)用戶無法檢出。 現(xiàn)在,用數(shù)千個(gè)無用的“正常”異常掩蓋它,并嘗試了解出了什么問題。
例如,大多數(shù)應(yīng)用程序具有“正?!奔墑e的錯(cuò)誤事件。 在下面的屏幕截圖中,我們可以看到每小時(shí)大約有4k個(gè)事件:
Takipi的錯(cuò)誤分析儀表板–錯(cuò)誤趨勢
如果我們“幸運(yùn)”,那么一個(gè)新的錯(cuò)誤會在圖中顯示為尖峰,就像我們在這里一樣,在凌晨1點(diǎn)左右(一次)發(fā)生IllegalStateException,發(fā)生了數(shù)十萬次。 我們可以立即看到導(dǎo)致峰值的原因。
綠線表示事件總數(shù),其余各行表示特定的異常和記錄的錯(cuò)誤/警告。
危險(xiǎn)來自異常,只有很少,很小但致命的實(shí)例被掩埋在所謂的“正?!碑惓<墑e內(nèi)。
您所說的這些“正常”例外是什么?
與需要更改代碼才能解決的實(shí)際錯(cuò)誤不同,如今的異常表明了很多其他情況,這些情況實(shí)際上并沒有任何可行的見解。 他們只會減輕系統(tǒng)壓力。 考慮任何有經(jīng)驗(yàn)的開發(fā)人員可以預(yù)期的以下兩種情況:
另一方面,真正的異常是您在編寫代碼時(shí)沒有意識到的事情,例如OutOfMemoryException甚至是NullPointerException,它們使事情意外地混亂了。 需要您采取措施解決問題的問題。
異常旨在崩潰和燃燒
未捕獲的異常會殺死您的線程,甚至在重要線程死機(jī)而其余線程仍在等待時(shí),甚至可能使整個(gè)應(yīng)用程序崩潰或使其處于某種“僵尸狀態(tài)”。 有些應(yīng)用程序知道如何處理,大多數(shù)卻不知道。
Java中的異常的主要目的是幫助您捕獲錯(cuò)誤并解決它,而不是跨入應(yīng)用程序邏輯領(lǐng)域。 它們旨在幫助調(diào)試,這就是為什么他們嘗試從應(yīng)用程序的角度包含盡可能多的信息。
這可能造成的另一個(gè)問題是狀態(tài)不一致,當(dāng)應(yīng)用程序流變得……跳動時(shí),甚至比goto語句還要糟糕。 它具有相同的缺點(diǎn),但也有一些曲折:
無例外地使用“錯(cuò)誤”流程
如果您嘗試使用異常處理應(yīng)由應(yīng)用程序邏輯處理的可預(yù)測情況,那么您會遇到麻煩。 大多數(shù)Java應(yīng)用程序都遇到同樣的麻煩。
本書預(yù)計(jì)不會發(fā)生的問題并不是真正的例外。 一個(gè)有趣的解決方案來自Scala的Futures –毫無例外地處理錯(cuò)誤。 來自官方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) }將來在內(nèi)部運(yùn)行的代碼可能會引發(fā)異常,但這些異常將被包含在內(nèi)并且不會泄漏到外部。 Failure(t)分支明確表明了失敗的可能性,并且很容易遵循代碼執(zhí)行。
在新的Java 8 CompletableFuture特性(我們最近才寫過)中,我們可以使用completeExceptionally(),盡管它不那么漂亮。
使用API??可以使圖變得更厚
假設(shè)我們有一個(gè)使用庫進(jìn)行數(shù)據(jù)庫訪問的系統(tǒng),那么數(shù)據(jù)庫庫如何將其錯(cuò)誤暴露給外界? 歡迎來到狂野的西部。 并且請記住,該庫可能仍會引發(fā)一般錯(cuò)誤,例如java.net.UnknownHostException或NullPointerException
現(xiàn)實(shí)生活中的一個(gè)例子就是一個(gè)包裝JDBC的庫,該庫包裝了JDBC,只是拋出了一個(gè)通用的DBException,而沒有讓您有機(jī)會知道出什么問題了。 也許這一切都很好,并且存在連接錯(cuò)誤,或者……您實(shí)際上需要更改一些代碼。
常見的解決方案是使用基本異常(例如DBException)的數(shù)據(jù)庫庫,該庫異常將從中繼承。 這允許庫用戶使用一個(gè)try塊捕獲所有庫錯(cuò)誤。 但是,可能導(dǎo)致庫錯(cuò)誤的系統(tǒng)錯(cuò)誤呢? 常見的解決方案是將發(fā)生的任何異常包裝起來。 因此,如果它無法解析DNS地址(更多是系統(tǒng)錯(cuò)誤,然后是庫錯(cuò)誤),它將捕獲該地址并拋出此更高級別的異常-庫用戶應(yīng)該知道要捕獲該異常。 嘗試捕獲惡夢,帶有嵌套異常的提示包裝了其他異常。
如果我們將Actors混合在一起,則控制流程甚至變得更加混亂。 帶有異常的異步編程是一團(tuán)糟。 它可以殺死一個(gè)Actor ,然后重新啟動它,一條消息將以原始錯(cuò)誤發(fā)送給其他Actor ,您將丟失堆棧。
所以你能對它做點(diǎn)啥?
從頭開始并避免不必要的異常總是很容易,但是很可能并非如此。 使用現(xiàn)有的系統(tǒng)(例如使用5年的應(yīng)用程序),您將需要進(jìn)行大量的管道工作(如果幸運(yùn)的話,并獲得管理部門的批準(zhǔn)以解決噪音問題)。
理想情況下,我們希望所有異常都是可操作的,也就是說,驅(qū)動將阻止它們再次發(fā)生的操作,而不僅僅是承認(rèn)有時(shí)會發(fā)生這些事情。
綜上所述,不可操作的異常會引起很多混亂:
- 性能
- 穩(wěn)定性
- 監(jiān)控/日志分析
- 而且...隱藏您要查看并采取行動的真實(shí)異常
解決方案是…進(jìn)行艱苦的工作,以消除噪音并創(chuàng)建更有意義的控制流。 另一個(gè)創(chuàng)造性的解決方案是更改日志級別,如果這不是可行的例外,請不要將其記錄為錯(cuò)誤。 那只是一個(gè)裝飾性的解決方案,但可能會讓您完成80%的工作。
歸根結(jié)底,日志和儀表板只是裝飾,需要解決該問題的核心并完全避免無法采取行動的異常。
在塔基皮(Takipi),我們最近發(fā)現(xiàn)平均記錄的錯(cuò)誤中有97%來自前10個(gè)唯一錯(cuò)誤 。 要查看應(yīng)用程序中異常和已記錄錯(cuò)誤的當(dāng)前狀態(tài),請連接Takipi代理,您將在幾分鐘內(nèi)完全了解代碼在生產(chǎn)環(huán)境中的行為方式(以及如何修復(fù))。 檢查一下 。
最后的想法
最重要的是,您是否有一個(gè)不會導(dǎo)致代碼更改的異常? 您甚至不應(yīng)該浪費(fèi)時(shí)間查看它。
這篇文章是基于Avishai所說的“可操作的異常”的閃電演講:
翻譯自: https://www.javacodegeeks.com/2016/06/truth-behind-big-exceptions-lie.html
plsql例外
總結(jié)
以上是生活随笔為你收集整理的plsql例外_大例外背后的真相的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: activiti脚本任务_Activit
- 下一篇: 安卓竖屏锁定哪里设置(安卓竖屏)