日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

invoke方法是做啥的_使用 NLog 给 Asp.Net Core 做请求监控

發(fā)布時(shí)間:2023/12/19 asp.net 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 invoke方法是做啥的_使用 NLog 给 Asp.Net Core 做请求监控 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

為了減少由于單個(gè)請(qǐng)求掛掉而拖垮整站的情況發(fā)生,給所有請(qǐng)求做統(tǒng)計(jì)是一個(gè)不錯(cuò)的解決方法,通過觀察哪些請(qǐng)求的耗時(shí)比較長,我們就可以找到對(duì)應(yīng)的接口、代碼、數(shù)據(jù)表,做有針對(duì)性的優(yōu)化可以提高效率。在?asp.net web api?中我們可以通過注冊一個(gè)?DelegatingHandler?來實(shí)現(xiàn)該功能。那在?asp.net core?中該如何實(shí)現(xiàn)呢?

一:比較?asp.net web api 和?asp.net core?的請(qǐng)求管道

觀察這兩張圖,可以發(fā)現(xiàn)他們非常的相似,都是管道式的設(shè)計(jì),在?asp.net web api?中,我們可以注冊一系列的?DelegatingHandler?來處理請(qǐng)求上下文?HttpRequestMessage,在?asp.net?core?中,我們可以注冊一系列中間件來處理請(qǐng)求上下文,他們兩者從功能和意義上是非常相似的,我這里這里不會(huì)詳細(xì)介紹各自的管道是如何的(這樣的文章非常多,博客園隨處可見),他們都完成了類似中間件的功能,只是在代碼設(shè)計(jì)上有一點(diǎn)區(qū)別。

我們先看一段代碼,新建一個(gè) asp.net web api 項(xiàng)目,添加幾個(gè) DelegatinHandler

然后在 Global 中注冊

修改一下 ValuesController

啟動(dòng)后輸入路徑 /api/values,我們可以在VS?的輸出欄看到下面這些內(nèi)容

輸出中我們可以看到?DelegatingHandler1?的 InnerHandler?是?DelegatingHandler2,以此類推,在?DelegatingHandler3?的?InnerHandler?處理請(qǐng)求的時(shí)候就轉(zhuǎn)發(fā)到了相關(guān)控制器,這里和 .net?core?中的中間件非常相似,在.net?core 中間件順序是?RequestServicesContainerMiddleware(給請(qǐng)求上下文綁定容器)->?AuthenticationMiddleware(認(rèn)證)-> RouterMiddleware (路由以及MVC)

如果我們在?ValuesController?中觀察表達(dá)式?this.RequestContext.Configuration.MessageHandlers?還可以看到最終處理請(qǐng)求的是一個(gè)?HttpRoutingDispatcher,最也是是分配到路由以及控制器來處理的,按照如此方式我們可以很容易在?asp.net?web api?中對(duì)請(qǐng)求統(tǒng)計(jì)。這里是比較簡陋的,對(duì)此我們可以記錄客戶端和服務(wù)器更詳細(xì)的信息,包括?IP?地址,http狀態(tài)碼,是否是認(rèn)證用戶等等,但是這篇主要是以?asp.net?core?為主的,所以這里就不詳細(xì)寫下去了。

?二:asp.net?core?中間件 + NLog 實(shí)現(xiàn)請(qǐng)求監(jiān)控

?先看統(tǒng)計(jì)結(jié)果,start?開始時(shí)間,time?是請(qǐng)求消耗時(shí)間(毫秒),authenicate?是認(rèn)證通過的?schema,使用 NLog?自定義字段也是非常方便的

先說一說遇到的問題

(1)NLog?記錄一張以上的表如何實(shí)現(xiàn),應(yīng)為首先會(huì)有一個(gè)一般性的日志表(稱他為?log),并且這些統(tǒng)計(jì)不對(duì)寫到?log?表

(2)使用?NLog?自定義字段?LayoutRenderer?沒有類似 .net framework?中的?System.Web.Current

(3)使用?UseMiddleware?無法在讓我們的中間件成為第一個(gè)中間件

(4)實(shí)現(xiàn)忽略記錄的方法,肯定有一些接口是不希望記錄的,所以這個(gè)也要實(shí)現(xiàn)

?NLog?配置

這里只列出了部分內(nèi)容,github 地址在最后,數(shù)據(jù)庫是?mysql ,apiinsight?表示請(qǐng)求統(tǒng)計(jì),log?是一般性的日志,debughelper?可以加快我們調(diào)試時(shí)日志的檢索速度

在?Startup?中

自定義字段都是通過?LayoutRenderer?實(shí)現(xiàn),由于自定義字段有很多,這里只列出了一個(gè)開始時(shí)間是如何查詢的,這個(gè)時(shí)間是在我們注冊的第一個(gè)中間件執(zhí)行 Invoke?方法的時(shí)候?qū)戇M(jìn)?HttpContext.Items?的

?NLog 規(guī)則,很容易理解日志統(tǒng)計(jì)只記錄?Cheers?命名空間下的日志

?核心 ApiInsightMiddleware?中間件

