最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang官方限流器庫實現(xiàn)限流示例詳解

 更新時間:2022年08月18日 11:17:56   作者:jiaxwu  
這篇文章主要為大家介紹了Golang官方限流器庫使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

在翻Golang官方庫的過程中,發(fā)現(xiàn)一個有趣的庫golang.org/x/time ,里面只有一個類rate,研究了一下發(fā)現(xiàn)它是一個限流器,實現(xiàn)了很多的功能,當(dāng)然它的核心原理并不復(fù)雜,也就是令牌桶算法。

令牌桶算法的原理是:令牌桶會不斷地把令牌添加到桶里,而請求會從桶中獲取令牌,只有擁有令牌地請求才能被接受。因為桶中可以提前保留一些令牌,所以它允許一定地突發(fā)流量通過。

例子

下面是限流算法常見的寫法,首先判斷是否有令牌,如果有就通過,否則直接失敗。

package main
import (
	"fmt"
	"time"
	"golang.org/x/time/rate"
)
func main() {
        // 每0.1秒生成一個令牌,也就是一秒10個令牌,最大保留令牌上限10
	l := rate.NewLimiter(rate.Every(time.Second/10), 10)
	for i := 0; i < 10; i++ {
		go func(i int) {
			for {
                                // 判斷是否有令牌,如果有就輸出
				if l.Allow() {
					fmt.Printf("allow %d\n", i)
				}
                                // 每0.5秒請求一次
				time.Sleep(time.Second / 2)
			}
		}(i)
	}
	time.Sleep(time.Second * 10)
}

上面的rate.Every(time.Second/10)會返回一個Limit類型,代表每秒生成多少個令牌。

這個庫還提供了另外一種寫法,等待直到有令牌為止(或超時):

func main() {
	l := rate.NewLimiter(rate.Every(time.Second/10), 100)
	for i := 0; i < 10; i++ {
		go func(i int) {
			for {
                                // 等待直到有令牌
				if err := l.Wait(context.TODO()); err != nil {
				} else {
					fmt.Printf("allow %d\n", i)
				}
				time.Sleep(time.Second / 2)
			}
		}(i)
	}
	time.Sleep(time.Second * 10)
}

這樣在某些場景下我們可以讓請求等待一會,而不是直接失敗。

還有一個更加特殊的請求令牌方式,也就是先預(yù)留令牌,到指定時間不再需要去獲取令牌,直接執(zhí)行操作即可:

func main() {
	l := rate.NewLimiter(rate.Every(time.Second/10), 10)
	for i := 0; i < 10; i++ {
		go func(i int) {
			for {
                                // 先預(yù)留令牌
				if r := l.Reserve(); r.OK() {
                                        // 休眠直到令牌生效
					time.Sleep(r.Delay())
					fmt.Printf("allow %d\n", i)
				}
				time.Sleep(time.Second / 2)
			}
		}(i)
	}
	time.Sleep(time.Second * 10)
}

當(dāng)然,如果預(yù)留的令牌不想使用了,也可以使用r.Cancel()歸還已預(yù)留的令牌。

上面的Allow()、Wait()、Reserve()都是一次消耗一個令牌,其實都有對應(yīng)的AllowN()、WaitN()、ReserveN()方法,一次消耗N個令牌,這樣就可以根據(jù)任務(wù)消耗的資源靈活的消耗令牌。

實現(xiàn)

不管我們從Allow()、Wait()還是Reserve()進去,最終都會進入到reserveN(now time.Time, n int, maxFutureReserve time.Duration) Reservation 方法:

首先在進入方法的時候,會先處理兩種特殊情況:

        // 如果無限生成令牌,則直接返回
        if lim.limit == Inf {
		return Reservation{
			ok:        true,
			lim:       lim,
			tokens:    n,
			timeToAct: now,
		}
        // 如果不會生成令牌,則在初始令牌里面拿,直到拿完為止
	} else if lim.limit == 0 {
		var ok bool
		if lim.burst >= n {
			ok = true
			lim.burst -= n
		}
		return Reservation{
			ok:        ok,
			lim:       lim,
			tokens:    lim.burst,
			timeToAct: now,
		}
	}

然后重新計算當(dāng)前有多少令牌,減去要消耗的令牌:

        // 計算當(dāng)前有多少令牌
	now, last, tokens := lim.advance(now)
	// 減去要消耗的N個令牌
	tokens -= float64(n)
        // 如果剩余令牌為負(fù)數(shù),那么計算一下要等待多久才能拿到令牌
        var waitDuration time.Duration
	if tokens < 0 {
		waitDuration = lim.limit.durationFromTokens(-tokens)
	}
        // 判斷請求是否成功,maxFutureReserve代表最大可以等待的時間,也就是請求能否接收拿到令牌需要等待的時間
        ok := n <= lim.burst && waitDuration <= maxFutureReserve

