旁白音:本文是不定時更新的.net core,當前主線任務的Nuxt+VueAdmin教程的 nuxt.js 之 tibug項目已上線,大家可以玩一玩:http://123.206.33.109:7090,具體的部署教程會在下周發表。 緣起 哈嘍大家周五好呀,今天是一個不定時更新的文章,是很簡單的一 ...
旁白音:本文是不定時更新的.net core,當前主線任務的Nuxt+VueAdmin教程的 nuxt.js 之 tibug項目已上線,大家可以玩一玩:http://123.206.33.109:7090,具體的部署教程會在下周發表。
緣起
哈嘍大家周五好呀,今天是一個不定時更新的文章,是很簡單的一篇文章,大家應該都能看懂,主要包含了兩個內容,一個是對AOP編程的進一步的理解(其中還有和過濾器比較),第二個就是一個簡單的小插件——記錄介面的調用時間調用情況,也就是很簡單的性能記錄,這個時候你肯定不要和 Metricss+influxdb+grafana 作比較了,它們功能雖然很大,但是用起來笨重,咱們這種入門級別的小項目暫時先不用這個了,說到這裡,昨天有小伙伴留言,說要不要在項目中增加消息隊列 ReditMQ ,我正在考慮中,看看如何使用,好啦廢話不多說,先來幾個小問題,熱熱身:
1、在平時開發的時候,大家是如何記錄當前 <介面/方法> 的調用時間的?// 手動寫起止時間相減
2、如何對異常進行處理的,這裡有 <api層的異常>,以及 <service 層的異常> 的?// 加 try catch
3、如何快速的找到當前介面的錯誤信息?// 查看日誌記錄
大家先帶著這幾個問題自己想一想,是不是和我的綠色解決方案一致,要是有更好的辦法也幫忙提給我,不勝感激!
不過!今天肯定不會用這些解決方案的,今天玩兒一個新花樣,應該也會有人玩兒過,彆著急,咱們往下看。
先來個實現圖,預熱下,以後調試介面,性能+錯誤信息一目瞭然:
一、複習篇——我們把AOP用在了哪裡?
時間是很快,我也已經從第一個專題,寫到了第三個專題,還記得當時第一次寫AOP的時候《框架之十 || AOP面向切麵編程淺解析:簡單日誌記錄 + 服務切麵緩存》,很多很多的小伙伴不是很明白,也不知道應用場景到底在哪裡,完全不瞭解落地幾何,現在也能在群里,時不時看到有小伙伴用到AOP編程,感覺很開心,至少幫到了一些人了,這就是最大的欣慰!那咱們在Blog.core 項目中,到底如何運用了 AOP 呢?
1、切麵緩存
這一塊相信已經有小伙伴知道,並且用到了,我也是在很多地方使用到了,比如在基於策略的許可權認證文章中《JWT完美實現許可權與介面的動態分配》,通過了對角色模塊的切麵緩存,很好的實現了快速授權的目的,不僅代碼整潔,而且功能也實現了:
// 將最新的角色和介面列表更新 var data = await _roleModulePermissionServices.GetRoleModule(); var list = (from item in data where item.IsDeleted == false orderby item.Id select new PermissionItem { Url = item.Module?.LinkUrl, Role = item.Role?.Name, }).ToList();
// 通過AOP緩存獲取角色模塊信息 [Caching(AbsoluteExpiration = 10)] public async Task<List<RoleModulePermission>> GetRoleModule() { var roleModulePermissions = await dal.Query(a => a.IsDeleted == false); //....... return roleModulePermissions; }
另外還有在當前第三系列教程中,獲取Bug信息的時候,也用到了切麵緩存(所以,如果你用了文章開頭的 tibug 系統,提交了一個 bug,但是沒有立刻顯示出來,就是這個原因,10分鐘緩存):
綜上所言,經過多次使用,我個人表示真的是一個神器,在完全不露痕跡的情況下,實現了緩存,是不是很好用?
這個時候你會問,單獨為了緩存的話,AOP不是很透徹,那還有其他的用處麽?請往下看。前提是上邊的這種基於AOP的緩存你要看懂了,先在腦子裡回顧下整體流程。
2、切麵日誌
上邊咱們說了緩存,我個人感覺還有一個很大的用戶就是切麵日誌,這個具體的內容以前已經說過了,這裡就不多說了,想瞭解原理和詳細說明,請看《AOP面向切麵編程淺解析:簡單日誌記錄 + 服務切麵緩存》,這裡只是複習下流程:
public void Intercept(IInvocation invocation) { //記錄被攔截方法信息的日誌信息 var dataIntercept = $"{DateTime.Now} " + $"當前執行方法:{ invocation.Method.Name} "; //在被攔截的方法執行完畢後 繼續執行當前方法,註意是被攔截的是非同步的 invocation.Proceed(); dataIntercept += ($"方法執行完畢,返回結果:{invocation.ReturnValue}"); #region 輸出到日誌文件 #endregion }
只需要我們 ServiceConfigure 中開啟服務以後,就可以在指定文件中,看到每次的切麵介面調用情況,註意這裡是 service 層的,不是 controller 的日誌,這個時候就是 AOP 和過濾器 Filter 的區別了:
1、Filter過濾器是基於當前Http請求的,也就是介面層面的,顆粒度比較大;
2、而AOP是基於服務切麵的,是 Service 層的請求,顆粒度比較小;
那既然AOP能記錄調用日誌,能捕獲異常麽,上次群里有一個小伙伴問到了,這裡就點名錶揚了,挺棒的,能自己思考,那如何捕獲呢?
3、切麵異常
在平時的開發中,我們經常會遇到各種 Bug ,在 controller 里的錯誤就不說了,編譯的時候基本都能看出來,但是很多 service 層的錯誤,真是難找,比如我故意寫的這個bug,一個不重要的方法:
public void NoImportantMethod() { int a = 1; int b = 0; int c = a / b; }
這個錯誤是如何捕獲的,大家還記得麽,就是我們用全局變數異常過濾器 Filter 捕獲的《三十五║ 完美實現全局異常日誌記錄》:
我們平時可能會在 api 中使用這樣的service層方法,然後下邊也會有其他的一些方法,因為這個方法不重要,比如僅僅是閱讀數量+1,那我們就不能讓當前介面崩了
public async Task<MessageModel<Response>> Get() { var data = new MessageModel<Response>(); // 一個不重要的方法 _advertisementServices.NoImportantMethod(); // 核心功能:說愛你 Love love = New Love(); love.SayLoveU(); return data; }
這個我們我們會在 NoImportantMethod() 這裡報異常,直接崩潰出去,你感覺這樣的設計合理麽?我們不能因為一個不重要的動作就不說核心的 我愛你 了吧