精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Service 層的異常是拋到 Controller 層還是直接處理?

開發
Java因為Checked Exception設計問題不得不避免使用,而Uncaughted Exception實在是太過于弱雞,是不能給程序員提供更好地幫助的。

1 前言

一般初學者學習編碼和 錯誤處理 時,先知道 編程語言 有一種處理錯誤的形式或約定(如Java就拋異常),然后就開始用這些工具。但卻忽視這問題本質:處理錯誤是為了寫正確程序。可是

2 啥叫“正確”?

由解決的問題決定的。問題不同,解決方案不同。

如一個web接口接受用戶請求,參數age,也許業務要求字段是0~150之間整數。如輸入字符串或負數就肯定不接受。一般在后端某地做輸入合法性檢查,不過就拋異常。

但歸根到底這問題“正確”解決方法總是要以某種形式提示用戶。而提示用戶是某種前端工作,就要看界面是app,H5+AJAX還是類似于[jsp]的服務器產生界面。不管啥,你要根據需求去”設計一個修復錯誤“的流程。

如一個常見的流程要后端拋異常,然后一路到某個集中處理錯誤的代碼,將其轉換為某個HTTP的錯誤(業務錯誤碼)提供給前端,前端再映射做”提示“。如用戶輸入非法請求,從邏輯上后端都沒法自己修復,這是個“正確”的策略。

3 報500了嘞!

如用戶上傳一個頭像,后端將圖片發給[云存儲],結果云存儲報500,咋辦?你可能想重試,因為也許僅是[網絡抖動],重試就能正常執行。但若重試多次無效,若設計了某種熱備方案,可能改為發到另一個服務器。“重試”和“使用備份的依賴”都是“立刻處理“。

但若重試無效,所有的[備份服務]也無效,也許就能像上面那樣把錯誤拋給前端,提示用戶“服務器開小差”。從這方案易看出,你想把錯誤拋到哪里是因為那個catch的地方是處理問題最方便的地方。一個問題的解決方案可能要幾個不同的錯誤處理組合起來才能辦到。

4 NPE了!

你的程序拋個NPE。這一般就是程序員的bug:

  • 要不就是程序員想表達一個東西”沒有“,結果在后續處理中忘判斷是否為null
  • 要不就是在寫代碼時覺得100%不可能為null的地方出現了一個null

不管哪種,這錯誤用戶總會看到一個很含糊的報錯信息,這遠遠不夠。“正確”辦法是程序員自己能盡快發現它,并盡快修復。要做到這點,需要[監控系統]不斷爬log,把問題報警出來。而非等用戶找客服投訴。

5 OOM了!

比如你的[后端程序]突然OOM掛了。掛的程序沒法恢復自己。要做到“正確”,須在服務之外的容器考慮這問題。

如你的服務跑在[k8s],他們會監控你程序狀態,然后重啟新的服務實例彌補掛掉的服務,還得調整流量,把去往宕機服務的流量切換到新實例。這的恢復因為跨系統所以不能僅用異常實現,但道理一樣。

但光靠重啟就“正確”了?若服務是完全無狀態,問題不大。但若有狀態,部分用戶數據可能被執行一半的請求搞亂。因此重啟要留意先“恢復數據到合法狀態”。這又回到你要知道咋樣才是“正確”的做法。只依靠簡單的語法功能不能無腦解決這事。

6 提升維度

  • 一個工作線程的“外部容器“是管理工作線程的“master”
  • 一個網絡請求的“外部容器”是一個Web Server
  • 一個用戶進程的“外部容器”是[操作系統]
  • Erlang把這種supervisor-worker的機制融入到語言的設計

