<input id="ohw05"></input>
  • <table id="ohw05"><menu id="ohw05"></menu></table>
  • <var id="ohw05"></var>
  • <code id="ohw05"><cite id="ohw05"></cite></code>
    <label id="ohw05"></label>
    <var id="ohw05"></var>
  • .net core 拋異常對性能影響的求證之路

    一、前言

    在.net 相關技術群、網絡上及身邊技術討論中看到過關于大量拋異常會影響性能這樣的結論,心中一直就存在各種疑問。項目中使用自定義異常來處理業務很爽,但是又擔心大量拋業務異常存在性能問題。
    查閱了各種文檔,微軟官方對性能優化這一塊也不建議使用過多的異常,故我心中冒出疑問。

    • 疑問一:項目中大量拋出業務異常對性能是否會受到影響?

    二、求證

    壓測環境

    • 服務器:阿里云服務器
    • 宿主機:4C16G*1臺
    • pod 配置:3C3G*1pod
    • 壓測腳本:堡壘機上,網絡等相關影響條件比較小

    2.1 使用.net 6 建立了一個簡單的web api 項目 新增兩個壓測接口

    • api接口代碼如下
            /// <summary>
            /// 正常返回數據接口1
            /// </summary>
            /// <returns></returns        
            [HttpGet("Test1")]
            public async Task<IActionResult> Test()
            {
                return Content("1");
            }
    
            /// <summary>
            /// 拋異常返回接口2 ,同時存在全局過濾器
            /// </summary>
            /// <returns></returns        
            [HttpGet("Test2")]
            public async Task<IActionResult> Test2(string open)
            {
                throw new BusinessException(Model.EnumApiCode.SignWrong);
            }
    
    • 全局過濾器代碼如下
        /// <summary>
        /// 全局異常日志
        /// </summary>
        public class ExceptionFilter : IExceptionFilter
        {
            /// <summary>
            /// 
            /// </summary>
            /// <param name="context"></param>
            public void OnException(ExceptionContext context)
            {
                //不做任何處理,直接返回1
                context.Result = new JsonResult("1");
            }
        }
    
       //全局過濾器注入
       services.AddControllers()
           .AddMvcOptions(option =>
           {
                 option.Filters.Add<ExceptionFilter>();
           });
    
    • 現在對test1 接口并發200的情況下進行壓測,持續15分鐘的壓測結果如下:

    • 對通過全局過濾器捕獲異常并大量拋出異常 在相同壓測條件情況下的壓測結果如下:

    • 對test1 和test2 同等條件下壓測結果對比
    接口 tps cpu 壓測條件
    test1 10300左右 cpu消耗90%左右 并發200,持續壓測
    test2 4300左右 cpu消耗100%左右 并發200,持續壓測

    目前得到的結論是拋異常確實影響性能,并且對性能下降了60% 左右,上面主要是異常流程走了全局過濾器方式,故參考意義不大,下面再進一步修改代碼進行壓測

    • 對test2 代碼進行修改如下
           /// <summary>
            /// 拋異常返回接口2 ,直接try catch 不走全局過濾器
            /// </summary>
            /// <returns></returns        
            [HttpGet("Test2")]
            public async Task<IActionResult> Test2()
            {
                try
                {
                    throw new BusinessException(Model.EnumApiCode.SignWrong);
                }
                catch (Exception ex)
                {
                    return Content("1");
                }
            }
    
    • 再對修改后的test2 接口進行壓測,壓測結果如下:

    接口 tps cpu占用 壓測條件
    test1 10300左右 90% 左右 并發200,持續壓測
    test2 9200左右 91% 左右 并發200,持續壓測

    進一步得到的結論是try catch 后性能有所提高,跟正常相比還有點點差距,全局過濾器對性能影響比較大,相當于走了管道,但是觀察代碼test1 和test2代碼還存在差距,懷疑test2 代碼中new 了新異常導致性能差異,故再進一步進行代碼修改求證

    • 對test1 代碼進行修改,修改后的代碼如下:
            /// <summary>
            /// 正常返回數據接口1,但是先new 異常出來,保持跟上面test2 代碼一致
            /// </summary>
            /// <returns></returns        
            [HttpGet("Test2")]
            public async Task<IActionResult> Test2(string open)
            {
                var ex= new BusinessException(Model.EnumApiCode.SignWrong);
                return Content("1");
            }
    
    • 對修改后的test1 代碼進行壓測結果如下:

      忘記截圖,大概和修改后的test2 代碼壓測結果相差不大,大概tps 9300左右,故還是拿的上一個圖貼出來,諒解
    接口 tps cpu占用 壓測條件
    test1 9300左右 90%左右 并發200,持續壓測
    test2 9200左右 90%左右 并發200,持續壓測

    進一步得到的結論是try catch 后性能和正常返回代碼性能相當,相差無幾,可以忽略不計

    2.2 最終結論

    • 異常和正常代碼性能旗鼓相當,但是全局過濾器對性能影響比較大,大概降低了60%左右(空業務情況下壓測,性能降低是會被放大),全局過濾器走了管道,但是這跟微軟官方的性能優化又有沖突,想必微軟官方也是出于對全局過濾器異常處理的考慮吧。同時對于添加了業務的情況下,這個降低會被稀釋,沒去做壓測對比哈(估計影響不會太大),正常用戶體量還不至于被這個給影響到穩定性。所以怎么取舍看自己
    • 這里不否定使用 全局過濾器進行業務自定義異常捕獲,是否最外層try catch 掉還是全局過濾器去捕獲處理,自己根據復雜度和性能兩者中自行取舍,至少全局過濾器處理異常從性能角度上來說不是優雅的解決方式
    • 對于異常,盡量按照微軟官方建議
      • 使用 “測試者-執行者”模式
      • “嘗試-分析”模式

    最后拋出一個待求證的問題

    • 疑問一:大量拋出非自定義異常,性能和正常返回性能對比會如何?比如字符串轉換int 不使用TryParse 去轉換

    以上結論個人壓測結果,如有不對,歡迎交流糾正?

    posted @ 2022-06-11 11:49  Jlion  閱讀(3784)  評論(55編輯  收藏  舉報
    国产美女a做受大片观看