Golang 限速器

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

限速器

之前看到這篇golang並發編程的兩種限速方法,覺得 sleep 等待的方式不是特別好,喚醒線程的時間比較長。而且1s內的請求只能均勻的到來,如瞬間來 N 個, 那麼只有一個能立刻返回,剩下的只能等待。

【修正】
根據的說明,無論是 sleep 還是 chan block, 發生的事情都是 G 和 P 分離,等待下次輪訓,再接著執行,所以可能效能是幾乎一樣的。(這種說法可能不準確,沒有深入)

限速器的作用還是比較重要的,特別是協程使用較多的應用,如果不加限制,可能會OOM。

簡單說下思路:預設時間間隔定為1秒,簡化問題。如果 調用 Limit() bool 介面,如果一秒內運行次數到達某個值,那麼就阻塞, 直到下一個1秒重新計數。

代碼

package libimport (    "sync/atomic"    "time")type RateLimiter struct {    limit  uint64    count  uint64    ticker *time.Ticker    lockCh chan struct{}}func NewRateLimiter(limit uint64) *RateLimiter {    ticker := time.NewTicker(time.Second)    r := &RateLimiter{        limit:  limit,        count:  0,        ticker: ticker,        lockCh: make(chan struct{}),    }    go func() {        for range ticker.C {            if r.count > r.limit {                select {                case <-r.lockCh:                default:                    r.resetCount()                }            }                        if r.count > 0 {                r.resetCount()                            }        }    }()    return r}func (r *RateLimiter) Limit() bool {    r.addCount(1)    if r.getCount() > r.limit {        var s struct{}        r.lockCh <- s    }    return true}func (r *RateLimiter) addCount(interval uint64) {    atomic.AddUint64(&r.count, interval)}func (r *RateLimiter) getCount() uint64 {    return atomic.LoadUint64(&r.count)}func (r *RateLimiter) resetCount() {    atomic.StoreUint64(&r.count, 1)}

測試

package libimport (    "log"    "testing"    "time")func TestLimit(t *testing.T) {    limiter := NewRateLimiter(3)    start := time.Now()    for i := 0; i < 30; i++ {        if limiter.Limit() {            log.Printf("i is %d \n", i)        }    }    end := time.Now()    d := end.Sub(start)    log.Println("spends seconds: ", d.Seconds())}

比較

對比了開篇的sleep實現,limiter設為每秒3次,迴圈30次,用時分別為:

2016/08/31 14:38:26 my limiter spends seconds:  9.00220346s2016/08/31 14:38:35 sleep limiter spends seconds:  9.762009934s

這裡sleep limiter多sleep了兩次,大約 0.67s, 減去這個值等於9.092009934。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.