Web程序很大程度能把異常拋給頂層,是因為:

  • 請求來自前端,對因為用戶請求有誤(數據合法性、權限、用戶上下文狀態)造成的問題,最終基本只能告訴用戶。因此拋異常到一個集中處理錯誤的地方,把異常轉換為某個業務錯誤碼的方法,合理
  • 后端服務一般無狀態。這也是軟件系統設計的一般原則。無狀態才意味著可隨時隨地安心重啟。用戶數據不會因為因為下一條而會出問題
  • 后端對數據的修改依賴DB的事務。因此一個改一半的、沒提交的事務不會造成副作用。

但這3條件并非總成立。總能遇到:

  • 一些處理邏輯并非無狀態
  • 也并非所有的數據修改都能用一個事務保護

尤其要注意對[微服務]的調用,對內存狀態「的修改是沒有事務保護的」,一不留神就會搞亂用戶數據。比如下面代碼段

7 難以排查的代碼段

try {    
   int res1 = doStep1();    
   this.status1 += res1;    
   int res2 = doStep2();    
   this.status2 += res2;    
   // 拋個異常    
   int res3 = doStep3();    
   this.status3 = status1 + status2 + res3;    
} catch ( ...) {     
   // ...    
}

先假設status1、status2、status3之間需維護某種不變的約束(invariant)。然后執行這段代碼時,如在doStep3拋異常,下面對status3的賦值就不會執行。這時如不能將status1、status2的修改rollback,就會造成數據違反約束的問題。

而程序員很難發現這個數據被改壞了。壞數據還可能導致其他依賴這數據的代碼邏輯出錯(如原本應該給積分的,卻沒給)。而這種錯誤一般很難排查,從大量數據里找到不正確的那一小段何其困難。

8 更難搞定的代碼段

// controller    
void controllerMethod(/* 參數 */) {    
  try {    
    return svc.doWorkAndGetResult(/* 參數 */);    
  } catch (Exception e) {    
    return ErrorJsonObject.of(e);    
  }    
}    
    
// svc    
void doWorkAndGetResult(/* some params*/) {    
    int res1 = otherSvc1.doStep1(/* some params */);    
    this.status1 += res1;    
    int res2 = otherSvc2.doStep2(/* some params */);    
    this.status2 += res2;    
    int res3 = otherSvc3.doStep3(/* some params */);    
    this.status3 = status1 + status2 + res3;    
    return SomeResult.of(this.status1, this.status2, this.status3);    
}

難搞在于你寫的時候可能以為doStep1~3這種東西即使拋異常也能被Controller里的catch。

在svc這層是不用處理任何異常,因此不寫[try……catch]天經地義。但實際上doStep1、doStep2、doStep3任何一個拋異常都會造成svc的數據狀態不一致。甚至你一開始都可以通過文檔或其他溝通確定doStep1、doStep2、doStep3一開始都是必然可成功,不會拋錯的,因此你寫的代碼一開始是對的。

但你可能無法控制他們的實現(如他們是另外一個團隊開發的[jar]提供的),而他們的實現可能會改成拋錯。你的代碼可能在完全不自知情況下從“不會出問題”變成“可能出問題”…… 更可怕的類似代碼不能正確工作:

void doWorkAndGetResult(/* some params*/) {    
    try {    
       int res1 = otherSvc1.doStep1(/* some params */);    
       this.status1 += res1;    
       int res2 = otherSvc2.doStep2(/* some params */);    
       this.status2 += res2;    
       int res3 = otherSvc3.doStep3(/* some params */);    
       this.status3 = status1 + status2 + res3;    
       return SomeResult.of(this.status1, this.status2, this.status3);    
   } catch (Exception e) {    
     // do rollback    
   }    
}

你以為這樣就會處理好數據rollback,甚至「覺得這種代碼優雅」。但實際上doStep1~3每一個地方拋錯,rollback的代碼都不一樣。

得這么寫

