<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                今天的課程安排 流控 ***** ### 流控 為什么要流控呢? > 一年一度的「雙 11」又要到了,阿里的碼農們進入了一年中最辛苦的時光。各種容量評估、壓測、擴容讓我們忙得不可開交。洛陽親友如相問,就說我搞雙十一。 如何讓系統在洶涌澎湃的流量面前談笑風生?我們的策略是不要讓系統超負荷工作。如果現有的系統扛不住業務目標怎么辦?加機器!機器不夠怎么辦?業務降級,系統限流! 正所謂「他強任他強,清風拂山崗;他橫任他橫,明月照大江」,降級和限流是大促保障中必不可少的神兵利器,丟卒保車,以暫停邊緣業務為代價保障核心業務的資源,以系統不被突發流量壓掛為第一要務。 設置網站最大流量為1W第一個用戶進來返回正常信息第9999位用戶進來返回正常信息第1W1個用戶進來不提供服務 我們這里流控算法Token Bucket 令牌桶算法 ![](https://box.kancloud.cn/84db1e1bef847bc4c908b32f88b8d39c_373x446.png) 用戶進來給他一個token,用戶離開就回收token 是不是很簡單啊! golang實現思路 初始化一個channel 用戶進來判斷channel中數據的len 再判斷初始化max長度的大小 如果>=初始化長度就是流量過了 if < 初始化長度 就是流量還沒有到紅線 此時想channel添加數 如果用戶結束鏈接就想channel取數 哈哈非常easy吧 大家先動手實踐一下,再看我的代碼 這個就放在router文件夾下吧flowControl.go ``` package router import "log" type BucketLimit struct { count int // 定義最大流量 bucket chan int // 定義令牌桶 } func NewBucketLimit(cc int) *BucketLimit { return &BucketLimit{ cc, make(chan int,cc), } } // 獲得令牌 func (cl *BucketLimit) GetConn() bool { // 如果滿了 if len(cl.bucket) >= cl.count { log.Println("滿了") return false } // 沒有滿 就頒發令牌 cl.bucket <- 1 return true } // 回收令牌 func (cl *BucketLimit) ReleaseConn() { i := <-cl.bucket log.Printf("New connction coming:%d\n",i) } ``` 是不是非常簡單啊! 問題來了,寫是寫出來了,但是沒有和http關聯啊! 我們先做一個粗粒度的限流把,限制整個服務的流量 新建一個middleware.go ``` package router import ( "GolangWebCourseware/response" "github.com/julienschmidt/httprouter" "net/http" ) type middleWareHandle struct { R *httprouter.Router L *BucketLimit // 流控 } func NewMiddleWareHandler(r *httprouter.Router,cc int) http.Handler { handle := &middleWareHandle{} handle.R =r handle.L = NewBucketLimit(cc) return handle } // 流控核心 func (m *middleWareHandle) ServeHTTP(w http.ResponseWriter,r *http.Request) () { // 從桶中獲得令牌 if !m.L.GetConn() { response.SendNormalResponse(w,"Too many requests",http.StatusTooManyRequests) return } m.R.ServeHTTP(w,r) defer func() { // 當連接結束 令牌返回令牌桶中 m.L.ReleaseConn() }() } ``` 修改main方法 ``` func main() { registerRouter := router.RegisterRouter()// 注冊路由 fmt.Println("server is runing ...") // middleware 接替 handler := router.NewMiddleWareHandler(registerRouter,1000) err := http.ListenAndServe(":8085", handler) if err != nil { fmt.Println("server error:",err.Error()) } } ``` 本次課程代碼: [https://github.com/dollarkillerx/GolangWebCourseware/tree/%E6%B5%81%E6%8E%A7](https://github.com/dollarkillerx/GolangWebCourseware/tree/%E6%B5%81%E6%8E%A7)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看