余下的代碼就是更新限流器的狀態(tài)。

小結(jié)

可以看到這個令牌桶限流器實現(xiàn)的功能非常的豐富,如果需要令牌桶限流器,可以優(yōu)先考慮使用這個實現(xiàn)。

以上就是Golang官方限流器庫使用示例詳解的詳細內(nèi)容,更多關(guān)于Golang官方限流器庫的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 重學(xué)Go語言之基礎(chǔ)數(shù)據(jù)類型詳解

    重學(xué)Go語言之基礎(chǔ)數(shù)據(jù)類型詳解

    Go語言有非常強大的數(shù)據(jù)類型系統(tǒng),其支持的數(shù)據(jù)類型大體上可分為四類:基礎(chǔ)數(shù)據(jù)類型、引用數(shù)據(jù)類型、接口類型、復(fù)合類型。本文就來講講它們各自的用法吧
    2023-02-02
  • Golang實現(xiàn)多存儲驅(qū)動設(shè)計SDK案例

    Golang實現(xiàn)多存儲驅(qū)動設(shè)計SDK案例

    這篇文章主要介紹了Golang實現(xiàn)多存儲驅(qū)動設(shè)計SDK案例,Gocache是一個基于Go語言編寫的多存儲驅(qū)動的緩存擴展組件,更多具體內(nèi)容感興趣的小伙伴可以參考一下
    2022-09-09
  • Go語言中websocket的使用demo分享

    Go語言中websocket的使用demo分享

    WebSocket是一種在單個TCP連接上進行全雙工通信的協(xié)議。這篇文章主要和大家分享了一個Go語言中websocket的使用demo,需要的可以參考一下
    2022-12-12
  • Go語言設(shè)置JSON的默認(rèn)值操作

    Go語言設(shè)置JSON的默認(rèn)值操作

    這篇文章主要介紹了Go語言設(shè)置JSON的默認(rèn)值操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go高級特性探究之recover捕獲panic詳解

    Go高級特性探究之recover捕獲panic詳解

    在Go語言中,當(dāng)程序出現(xiàn)panic(即運行時錯誤)時,程序會立即停止當(dāng)前的執(zhí)行流程,而recover函數(shù)的作用就是捕獲這個panic,下面就來看看具體是怎么操作的吧
    2023-06-06
  • 深入解析快速排序算法的原理及其Go語言版實現(xiàn)

    深入解析快速排序算法的原理及其Go語言版實現(xiàn)

    這篇文章主要介紹了快速排序算法的原理及其Go語言版實現(xiàn),文中對于快速算法的過程和效率有較為詳細的說明,需要的朋友可以參考下
    2016-04-04
  • go語言簡單的處理http請求的函數(shù)實例

    go語言簡單的處理http請求的函數(shù)實例

    這篇文章主要介紹了go語言簡單的處理http請求的函數(shù),實例分析了Go語言處理http請求的技巧,需要的朋友可以參考下
    2015-03-03
  • GO語言標(biāo)準(zhǔn)錯誤處理機制error用法實例

    GO語言標(biāo)準(zhǔn)錯誤處理機制error用法實例

    這篇文章主要介紹了GO語言標(biāo)準(zhǔn)錯誤處理機制error用法,實例分析了錯誤處理機制的具體用法,具有一定的參考借鑒價值,需要的朋友可以參考下
    2014-12-12
  • Golang?template?包基本原理分析

    Golang?template?包基本原理分析

    這篇文章主要為大家介紹了Golang?template?包基本原理分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • Golang中調(diào)用deepseekr1的教程詳解

    Golang中調(diào)用deepseekr1的教程詳解

    這篇文章主要為大家詳細介紹了Golang中調(diào)用deepseekr1的相關(guān)教程,文中的示例代碼講解詳細,具有一定的借鑒價值,感興趣的小伙伴可以了解下
    2025-02-02

最新評論

浦江县| 海安县| 墨玉县| 温州市| 寻甸| 普兰县| 巨鹿县| 岱山县| 东丽区| 章丘市| 嵊州市| 会昌县| 云霄县| 固原市| 和龙市| 商洛市| 怀仁县| 漳州市| 泸溪县| 海安县| 海阳市| 台南县| 安仁县| 定襄县| 慈溪市| 泗洪县| 峡江县| 开化县| 东至县| 安阳市| 军事| 三亚市| 津南区| 韶山市| 于田县| 临汾市| 宝清县| 长春市| 萝北县| 鹿泉市| 碌曲县|