很好理解,在執(zhí)行下一個(gè)中間件之前調(diào)用?SetValues?開始計(jì)時(shí),下一個(gè)中間件執(zhí)行成功開始統(tǒng)計(jì)并寫入日志(或者忽略不寫)。現(xiàn)在他是?asp.net core?mvc?的第一個(gè)中間件了,好處就是更符合這個(gè)中間件本身的所做的事情了,但是帶來的問題就是?httpContext.RequestService?是 null ,因?yàn)?RequestService?是在?RequestServicesContainerMiddleware?這個(gè)中間件寫進(jìn)去的,在者其實(shí)很多地方我們都需要?HttpContext ,并且目前微軟還沒有給我們定義一個(gè)靜態(tài)的?HttpContext。

靜態(tài)的?HttpContext

HttpContext?是通過單例 IHttpContextAccessor?提供的,當(dāng)?HttpContext?創(chuàng)建的時(shí)候就會(huì)賦值給他,當(dāng)請(qǐng)求到達(dá)中間件這個(gè)管道的時(shí)候,HttpContext?就已經(jīng)存在于?IHttpContextAccessor?了,并且和?Invoke?參數(shù)列表中的?HttpContext?是一致的(同一個(gè)請(qǐng)求中),問題在于?RequestServicesContainerMiddleware?這個(gè)中間件沒有執(zhí)行就沒有容器,并且很多時(shí)候我們都要用到容器,所以就模仿源碼在這里都加進(jìn)去了。

我們只需要在?Startup?中使用?app.UseGlobalHttpContext();?就可以在程序的任何地方得到?HttpContext?和容器了,肯定會(huì)有人說為什么不通過構(gòu)造函數(shù)來獲取我們想要的注入呢,因?yàn)橛行┑谌娇蚣芑蜻@某些地方我們不能使用容器獲取服務(wù),比如這里 NLog?的自定義字段使用的?LayoutRenderer?就無法通過構(gòu)造器得到我們想要的服務(wù)。

第一個(gè)中間件

在?Startup?的?Configure?方法中目前還沒發(fā)現(xiàn)如何注冊第一個(gè)中間件,因?yàn)?Configure?方法始終是在?IStartupFilter?這個(gè)接口之后執(zhí)行的,這也提供了我們讓自己的中間件成為第一個(gè)中間件的可能??赡苓@樣做并不是特別有必要,甚至是沒有意義的,但是實(shí)現(xiàn)的過程確實(shí)很有意思的。這里在?Startup?中的?方法?ConfigureService 注冊我們的中間件。

具體的

這里注冊了三個(gè)服務(wù)

IApiInsightsKeys

定義了存儲(chǔ)在?HttpContext.Item?中的鍵值對(duì)的名稱

IRequestIsAuthenticate

就驗(yàn)證而言可能不同的開發(fā)者使用的是不一樣的驗(yàn)證方式,可能是基于 Asp.Net Core?Authentication?中間件的認(rèn)證方式,也可能是其他的比如自定義的?token,或者有一個(gè)單點(diǎn)登錄的服務(wù)器,又或者是?session,其實(shí) Asp.Net Core?的?Authentication?中間件也可以幫我們實(shí)現(xiàn)基于?restful?的token?認(rèn)證。所以就把它定義出來了,并且默認(rèn)的實(shí)現(xiàn)就是基于?Authentication?這個(gè)中間件的。

IStartupFilter

看到他是一個(gè)非常特殊的方式來注冊的,自定義的 FirstRegister?這個(gè)方法,實(shí)際上?Asp.Net?Core?內(nèi)置有多個(gè)?IStartup?這樣的服務(wù),并且都是在?Startup?的?Configure?之前執(zhí)行的,所以這里一定要用這個(gè)服務(wù)來讓我們的中間件成為第一個(gè)中間件。FirstRegister?代碼也很容易理解,由于在宿主啟動(dòng)之前,內(nèi)部注冊了多個(gè)?IStartup,并且最后會(huì)按先后順序配置 IApplicationBuilder,所以我們只能讓第一個(gè) StartupFilter 的?IApplicationBuilder 就注冊我們的中間件,通過改動(dòng) ServiceCollection 中服務(wù)的順序可以實(shí)現(xiàn)。雖然不是很有必要,但是可以從中觀察的 Startup 的 Configure方法 以及 接口StartupFilter (還有 IHostingStartup )的執(zhí)行順序。

忽略的方法

在 ApiInsight 方法中會(huì)調(diào)用 IsIgnore 檢測該方法是否打了標(biāo)簽?NoInsightAttribute,如果是那就忽略該方法,這里建議使用特性路由,原因有兩點(diǎn),第一特性路由不需要使用?IActionSelector 接口重新查找匹配的方法,第二,在 restful api 中,結(jié)合特性路由和 HttpMethodAttribute 標(biāo)簽可以使方法更簡潔,相同的接口名稱通過不同的請(qǐng)求方式達(dá)到不同的目的

好看你就點(diǎn)點(diǎn)我

看完本文有收獲?請(qǐng)轉(zhuǎn)發(fā)分享給更多人

關(guān)注「.net學(xué)院」,提升.Net技能?


總結(jié)

以上是生活随笔為你收集整理的invoke方法是做啥的_使用 NLog 给 Asp.Net Core 做请求监控的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。