void doWorkAndGetResult(/* some params*/) {    
    int res1, res2, res3;    
    try {    
       res1 = otherSvc1.doStep1(/* some params */);    
       this.status1 += res1;    
    } catch (Exception e) {    
       throw e;    
    }    
    
    try {    
      res2 = otherSvc2.doStep2(/* some params */);    
      this.status2 += res2;    
    } catch (Exception e) {    
      // rollback status1    
      this.status1 -= res1;    
      throw e;    
    }    
      
    try {    
      res3 = otherSvc3.doStep3(/* some params */);    
      this.status3 = status1 + status2 + res3;    
    } catch (Exception e) {    
      // rollback status1 & status2    
      this.status1 -= res1;    
      this.status2 -= res2;    
      throw e;    
   }     
}

這才是得到正確結果的代碼,在任何地方出錯都能維護數據一致性。優雅嗎?

看起來很丑。比go的if err != nil還丑。但要在正確性和優雅性取舍,肯定毫不猶豫選前者。作為程序員不能直接認為拋異常可解決任何問題,須學會寫出有正確邏輯的程序,哪怕很難且看起來丑。

為達成高正確性,你不能總將自己大部分注意力放在“一切都OK的流程“,而把錯誤看作是可隨便應付了事的工作或簡單的相信exception可自動搞定一切。

9總結

希望程序員們對錯誤處理都要有敬畏之心。Java因為Checked Exception設計問題不得不避免使用,而Uncaughted Exception實在是太過于弱雞,是不能給程序員提供更好地幫助的

因此,程序員在每次拋錯或者處理錯誤的時候都要三省吾身:

  • 這個錯誤的處理是正確的嗎?
  • 會讓用戶看到什么?
  • 會不會搞亂數據?

不要以為自己拋了個異常就不管了。在[編譯器]不能幫上太多忙的時候,好好寫UT來保護代碼脆弱的正確性。

為人為己,請多寫正確的代碼

責任編輯:張燕妮 來源: 互聯網架構小馬哥
相關推薦

2024-07-29 08:02:07

Service類型開發

2019-07-09 13:54:19

網絡模型網絡協議TCP

2019-07-16 10:42:02

網絡模型TCP

2020-08-31 08:42:21

Node Controller數據校驗

2020-11-19 09:07:56

Service接口CTO

2023-04-06 15:19:51

2024-03-26 08:17:00

Controller參數校驗

2010-09-07 14:33:30

DIVmargin

2009-06-12 18:53:35

Django控制層Django表現層

2024-05-07 08:43:30

Service分層設計接口

2024-11-27 13:01:22

應用層領域層對接層

2014-10-11 17:06:07

交換機

2011-12-02 10:58:55

交換機

2016-11-29 15:22:47

協議應用層安全層

2014-07-24 09:38:34

2012-11-12 11:26:44

2025-01-02 10:24:54

Spring控制器單元測試

2022-03-04 08:31:07

Spring異常處理

2021-01-29 08:09:32

Service接口表現層

2019-08-09 16:14:33

MySQLServer存儲
點贊
收藏

51CTO技術棧公眾號

