結(jié)合項(xiàng)目解答使用Go中間件遇到的問題:中間件的概念和應(yīng)用
什么是中間件?
在服務(wù)端開發(fā)中,“中間件”是大家一定會(huì)聽到的名詞。
初學(xué)者聽起來覺得很高大上,覺得很難,其實(shí)“中間件”并不難,對(duì)我們學(xué)習(xí)Go語言來說,使用中間件也沒有太多心智挑戰(zhàn)。
“中間件”它并沒有很嚴(yán)格的定義,但是普遍接受IDC的定義:中間件是一種獨(dú)立的系統(tǒng)軟件服務(wù)程序,分布式應(yīng)用軟件借助這種軟件在不同的技術(shù)之間共享資源,中間件位于客戶機(jī)服務(wù)器的操作系統(tǒng)之上,管理計(jì)算資源和網(wǎng)絡(luò)通信。
比如:
我們今天要重點(diǎn)介紹的“GoFrame網(wǎng)絡(luò)請(qǐng)求控制中間件”是中間件的一種,它是基于GoFrame框架內(nèi)部的一種中間件,也是我們這期內(nèi)容的重點(diǎn)。
在我們WEB開發(fā)過程中,像常用的MySQL、Redis、RabbitMQ在系統(tǒng)架構(gòu)角度也被稱為中間件。
從基礎(chǔ)架構(gòu)、系統(tǒng)架構(gòu)、程序架構(gòu)等不同的觀點(diǎn)來看,中間件的概念是不一樣的。我們也不用過于糾結(jié)于這個(gè)名詞的具體解釋。
畢竟結(jié)合自己的需求,掌握如何使用中間件,遠(yuǎn)比只搞清楚中間件的解釋要有意義的多。
更多介紹大家可以查看:中間件-計(jì)算機(jī)用語--百度百科[1],不作為我這期內(nèi)容的重點(diǎn)。
GoFrame中間件/攔截器-基本介紹
GoFrame?提供了優(yōu)雅的中間件請(qǐng)求控制方式,該方式也是主流的WebServer?提供的請(qǐng)求流程控制方式,基于中間件設(shè)計(jì)可以為WebServer提供更靈活強(qiáng)大的插件機(jī)制。
經(jīng)典的中間件洋蔥模型:
中間件定義
中間件的定義和普通HTTP執(zhí)行方法HandlerFunc?一樣,但是可以在Request?參數(shù)中使用Middleware屬性對(duì)象來控制請(qǐng)求流程。
我們拿一個(gè)跨域請(qǐng)求的中間件定義來示例說明一下:
可以看到在該中間件中執(zhí)行完成跨域請(qǐng)求處理的邏輯后,使用r.Middleware.Next()?方法進(jìn)一步執(zhí)行下一個(gè)流程;如果這個(gè)時(shí)候直接退出不調(diào)用r.Middleware.Next()方法的話,將會(huì)退出后續(xù)的執(zhí)行流程(例如可以用于請(qǐng)求的鑒權(quán)處理)。
中間件類型
中間件的類型分為兩種:前置中間件和后置中間件。前置即在路由服務(wù)函數(shù)調(diào)用之前調(diào)用,后置即在其后調(diào)用。
前置中間件
其定義類似于:
后置中間件
其定義類似于:
按照中間件注冊(cè)方式劃分,又可分為:全局中間件、分組路由中間件。
全局中間件
全局中間件是可以獨(dú)立使用的請(qǐng)求攔截方法,通過路由規(guī)則的方式進(jìn)行注冊(cè),綁定到Server上,由于中間件需要執(zhí)行請(qǐng)求攔截操作,因此往往是使用"模糊匹配"或者"命名匹配"規(guī)則。
全局中間件僅對(duì)動(dòng)態(tài)請(qǐng)求攔截有效,無法攔截靜態(tài)文件請(qǐng)求。
分組路由中間件
分組路由中注冊(cè)的中間件綁定到當(dāng)前分組路由中的所有的服務(wù)請(qǐng)求上,當(dāng)服務(wù)請(qǐng)求被執(zhí)行前會(huì)調(diào)用到其綁定的中間件方法。
分組路由僅有一個(gè)Middleware的中間件注冊(cè)方法。分組路由中間件與全局中間件不同之處在于,分組路由中間件無法獨(dú)立使用,必須在分組路由注冊(cè)中使用,并且綁定到當(dāng)前分組路由中所有的路由上作為路由方法的一部分。
執(zhí)行優(yōu)先級(jí)
全局中間件
由于全局中間件也是通過路由規(guī)則執(zhí)行,那么也會(huì)存在執(zhí)行優(yōu)先級(jí):
- 首先,由于全局中間件是基于模糊路由匹配,因此當(dāng)同一個(gè)路由匹配到多個(gè)中間件時(shí),會(huì)按照路由的深度優(yōu)先規(guī)則執(zhí)行,具體請(qǐng)查看路由章節(jié);
- 其次,同一個(gè)路由規(guī)則下,會(huì)按照中間件的注冊(cè)先后順序執(zhí)行,中間件的注冊(cè)方法也支持同時(shí)按照先后順序注冊(cè)多個(gè)中間件;
- 最后,為避免優(yōu)先級(jí)混淆和后續(xù)管理,建議將所有中間件放到同一個(gè)地方進(jìn)行先后順序注冊(cè)來控制執(zhí)行優(yōu)先級(jí);
這里的建議來參考于gRPC的攔截器設(shè)計(jì),沒有過多的路由控制,僅在一個(gè)地方同一個(gè)方法統(tǒng)一注冊(cè)。往往越簡(jiǎn)單,越容易理解,也便于長(zhǎng)期維護(hù)。
分組路由中間件
分組路由中間件是綁定到分組路由上的服務(wù)方法,不存在路由規(guī)則匹配,因此只會(huì)按照注冊(cè)的先后順序執(zhí)行。
示例
官方文檔為我們提供了比較詳細(xì)的示例,包括:
- 允許跨域請(qǐng)求
- 請(qǐng)求鑒權(quán)處理
- 鑒權(quán)例外處理
- 統(tǒng)一的錯(cuò)誤處理
- 自定義日志處理
本文轉(zhuǎn)載自微信公眾號(hào)「 程序員升級(jí)打怪之旅」,作者「王中陽Go」,可以通過以下二維碼關(guān)注。
轉(zhuǎn)載本文請(qǐng)聯(lián)系「 程序員升級(jí)打怪之旅」公眾號(hào)。