golang实现流量控制操作

lu569368 · · 2447 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

利用`go` `channel`实现限流量控制,原理:设置一个缓冲通道,设置访问中间键,当用户请求连接时判断channel里面长度是不是大于设定的缓冲值,如果没有就存入一个值进入channel,如果大于缓冲值,channel自动阻塞。当用户请求结束的时候,取出channel里面的值。 ** 文章转自go语言中文文档 [http://www.topgoer.com](http://www.topgoer.com/?from=studygolang "文章转自go语言中文文档http://www.topgoer.com") ** 如果想限制用户HTTP请求进行速率限制可以参考 https://github.com/didip/tollbooth 这个中间键 目录: -videos --ce.html -limiter.go -main.go main.go文件代码: ```go package main import ( "log" "net/http" "text/template" "time" "github.com/julienschmidt/httprouter" ) type middleWareHandler struct { r *httprouter.Router l *ConnLimiter } //NewMiddleWareHandler ... func NewMiddleWareHandler(r *httprouter.Router, cc int) http.Handler { m := middleWareHandler{} m.r = r m.l = NewConnLimiter(cc) return m } func (m middleWareHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if !m.l.GetConn() { defer func() { recover() }() log.Panicln("Too many requests") return } m.r.ServeHTTP(w, r) defer m.l.ReleaseConn() } //RegisterHandlers ... func RegisterHandlers() *httprouter.Router { router := httprouter.New() router.GET("/ce", ce) return router } func ce(w http.ResponseWriter, r *http.Request, p httprouter.Params) { //为了演示效果这块设置了等待 time.Sleep(time.Second * 100) t, _ := template.ParseFiles("./videos/ce.html") t.Execute(w, nil) } func main() { r := RegisterHandlers() //里面的参数2为设置的最大流量 mh := NewMiddleWareHandler(r, 2) http.ListenAndServe(":9000", mh) } ``` limiter.go文件代码 ```go package main import ( "log" ) //ConnLimiter 定义一个结构体 type ConnLimiter struct { concurrentConn int bucket chan int } //NewConnLimiter ... func NewConnLimiter(cc int) *ConnLimiter { return &ConnLimiter{ concurrentConn: cc, bucket: make(chan int, cc), } } //GetConn 获取通道里面的值 func (cl *ConnLimiter) GetConn() bool { if len(cl.bucket) >= cl.concurrentConn { log.Printf("Reached the rate limitation.") return false } cl.bucket <- 1 return true } //ReleaseConn 释放通道里面的值 func (cl *ConnLimiter) ReleaseConn() { c := <-cl.bucket log.Printf("New connction coming: %d", c) } ``` videos/ce.html文件代码 ```go <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> 欢迎访问www.5lmh.com </body> </html> ```

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:701969077

2447 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传