Golang Go语言中实现一个http router库玩玩

Golang Go语言中实现一个http router库玩玩

brouter

项目一开始时只是一个新的尝试,看能否性能比 httprouter 更快。

项目地址

https://github.com/antlabs/brouter

demo

package main

import ( “fmt” “net/http” “log”

"github.com/antlabs/brouter"

)

func Index(w http.ResponseWriter, r *http.Request, _ brouter.Params) { fmt.Fprint(w, “Welcome!\n”) }

func Hello(w http.ResponseWriter, r *http.Request, ps brouter.Params) { fmt.Fprintf(w, “hello, %s!\n”, ps.ByName(“name”)) }

func main() { router := brouter.New() router.GET("/", Index) router.GET("/hello/:name", Hello)

log.Fatal( http.ListenAndServe(":8080", router))

}

测试结果

  • httprouter 1.3
  • brouter 0.0.1
GithubAPI Routes: 180
GithubAPI2 Routes: 203
   BeegoMuxRouter: 97024 Bytes
   BoneRouter: 86368 Bytes
   ChiRouter: 64584 Bytes
   HttpRouter: 35360 Bytes
   BRouter: 51096 Bytes
   trie-mux: 121736 Bytes
   MuxRouter: 1373064 Bytes
   GoRouter1: 76528 Bytes
   GoRouter2: 84624 Bytes
#Static Routes: 157
   HttpRouter: 21680 Bytes
   BRouter: 35208 Bytes

goos: linux goarch: amd64 pkg: test BenchmarkBeegoMuxRouterWithGithubAPI-4 10000 111713 ns/op 116352 B/op 900 allocs/op BenchmarkBoneRouterWithGithubAPI-4 721 1546779 ns/op 562878 B/op 6807 allocs/op BenchmarkTrieMuxRouterWithGithubAPI-4 19060 64217 ns/op 57024 B/op 468 allocs/op BenchmarkBRouterWithGithubAPI-4 70467 16971 ns/op 0 B/op 0 allocs/op BenchmarkHttpRouterWithGithubAPI-4 45830 26609 ns/op 11744 B/op 144 allocs/op BenchmarkGoRouter1WithGithubAPI-4 24042 49632 ns/op 11920 B/op 360 allocs/op BenchmarkGoRouter2WithGithubAPI2-4 21088 57408 ns/op 13832 B/op 406 allocs/op BenchmarkChiRouterWithGithubAPI2-4 8469 128427 ns/op 106000 B/op 1110 allocs/op BenchmarkMuxRouterWithGithubAPI2-4 358 3414899 ns/op 59373 B/op 992 allocs/op BenchmarkHttpRouter_StaticAll-4 120054 9994 ns/op 0 B/op 0 allocs/op BenchmarkBRouter_StaticAll-4 111614 10838 ns/op 0 B/op 0 allocs/op PASS ok test 15.950s

  • httprouter fe77dd05ab5a80f54110cccf1b7d8681c2648323(在测试这版本时候遇到过 panic)
  • brouter 0.0.1
GithubAPI Routes: 180
GithubAPI2 Routes: 203
   BeegoMuxRouter: 97232 Bytes
   BoneRouter: 88296 Bytes
   ChiRouter: 64592 Bytes
   HttpRouter: 33480 Bytes
   BRouter: 51096 Bytes
   trie-mux: 123448 Bytes
   MuxRouter: 1373064 Bytes
   GoRouter1: 76320 Bytes
   GoRouter2: 85040 Bytes
#Static Routes: 157
   HttpRouter: 21712 Bytes
   BRouter: 35200 Bytes

goos: linux goarch: amd64 pkg: test BenchmarkBeegoMuxRouterWithGithubAPI-4 10000 111217 ns/op 116352 B/op 900 allocs/op BenchmarkBoneRouterWithGithubAPI-4 780 1554833 ns/op 562871 B/op 6807 allocs/op BenchmarkTrieMuxRouterWithGithubAPI-4 19020 62882 ns/op 57024 B/op 468 allocs/op BenchmarkBRouterWithGithubAPI-4 69400 17426 ns/op 0 B/op 0 allocs/op BenchmarkHttpRouterWithGithubAPI-4 75178 15907 ns/op 0 B/op 0 allocs/op BenchmarkGoRouter1WithGithubAPI-4 24426 49969 ns/op 11920 B/op 360 allocs/op BenchmarkGoRouter2WithGithubAPI2-4 21087 56849 ns/op 13832 B/op 406 allocs/op BenchmarkChiRouterWithGithubAPI2-4 8490 129326 ns/op 105974 B/op 1110 allocs/op BenchmarkMuxRouterWithGithubAPI2-4 349 3383843 ns/op 59369 B/op 992 allocs/op BenchmarkHttpRouter_StaticAll-4 120390 10094 ns/op 0 B/op 0 allocs/op BenchmarkBRouter_StaticAll-4 113125 10633 ns/op 0 B/op 0 allocs/op PASS ok test 15.887s

测试代码位置

https://github.com/junelabs/brouter-benchmark


更多关于Golang Go语言中实现一个http router库玩玩的实战教程也可以访问 https://www.itying.com/category-94-b0.html

9 回复

发了这么会儿,都没人找我吹牛的。。。

更多关于Golang Go语言中实现一个http router库玩玩的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


因为你没有整活

啥是整活?

感觉我的比你简单点,我也贴下我的路由器和性能测试,性能是 httprouter 的 70-90%内存更少功能更多,节点匹配顺序测试和 httprouter 不同,mux 这个库感觉性能低,但是没想到性能差几百倍了。

https://github.com/eudore/eudore/blob/master/routerstd.go

https://github.com/eudore/web-framework-benchmark

哈哈,为了性能放弃了一些可读性。

httprouter 找儿子节点的方式会生成更少的汇编代码,所以效率很高。一开始我用查表的方式,都慢一点。是不是很违背直觉。。。

首先高性能路由器使用 radix 和 trie 是标配,没有的就是低性能例如 mux 。

在 httprouter 中如果节点是下面的路由规则越多,他的权重越高,那么这个节点在 childs 里面是顺序考前,这种规则在只访问一次的情况下,静态路由会强变量性能弱。

而 httprouter 代码真心丑,函数复杂的贼高,还要没有匹配优先级。

哈哈,同感,httprouter 的代码真是丑爆了。

当然,实现一个简单的HTTP router库是一个很好的学习Go语言的项目。下面是一个基本的实现思路:

  1. 定义路由结构: 首先,你需要定义一个结构体来表示一个路由,包括路径(Path)和处理函数(Handler)。

  2. 创建路由表: 使用一个map来存储路由,其中键是路径,值是处理函数。这样你可以快速查找和匹配路径。

  3. 解析请求: 当HTTP请求到达时,解析请求的URL路径,并在路由表中查找匹配的路由。

  4. 调用处理函数: 如果找到匹配的路由,调用相应的处理函数来处理请求。

  5. 处理404错误: 如果没有找到匹配的路由,返回404错误。

  6. 支持参数: 为了更灵活,你可以支持路径参数,例如/user/:id,其中:id是一个参数。

  7. 测试: 编写一些测试用例来验证你的router库是否按预期工作。

  8. 优化: 根据需求,你可以添加更多功能,如支持GET、POST等HTTP方法,中间件支持,静态文件服务等。

这是一个非常基础的实现思路,实际上构建一个功能完善的HTTP router库要复杂得多,涉及更多的细节和优化。但这是一个很好的起点,可以帮助你深入理解Go语言的网络编程和HTTP处理机制。祝你玩得开心!

回到顶部