什麼是中介軟體

語言: CN / TW / HK

什麼是中介軟體?

中介軟體是一種計算機軟體,可為作業系統提供的軟體應用程式提供服務,以便於各個軟體之間的溝通,特別是系統軟體和應用軟體。廣泛用於web應用和麵向服務的體系結構等。

個人理解的“web的中介軟體” 就是 ”在原始請求上增加一些和原始請求資料無關的操作,可能在請求前也可能在請求後;比如:增加日誌、驗證 Token等“。

因為大部分中介軟體跟業務邏輯沒什麼關係,因此要求中介軟體需要具備:可插拔特性。不會影響業務邏輯,哪裡要用插到哪裡的。

golang中介軟體原理

中介軟體處理程式是簡單的http.Handler,它包裝另一個http.Handler做請求的一些預處理和/或後處理。它被稱為“中介軟體”,因為它位於Go Web伺服器和實際處理程式之間的中間位置。

mux 介紹:(https://www.jianshu.com/p/8ade70e51210)

中介軟體本身只是將其http.HandlerFunc作為其引數之一,包裝它並返回一個新http.HandlerFunc的伺服器來呼叫。

舉個栗子便於理解:

package main
 
import (
   "fmt"
   "log"
   "net/http"
)
 
func foo(w http.ResponseWriter, r *http.Request) {
   fmt.Fprintln(w, "foo")
}
func bar(w http.ResponseWriter, r *http.Request) {
   fmt.Fprintln(w, "bar")
}
 
func loggingMiddleware(next http.Handler) http.Handler {
   return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
      log.Println(r.URL.Path)
      next.ServeHTTP(w, r)
   })
}
 
func main() {
 
   http.Handle("/foo", loggingMiddleware(http.HandlerFunc(foo)))
   http.Handle("/bar", loggingMiddleware(http.HandlerFunc(bar)))
   http.ListenAndServe(":8080", nil)
}

golang 如何自定義中介軟體

編寫中介軟體的邏輯

  • 自定義的中介軟體函式接收一個 http.Handler 作為引數;目的是可使用其他中介軟體或應用處理器,呼叫其他中介軟體或應用的方法就是呼叫其 HttpServe 的方法。

  • 將 http.Handler 作為返回值,這樣其他中介軟體可以使用 http.Handler 作為輸入的引數,達到鏈式呼叫。

例如:

func middlewareHandler(next http.Handler) http.Handler {
 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 // 在執行應用處理器前編譯中介軟體的邏輯
 next.ServeHTTP(w, r)
 // 在執行應用處理器後將會執行的編譯中介軟體的邏輯
 })
}

通過向下傳遞 http.Handler 實現了多箇中間件的呼叫。

package main
 
import (
    "fmt"
    "log"
    "net/http"
    "time"
)
 
func logginHandler(next http.Handler) http.Handler{
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){
        start := time.Now()
        log.Printf("Started %s %s",r.Method, r.URL.Path)
        next.ServeHTTP(w,r)
        log.Printf("Completed %s in %v", r.URL.Path, time.Since(start))
    })
}
 
func index(w http.ResponseWriter,r *http.Request ){
    log.Println("Executing index handler")
    fmt.Fprintf(w,"welcome!")
}
 
func about(w http.ResponseWriter, r *http.Request){
    log.Println("Executing about handler")
    fmt.Fprintf(w,"Go Middleware")
}
 
func iconHandler(w http.ResponseWriter, r *http.Request){
 
}
 
func main()  {
 
    http.HandleFunc("/favicon.ico", iconHandler)
 
    indexHandler := http.HandlerFunc(index)
    aboutHandler := http.HandlerFunc(about)
 
    http.Handle("/",logginHandler(indexHandler))
    http.Handle("/about",logginHandler(aboutHandler))
 
    server :=  &http.Server{
        Addr:":8080",
    }
 
    log.Println("Listening...")
    server.ListenAndServe()
}
  • 上面的程式碼關鍵是 logginHandler 這個日誌處理器,作為中介軟體會攔截請求,進行處理輸出日誌,通過next.ServeHTTP(w,r)將請求向下進行傳遞
  • 建立兩個簡單路由處理器index和about。都是向客戶端輸出不同的文字。
  • http.Handle("/",logginHandler(indexHandler)) 通過 logginHandler 函式進行包裹,日誌中介軟體可以攔截到發起的請求進行一些中介軟體邏輯,中介軟體邏輯可以位於next.ServeHTTP(w,r)之前或之後。通過下面的輸出我們可以清晰可見程式碼執行的順序。
Listening...
 Started GET /
 Executing index handler
 Completed / in 41.129µs
 Started GET /
 Executing index handler
 Completed / in 50.475µs
 Started GET /about
 Executing about handler
 Completed /about in 49.483µs

參考資料

參考資料 !

參考資料