golang高性能支持HTTP/2的多路复用路由插件库xmux的使用
Golang高性能支持HTTP/2的多路复用路由插件库xmux的使用
简介
Xmux是一个基于xhandler的轻量级高性能HTTP请求多路复用器。Xmux从httprouter的分支中获得其速度优势,路由参数存储在context
中而不是作为额外参数传递。
特性
- 精确匹配:每个请求只能精确匹配一个路由或完全不匹配,避免了意外匹配
- 自动处理尾部斜杠:自动重定向缺少或多余的尾部斜杠
- 路径自动校正:可以修正大小写错误并移除多余的路径元素
- 路由参数:直接在路由模式中定义参数,无需手动解析URL
- 路由组:创建路由组而不会产生每次请求的开销
- 零垃圾:匹配和分发过程不产生垃圾数据
- 恐慌恢复:可以设置恐慌处理程序来处理HTTP请求处理期间的恐慌
- 自定义NotFound和MethodNotAllowed处理程序
基本用法
package main
import (
"fmt"
"log"
"net/http"
"context"
"github.com/rs/xhandler"
"github.com/rs/xmux"
)
// 定义处理函数
func Index(ctx context.Context, w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Welcome!\n")
}
func Hello(ctx context.Context, w http.ResponseWriter, r *http.Request) {
// 从context中获取路由参数
fmt.Fprintf(w, "hello, %s!\n", xmux.Param(ctx, "name"))
}
func main() {
// 创建新的mux实例
mux := xmux.New()
// 注册路由和处理函数
mux.GET("/", xhandler.HandlerFuncC(Index))
mux.GET("/hello/:name", xhandler.HandlerFuncC(Hello))
// 启动HTTP服务器
log.Fatal(http.ListenAndServe(":8080", xhandler.New(context.Background(), mux)))
}
中间件链
package main
import (
"context"
"fmt"
"log"
"net/http"
"time"
"github.com/rs/xhandler"
"github.com/rs/xmux"
)
func main() {
// 创建中间件链
c := xhandler.Chain{}
// 添加上下文感知的中间件
c.UseC(xhandler.CloseHandler)
c.UseC(xhandler.TimeoutHandler(2 * time.Second))
// 创建mux实例
mux := xmux.New()
// 使用中间件链处理路由
mux.GET("/welcome/:name", xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "Welcome %s!", xmux.Param(ctx, "name"))
}))
// 启动服务器
if err := http.ListenAndServe(":8080", c.Handler(mux)); err != nil {
log.Fatal(err)
}
}
路由参数
Xmux支持两种类型的参数:
-
命名参数:格式为
:name
,只匹配单个路径段user := xmux.Param(ctx, "user")
-
通配参数:格式为
*name
,匹配所有内容,必须放在路径末尾Pattern: /src/*filepath /src/ match /src/somefile.go match /src/subdir/somefile.go match
多域名/子域名支持
// 定义HostSwitch类型实现xhandler.HandlerC接口
type HostSwitch map[string]xhandler.HandlerC
func (hs HostSwitch) ServeHTTPC(ctx context.Context, w http.ResponseWriter, r *http.Request) {
if handler := hs[r.Host]; handler != nil {
handler.ServeHTTPC(ctx, w, r)
} else {
http.Error(w, "Forbidden", 403)
}
}
func main() {
c := xhandler.Chain{}
mux := xmux.New()
mux.GET("/", Index)
mux.GET("/hello/:name", Hello)
// 为不同域名配置不同路由
hs := make(HostSwitch)
hs["example.com:12345"] = mux
if err := http.ListenAndServe(":12345", c.Handler(hs)); err != nil {
log.Fatal(err)
}
}
基准测试
Xmux性能接近httprouter,虽然由于使用context存储参数略有开销,但仍然优于其他路由器:
BenchmarkXhandler_APIStatic-8 50000000 39.6 ns/op 0 B/op 0 allocs/op
BenchmarkChi_APIStatic-8 3000000 439 ns/op 144 B/op 5 allocs/op
BenchmarkHTTPRouter_APIStatic-8 50000000 37.3 ns/op 0 B/op 0 allocs/op
工作原理
Xmux使用压缩的动态trie(基数树)结构进行高效匹配,每个请求方法管理单独的树,子节点按优先级排序(基于注册的处理程序数量)。
基本认证示例
func BasicAuth(user, pass []byte, next xhandler.HandlerC) xhandler.HandlerC {
return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
const basicAuthPrefix string = "Basic "
auth := r.Header.Get("Authorization")
if strings.HasPrefix(auth, basicAuthPrefix) {
payload, err := base64.StdEncoding.DecodeString(auth[len(basicAuthPrefix):])
if err == nil {
pair := bytes.SplitN(payload, []byte(":"), 2)
if len(pair) == 2 && bytes.Equal(pair[0], user) && bytes.Equal(pair[1], pass) {
next.ServeHTTPC(ctx, w, r)
return
}
}
}
w.Header().Set("WWW-Authenticate", "Basic realm=Restricted")
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
})
}
func main() {
user := []byte("gordon")
pass := []byte("secret!")
c := xhandler.Chain{}
mux := xmux.New()
mux.GET("/", xhandler.HandlerFuncC(Index))
mux.GET("/protected/", BasicAuth(user, pass, xhandler.HandlerFuncC(Protected)))
log.Fatal(http.ListenAndServe(":8080", c.Handler(mux)))
}
Xmux是一个高效、功能丰富的路由库,特别适合需要高性能和HTTP/2支持的Golang web应用。
更多关于golang高性能支持HTTP/2的多路复用路由插件库xmux的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang高性能支持HTTP/2的多路复用路由插件库xmux的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
xmux - 高性能HTTP/2多路复用路由库
xmux是一个轻量级、高性能的Go语言HTTP路由库,专门为HTTP/2多路复用设计,提供了比标准库net/http
更高效的路由能力。
主要特性
- HTTP/2多路复用支持:原生支持HTTP/2协议特性
- 高性能路由:基于Radix树实现的路由匹配
- 中间件支持:灵活的中间件机制
- 路由分组:方便的路由分组管理
- 路径参数:支持
:param
和*wildcard
参数
安装
go get github.com/rs/xmux
基本使用示例
package main
import (
"fmt"
"net/http"
"github.com/rs/xmux"
)
func main() {
mux := xmux.New()
// 简单路由
mux.GET("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, xmux!"))
})
// 带参数的路由
mux.GET("/user/:name", func(w http.ResponseWriter, r *http.Request) {
name := xmux.Param(r, "name")
w.Write([]byte(fmt.Sprintf("Hello, %s!", name)))
})
// 通配符路由
mux.GET("/files/*path", func(w http.ResponseWriter, r *http.Request) {
path := xmux.Param(r, "path")
w.Write([]byte(fmt.Sprintf("File path: %s", path)))
})
// 路由分组
api := mux.Group("/api")
{
api.GET("/users", listUsers)
api.POST("/users", createUser)
api.GET("/users/:id", getUser)
}
// 启动HTTP/2服务器
http.ListenAndServeTLS(":443", "server.crt", "server.key", mux)
}
func listUsers(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("User list"))
}
func createUser(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Create user"))
}
func getUser(w http.ResponseWriter, r *http.Request) {
id := xmux.Param(r, "id")
w.Write([]byte(fmt.Sprintf("Get user %s", id)))
}
中间件使用
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Printf("Request: %s %s\n", r.Method, r.URL.Path)
next.ServeHTTP(w, r)
})
}
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Authorization") == "" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
func main() {
mux := xmux.New()
// 全局中间件
mux.Use(loggingMiddleware)
// 公共路由
mux.GET("/public", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Public content"))
})
// 需要认证的路由分组
private := mux.Group("/private")
private.Use(authMiddleware)
{
private.GET("/data", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Private data"))
})
}
http.ListenAndServe(":8080", mux)
}
性能优化技巧
- 避免频繁的路由注册:在初始化时一次性注册所有路由
- 合理使用中间件:避免不必要的中间件处理
- 利用HTTP/2特性:保持长连接,减少连接开销
- 使用路由分组:提高路由匹配效率
与标准库对比
xmux相比标准库net/http
的ServeMux
有以下优势:
- 支持路径参数和通配符
- 路由匹配速度更快
- 更灵活的路由分组和中间件支持
- 更好的HTTP/2支持
注意事项
- xmux与标准库完全兼容,可以无缝替换
- 对于简单应用,标准库可能更合适
- 在生产环境中建议启用HTTPS以充分利用HTTP/2特性
xmux是一个轻量但功能强大的路由库,特别适合需要高性能HTTP/2支持的Go Web应用开发。