内容简介:今天写点有趣的小东西。事情是这样的,我经常看到有些软件加了统计数据的sdk,之后就可以实现统计接口的访问量,接口负载等等数据。而这些功能不需要原有的软件做些什么,对原来的业务完全无入侵,我觉得这样的功能很有实用性,所以没有参考其他类似的软件或者工具,我想自己试试怎么实现这样的功能。首先,我们先给要做的工具起个名字,就叫monitor。要实现无侵入,那么只能是在业务软件外面套一层,经由业务软件的流量,都需要经过monitor这一层,这让人很容易得想到了网关的功能也是类似的。恰好,golang实现反向代理十分简
前言
今天写点有趣的小东西。事情是这样的,我经常看到有些软件加了统计数据的sdk,之后就可以实现统计接口的访问量,接口负载等等数据。而这些功能不需要原有的软件做些什么,对原来的业务完全无入侵,我觉得这样的功能很有实用性,所以没有参考其他类似的软件或者工具,我想自己试试怎么实现这样的功能。
思路
首先,我们先给要做的 工具 起个名字,就叫monitor。要实现无侵入,那么只能是在业务软件外面套一层,经由业务软件的流量,都需要经过monitor这一层,这让人很容易得想到了网关的功能也是类似的。恰好,golang实现反向代理十分简单。所以,思路就有了。先实现一个反向代理,将经由业务的流量都由monitor反向代理给业务软件。接着,将访问的api放进通道中,对api进行分类,就可以统计api的访问量了。在这篇文章中,我还会用一个golang的图形库,这个库很酷,可以在终端图形化地展示我们的数据统计。
实现反向代理
func NewMultipleHostsReverseProxy(target url.URL) *httputil.ReverseProxy { director := func(req *http.Request) { req.URL.Scheme = target.Scheme req.URL.Host = target.Host req.URL.Path = target.Path go func() { ch <- req.RequestURI }() } return &httputil.ReverseProxy{Director: director} } func Proxy() { InitData() target := url.URL{ Scheme: "http", Host: ":9091", } proxy := NewMultipleHostsReverseProxy(target) log.Fatal(http.ListenAndServe(":9090", proxy)) } var ch chan string var labels map[string]float64 func InitData() { ch = make(chan string) //api通道,每访问一个api,就将api路径放至此通道 labels = make(map[string]float64) //api访问次数存储的地方 }
我们先构造一个proxy类型为*httputil.ReverseProxy,这个proxy的req会向目标地址访问,也就是我们要代理的目标访问。这段代码中,我们用9090反向代理了9091端口,也就是说,访问9091的流量会经过9090,这样我们就可以在这之间收集我们要的数据。我将req.RequestURI放进了一个channel中来实现统计。
//更新访问数据 go func() { for { select { case label := <-ch: _, has := labels[label] if has { labels[label]++ } else { labels[label] = 1 } } } }()
渲染数据
我还想要把统计的数据用图形化的方式展现出来。我用了github.com/gizak/termui,一个很棒的图形库。
首先初始化界面参数。
//初始化图形数据 bc := widgets.NewBarChart() bc.Title = "api访问量" bc.SetRect(5, 5, 100, 25) bc.BarWidth = 5 bc.BarColors = []ui.Color{ui.ColorRed, ui.ColorGreen} bc.LabelStyles = []ui.Style{ui.NewStyle(ui.ColorBlue)} bc.NumStyles = []ui.Style{ui.NewStyle(ui.ColorYellow)}
接着,写一个定时器,每秒钟刷新数据,并渲染图形。
uiEvents := ui.PollEvents() ticker := time.NewTicker(time.Second).C for { select { case e := <-uiEvents: //退出事件 switch e.ID { case "q", "<C-c>": return } case <-ticker: //定时事件 l := []string{} data := []float64{} for k, v := range labels { l = append(l, k) data = append(data, v) } if len(l) <= 0 { l = []string{"/"} data = []float64{1} } bc.Labels = l bc.Data = data ui.Render(bc) } }
测试
先写个监听9091端口的test,并运行起来。
func TestProxy(t *testing.T) { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("hello 9091")) }) log.Fatal(http.ListenAndServe(":9091", nil)) }
启动monitor,并访问9090端口。
postman.png
访问多几个不同的api,之后查看monitor界面。
monitor.png
总结
使用golang的反向代理可以简单地实现api统计的功能,并且在此基础上可以有其他的扩展,可以统计api负载情况,可以统计访问频率等等数据,在图形化界面上也可以展示更多聚合数据。完整代码可见: https://github.com/TomatoMr/monitor 。
欢迎关注我的公众号:onepunchgo,给我留言。
image
以上所述就是小编给大家介绍的《使用golang反向代理统计api访问次数》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Glow使用小结 - 统计Key出现的次数
- 【译】Swift算法俱乐部-统计出现次数
- 使用C++ STL库统计一散文中单词出现次数和行号
- PostgreSQL 14 pg_prepared_statements 新增统计软/硬解析次数
- Django annotation,减少IO次数利器
- 找出数组中出现次数超过一半的数
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Out of their Minds
Dennis Shasha、Cathy Lazere / Springer / 1998-07-02 / USD 16.00
This best-selling book is now available in an inexpensive softcover format. Imagine living during the Renaissance and being able to interview that eras greatest scientists about their inspirations, di......一起来看看 《Out of their Minds》 这本书的介绍吧!
JSON 在线解析
在线 JSON 格式化工具
Markdown 在线编辑器
Markdown 在线编辑器