国产私拍一区| 日韩精品在线免费观看| 中文精品一区二区三区| 精品毛片在线观看| 99视频一区| 亚洲欧洲日本专区| 小明看看成人免费视频| 性欧美1819sex性高清大胸| 本田岬高潮一区二区三区| 琪琪第一精品导航| 丝袜 亚洲 另类 欧美 重口| 清纯唯美亚洲经典中文字幕| 欧美日韩一区二区三区不卡| 亚洲人成无码网站久久99热国产 | 日韩欧美一二区| 5月婷婷6月丁香| 免费网站免费进入在线| 99国产精品国产精品久久| 国产精品久久久久久久久久久久 | 亚洲经典视频在线观看| 国产一区二区三区在线免费观看 | 欧美精品在线免费观看| 性欧美一区二区| 2023国产精华国产精品| 欧美亚男人的天堂| 97超碰人人澡| 高潮毛片在线观看| 久久精品欧美一区二区三区麻豆| 成人情视频高清免费观看电影| 国产精品传媒在线观看| 国产精品亚洲欧美| 欧美情侣性视频| 91香蕉视频污在线观看| 亚洲理论电影| 亚洲成人网av| 中文字幕欧美视频| 成人在线爆射| 精品免费在线视频| 亚洲国产一二三精品无码| 成人精品一区二区| 久久亚洲捆绑美女| 精品久久久久久乱码天堂| 国产伦精品一区二区三区免.费| 首页欧美精品中文字幕| 91成人国产在线观看| 久操视频免费在线观看| 小处雏高清一区二区三区| 中文在线不卡视频| 亚洲a v网站| 午夜先锋成人动漫在线| 亚洲国产天堂久久综合网| 男人的天堂免费| 日韩精品一区二区三区免费视频| 欧美精品xxxxbbbb| 五月天视频在线观看| 日韩国产大片| 欧美妇女性影城| 婷婷激情综合五月天| 狠狠久久综合| 欧美精品一级二级| 久久久久久综合网| 99综合久久| 欧美日产国产精品| 亚洲天堂国产视频| 成人在线日韩| 日韩欧美色电影| 波多野结衣中文字幕在线播放| 国产一区 二区| 欧美成人欧美edvon| 国产精品一级无码| 鲁大师精品99久久久| 亚洲激情成人网| 亚洲综合色一区| blacked蜜桃精品一区| 中文字幕日本精品| 99久久婷婷国产综合| 欧美日韩爆操| 欧美在线视频播放| 亚洲图片欧美在线| 国产精选一区二区三区| 国产精品手机视频| 国产一区电影| 亚洲欧美日韩中文字幕一区二区三区| 无码人妻精品一区二区蜜桃百度| av影视在线看| 91国模大尺度私拍在线视频| 亚洲一区二区福利视频| 久久久伦理片| 一色桃子一区二区| 福利所第一导航| 欧美亚洲网站| 成人av番号网| 人人妻人人澡人人爽人人欧美一区| www.av亚洲| 亚洲精品中文字幕乱码三区不卡| 高潮毛片在线观看| 欧美特黄级在线| 特级西西444www| 免费看成人吃奶视频在线| 日韩中文av在线| 精品91久久久| 精东粉嫩av免费一区二区三区| 国产精品久久久久久久天堂第1集| 男操女在线观看| 亚洲美腿欧美偷拍| 三年中国国语在线播放免费| 成人短视频软件网站大全app| 日韩av在线免费观看| 影音先锋男人资源在线观看| 99精品福利视频| 国产在线精品一区免费香蕉 | 国产成一区二区| 成人精品视频在线播放| 丰满圆润老女人hd| 精品中文一区| 欧美成人三级视频网站| 国产精品久久久久久久妇| 日韩有码一区二区三区| 超碰97人人在线| 97超碰国产一区二区三区| 亚洲高清免费观看高清完整版在线观看 | 国产精品美女一区二区三区| 日韩a级在线观看| 亚洲精品66| 亚洲欧美日韩国产中文| 久久久一二三区| 精品系列免费在线观看| 色播亚洲视频在线观看| 亚洲美女炮图| 精品国产91久久久久久久妲己 | 日韩欧美在线国产| 国产老头和老头xxxx×| 精品久久成人| 日韩av理论片| 日本一级在线观看| 天天色图综合网| 逼特逼视频在线观看| 91av精品| 国产欧美精品久久久| 丁香在线视频| 91久久香蕉国产日韩欧美9色| av2014天堂网| 在线视频观看日韩| 国产女主播一区二区| 在线观看电影av| 91精品国产综合久久小美女| 女性裸体视频网站| 欧美aaaaa成人免费观看视频| 欧美重口乱码一区二区| 成人性教育av免费网址| 日韩精品免费在线| 在线观看免费国产视频| av日韩在线网站| 国产av国片精品| 欧美日韩麻豆| 全球成人中文在线| 久青草国产在线| 欧美在线一二三| 在线观看免费小视频| 强制捆绑调教一区二区| 亚洲精品日韩精品| 成人网av.com/| 欧美日产国产成人免费图片| 性生交大片免费看女人按摩| 一区二区成人在线观看| 欧美做受高潮中文字幕| 亚洲日本激情| 免费成人深夜夜行视频| 午夜欧美巨大性欧美巨大| 国产香蕉一区二区三区在线视频 | 秋霞国产精品| 色偷偷888欧美精品久久久| 国产又大又黄又爽| 亚洲精品国产视频| 性欧美18—19sex性高清| 国产亚洲在线| 亚洲一一在线| 一区二区亚洲视频| 热re91久久精品国99热蜜臀| wwwxxx在线观看| 欧美一卡二卡在线| 日韩精品视频免费播放| 久久精品夜色噜噜亚洲a∨| 91女神在线观看| 国产主播精品| 任我爽在线视频精品一| 精品国产不卡一区二区| 97色在线播放视频| 瑟瑟视频在线| 精品国产麻豆免费人成网站| 天天操天天干天天摸| 综合电影一区二区三区 | 午夜精品一区二区三区在线视频 | 久久激情五月丁香伊人| 欧美视频一二区| 在线看国产一区| 免费一级片在线观看| 久久综合久久综合九色| 日韩av加勒比| 久久激情久久| 日本一本草久p| 九九热精品视频在线观看| 91香蕉亚洲精品| 激情都市亚洲| 欧美精品福利在线| 欧美精品hd| 日韩精品极品视频| 精品人妻少妇嫩草av无码专区| 色噜噜狠狠色综合欧洲selulu| 丝袜 亚洲 另类 欧美 重口| 国产日产欧美精品一区二区三区| 在线观看欧美一区二区| 日本不卡视频一二三区| 日韩国产一级片| 婷婷色综合网| 午夜老司机精品| 少妇精品导航| 国产精品免费一区二区| 婷婷综合六月| 性欧美xxxx视频在线观看| 最近中文字幕免费mv2018在线| 亚洲天堂视频在线观看| 欧美一级一区二区三区| 日韩一级免费观看| 亚洲在线免费观看视频| 欧美主播一区二区三区| 午夜影院在线看| 亚洲妇女屁股眼交7| 免费亚洲精品视频| 老司机一区二区三区| 日韩精品资源| 美女视频亚洲色图| 91精品国自产在线观看 | 精品视频亚洲| 精品一区二区三区国产| 动漫av一区| 操一操视频一区| 这里视频有精品| 中文字幕中文字幕中文字幕亚洲无线 | 大地资源第二页在线观看高清版| 中文精品一区二区| 久久精品中文字幕一区二区三区| 97久久精品| 99中文字幕| 豆花视频一区二区| 国产精品国产一区二区| 伊人精品久久| 国产精品日本一区二区| 粉嫩的18在线观看极品精品| www.久久久| 大型av综合网站| 国产亚洲福利社区| 开心激情综合| 欧美乱偷一区二区三区在线| 竹菊久久久久久久| 日本一区视频在线播放| 国内精品久久久久久久影视简单 | 久久77777| 久久网福利资源网站| free性欧美hd另类精品| 欧美日本亚洲视频| cao在线视频| 91精品国产电影| 欧美片第1页| 国产精品美乳在线观看| 日韩一级视频| 亚洲综合日韩中文字幕v在线| 日韩一区二区三区在线看| 国产精品sss| 亚洲三级性片| 亚洲欧美综合一区| 你懂的视频一区二区| 无码av天堂一区二区三区| 亚洲欧美激情诱惑| 五月天亚洲视频| 国产精品一二二区| 污片免费在线观看| 国产欧美一区二区精品久导航 | 国产美女久久久| 青草伊人久久| 开心色怡人综合网站| 日本a级不卡| www.国产亚洲| 国产一区二区三区的电影 | 欧美国产精品一区二区| 欧美成人777| 午夜视频一区二区| 无码人妻aⅴ一区二区三区有奶水| 4438全国亚洲精品观看视频| 奇米一区二区三区四区久久| 欧美亚洲二区| 国产精品免费一区二区| blacked蜜桃精品一区| 视色,视色影院,视色影库,视色网 日韩精品福利片午夜免费观看 | 精品无人区卡一卡二卡三乱码免费卡 | 免费麻豆国产一区二区三区四区| 午夜电影久久久| 亚洲视频久久久| 亚洲第一福利网| 日韩在线资源| 91禁国产网站| 高清久久一区| 欧美日韩精品免费观看视一区二区| 日韩啪啪电影网| 日日碰狠狠添天天爽超碰97| 激情综合五月婷婷| 欧美做受喷浆在线观看| 18欧美亚洲精品| 黄色av网站免费观看| 精品国产亚洲在线| 日本三级视频在线观看| 91精品国产亚洲| 欧洲大片精品免费永久看nba| 热舞福利精品大尺度视频| 影音先锋在线一区| 天天干天天色天天干| 久久色在线视频| 豆国产97在线 | 亚洲| 欧美日本一区二区三区| 你懂的在线播放| 久久久久久久国产精品| 亚洲国产天堂| 图片区小说区区亚洲五月| 一区二区毛片| 亚洲欧美高清在线| 亚洲品质自拍视频网站| 国产美女www| 国产精品三级| 99热亚洲精品| 成人国产精品免费观看| 欧美三级黄色大片| 欧美日韩aaaaaa| 92国产在线视频| 国产精品久久久av| 一区三区在线欧| 久久亚洲中文字幕无码| 成人综合婷婷国产精品久久蜜臀| 久艹在线观看视频| 欧美日韩一区二区三区四区五区 | 电影一区中文字幕| 中文字幕乱码一区二区三区| 久久99国产精品久久| 国产在视频线精品视频| 欧美四级电影网| 1024国产在线| 国产一区二区香蕉| 97视频热人人精品免费| 日日干夜夜操s8| 国产精品乱人伦中文| 中文字幕+乱码+中文| 国产一区二区三区视频在线观看 | 一级特黄曰皮片视频| 国产精品一卡二卡在线观看| 亚洲精品一卡二卡三卡四卡| 久久精品免费| 91精品国产自产| 日韩欧美高清在线视频| 日韩在线无毛| 国产精品美女久久久久aⅴ| 久久久国产精品成人免费| 亚洲国产精品嫩草影院久久| av最新在线| 久久精品99久久| 久久综合九色| 亚洲精品91在线| 欧美日韩电影在线| av在线影院| 国产精品制服诱惑| 亚洲综合国产| 精品无码在线观看| 欧美日韩精品一二三区| 超碰在线免费公开| 国产精品免费一区二区三区四区 | 五十路熟女丰满大屁股| 99久久99久久精品免费看蜜桃 | 葵司免费一区二区三区四区五区| 欧美成人国产精品一区二区| 欧美午夜电影网| 哥也色在线视频| 久久免费看av| 美腿丝袜一区二区三区| 欧美爱爱小视频| 亚洲毛片在线免费观看| 网站免费在线观看| 欧美在线观看18| 最新黄网在线观看| 欧美成ee人免费视频| 开心九九激情九九欧美日韩精美视频电影 | 亚洲熟妇一区二区| 五月天婷婷综合| 粉嫩av一区| 亚洲在线观看视频网站| 亚洲深夜激情| 国产亚洲精品久久久久久豆腐| 亚洲成人精品久久久| 国产极品久久久久久久久波多结野| 免费日韩在线观看| 国产亚洲欧美中文| 亚洲乱熟女一区二区| 国产精品久久久久影院日本|