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

Go語(yǔ)言使用漏桶算法和令牌桶算法來(lái)實(shí)現(xiàn)API限流

 更新時(shí)間:2024年11月21日 10:13:10   作者:左詩(shī)右碼  
為防止服務(wù)器被過(guò)多的請(qǐng)求壓垮,限流是一個(gè)至關(guān)重要的技術(shù)手段,下面我們就來(lái)看看如何使用漏桶算法和令牌桶算法來(lái)實(shí)現(xiàn) API 的限流吧

在現(xiàn)代 Web 應(yīng)用程序中,流量的突增是不可避免的。為防止服務(wù)器被過(guò)多的請(qǐng)求壓垮,限流(Rate Limiting) 是一個(gè)至關(guān)重要的技術(shù)手段。

本文將通過(guò) Go 語(yǔ)言的 Gin 框架,演示如何使用漏桶算法令牌桶算法來(lái)實(shí)現(xiàn) API 的限流。

限流的意義

限流的主要目的是保護(hù)系統(tǒng)資源,防止因請(qǐng)求量過(guò)大導(dǎo)致服務(wù)器崩潰。同時(shí),它也能防止惡意用戶對(duì)系統(tǒng)的攻擊,確保服務(wù)的穩(wěn)定性和可用性。

兩種常見的限流算法

1.漏桶算法(Leaky Bucket)

漏桶算法將請(qǐng)求視為水滴,水滴先進(jìn)入桶中,然后以固定的速率從桶中流出。如果請(qǐng)求的速率超過(guò)了桶的流出速率,多余的請(qǐng)求將會(huì)被丟棄。

這個(gè)算法的優(yōu)點(diǎn)很明顯,就是讓請(qǐng)求非常穩(wěn)定,但是缺點(diǎn)也很明顯,因?yàn)檎?qǐng)求非常穩(wěn)定,就不適于一些秒殺等一些可能在某一段時(shí)間會(huì)有洪峰流量的場(chǎng)景。不太好適情況控制流量的進(jìn)入。

2.令牌桶算法(Token Bucket)

令牌桶算法中,系統(tǒng)會(huì)以固定的速率向桶中加入令牌,每個(gè)請(qǐng)求需要獲取一個(gè)令牌才能執(zhí)行。如果桶中沒有足夠的令牌,請(qǐng)求將被拒絕。

代碼實(shí)現(xiàn)

在這個(gè)示例中,我們將展示如何在 Gin 框架中應(yīng)用這兩種算法來(lái)實(shí)現(xiàn) API 的限流。

package main

import (
	"fmt"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	ratelimit2 "github.com/juju/ratelimit" // 令牌桶算法
	ratelimit1 "go.uber.org/ratelimit"     // 漏桶算法
)

func pingHandler(c *gin.Context) {
	c.JSON(200, gin.H{
		"message": "pong",
	})
}

func pingHandler2(c *gin.Context) {
	c.JSON(200, gin.H{
		"message": "pong2",
	})
}

// rateLimit1 使用漏桶算法來(lái)限制請(qǐng)求速率
func rateLimit1() func(ctx *gin.Context) {
	// 漏桶算法,第一個(gè)參數(shù)為兩滴水滴之間的時(shí)間間隔。
	// 此時(shí)表示兩滴水之間的時(shí)間間隔是 100 納秒
	rl := ratelimit1.New(100)

	return func(ctx *gin.Context) {
		// 嘗試取出水滴
		if waitTime := rl.Take().Sub(time.Now()); waitTime > 0 {
			fmt.Printf("需要等待 %v 秒,下一滴水才會(huì)滴下來(lái)\n", waitTime)
			// 這里我們可以讓程序繼續(xù)等待,也可以直接拒絕掉
			// time.Sleep(waitTime)
			ctx.String(http.StatusOK, "rate limit, try again later")
			ctx.Abort()
			return
		}
		// 證明可以繼續(xù)執(zhí)行
		ctx.Next()
	}
}

// rateLimit2 使用令牌桶算法來(lái)限制請(qǐng)求速率
func rateLimit2() func(ctx *gin.Context) {
	// 令牌桶算法:第一個(gè)參數(shù)為每秒填充令牌的速率為多少
	// 第二個(gè)參數(shù)為令牌桶的容量
	// 這里表示每秒填充 10 個(gè)令牌
	rl := ratelimit2.NewBucket(time.Second, 10)

	return func(ctx *gin.Context) {
		// 嘗試取出令牌
		var num int64 = 1
		// 這里表示需要 num 個(gè)令牌和已經(jīng)取出的令牌數(shù)是否相等
		// 不相等,則表示超過(guò)了限流
                // 比如,假設(shè)每一個(gè)請(qǐng)求過(guò)來(lái)消耗2個(gè)令牌,但是從桶中取出的令牌個(gè)數(shù)為 1 ,那么則認(rèn)為超過(guò)了限流(一般而言是一個(gè)請(qǐng)求消耗一個(gè)令牌,這里僅為舉例)
		if rl.TakeAvailable(num) != num {
			// 此次沒有取到令牌,說(shuō)明超過(guò)了限流
			ctx.String(http.StatusOK, "rate limit, try again later")
			ctx.Abort()
			return
		}
		// 證明可以繼續(xù)執(zhí)行
		ctx.Next()
	}
}

func main() {
	r := gin.Default()

	// 漏桶算法限流
	r.GET("/ping", rateLimit1(), pingHandler)

	// 令牌桶算法限流
	r.GET("/ping2", rateLimit2(), pingHandler2)

	r.Run()
}

代碼解析

漏桶算法的實(shí)現(xiàn)(rateLimit1 函數(shù))

  • 通過(guò) go.uber.org/ratelimit 包中的 ratelimit.New 方法創(chuàng)建了一個(gè)限流器。
  • 當(dāng)請(qǐng)求速率超過(guò)限流器的處理能力時(shí),請(qǐng)求將被拒絕,并返回 "rate limit, try again later"。

令牌桶算法的實(shí)現(xiàn)(rateLimit2 函數(shù))

  • 使用 github.com/juju/ratelimit 包實(shí)現(xiàn)了令牌桶算法。每秒填充一定數(shù)量的令牌到桶中。
  • 如果桶中沒有足夠的令牌,請(qǐng)求將被拒絕。

Gin 路由配置

main 函數(shù)中,通過(guò) rateLimit1rateLimit2 中間件為 /ping/ping2 路由分別設(shè)置了漏桶和令牌桶限流。

總結(jié)

在本文中,我們演示了如何在 Go 中使用漏桶算法和令牌桶算法實(shí)現(xiàn) API 的限流。

這些算法在高并發(fā)的 Web 服務(wù)中非常有用,可以有效防止服務(wù)被大量請(qǐng)求淹沒,確保系統(tǒng)的穩(wěn)定性。希望通過(guò)這篇文章,您能更好地理解并應(yīng)用這些限流技術(shù)到您的項(xiàng)目中。

以上就是Go語(yǔ)言使用漏桶算法和令牌桶算法來(lái)實(shí)現(xiàn)API限流的詳細(xì)內(nèi)容,更多關(guān)于Go API限流的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • go 下載非標(biāo)準(zhǔn)庫(kù)包(部份包被墻了)到本地使用的方法

    go 下載非標(biāo)準(zhǔn)庫(kù)包(部份包被墻了)到本地使用的方法

    今天小編就為大家分享一篇go 下載非標(biāo)準(zhǔn)庫(kù)包(部份包被墻了)到本地使用的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-06-06
  • go?time.After優(yōu)化后性能提升34%內(nèi)存減少67%

    go?time.After優(yōu)化后性能提升34%內(nèi)存減少67%

    這篇文章主要介紹了go語(yǔ)言time.After優(yōu)化后性能提升34%內(nèi)存減少67%實(shí)例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • go-micro開發(fā)RPC服務(wù)以及運(yùn)行原理介紹

    go-micro開發(fā)RPC服務(wù)以及運(yùn)行原理介紹

    這篇文章介紹了go-micro開發(fā)RPC服務(wù)的方法及其運(yùn)行原理,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • Golang Recover處理錯(cuò)誤原理解析

    Golang Recover處理錯(cuò)誤原理解析

    Golang 中的?recover?是一個(gè)鮮為人知但非常有趣和強(qiáng)大的功能,讓我們看看它是如何工作的,以及在 Outreach.io 中如何利用它來(lái)處理 Kubernetes 中的錯(cuò)誤
    2023-12-12
  • 詳解golang中?work與?module?的區(qū)別與聯(lián)系

    詳解golang中?work與?module?的區(qū)別與聯(lián)系

    Go?模塊通常由一個(gè)項(xiàng)目或庫(kù)組成,并包含一組隨后一起發(fā)布的?Go?包,Go?模塊通過(guò)允許用戶將項(xiàng)目代碼放在他們選擇的目錄中并為每個(gè)模塊指定依賴項(xiàng)的版本,解決了原始系統(tǒng)的許多問(wèn)題,本文將給大家介紹一下golang中?work與?module?的區(qū)別與聯(lián)系,需要的朋友可以參考下
    2023-09-09
  • Golang負(fù)載均衡和?;钤O(shè)計(jì)原理示例探究

    Golang負(fù)載均衡和?;钤O(shè)計(jì)原理示例探究

    這篇文章主要為大家介紹了Golang負(fù)載均衡和?;钤O(shè)計(jì)原理示例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • 線上問(wèn)題排查之golang使用json進(jìn)行對(duì)象copy

    線上問(wèn)題排查之golang使用json進(jìn)行對(duì)象copy

    這篇文章主要介紹了線上問(wèn)題排查之golang使用json進(jìn)行對(duì)象copy,文章圍繞golang使用json進(jìn)行對(duì)象copy的內(nèi)存溢出問(wèn)題排查展開詳細(xì)內(nèi)容需要的小伙伴可以參考一下
    2022-06-06
  • 簡(jiǎn)單四步快速集成go環(huán)境變量

    簡(jiǎn)單四步快速集成go環(huán)境變量

    這篇文章主要為大家介紹了快速集成go環(huán)境變量的簡(jiǎn)單四個(gè)步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • golang?JSON序列化和反序列化示例詳解

    golang?JSON序列化和反序列化示例詳解

    通過(guò)使用Go語(yǔ)言的encoding/json包,你可以輕松地處理JSON數(shù)據(jù),無(wú)論是在客戶端應(yīng)用、服務(wù)器端應(yīng)用還是其他類型的Go程序中,這篇文章主要介紹了golang?JSON序列化和反序列化,需要的朋友可以參考下
    2024-04-04
  • GoFrame框架garray并發(fā)安全數(shù)組使用開箱體驗(yàn)

    GoFrame框架garray并發(fā)安全數(shù)組使用開箱體驗(yàn)

    這篇文章主要介紹了GoFrame框架garray并發(fā)安全數(shù)組使用開箱體驗(yàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06

最新評(píng)論

武强县| 庆云县| 页游| 永康市| 泌阳县| 石狮市| 闽侯县| 伊宁县| 盱眙县| 西乌| 遂宁市| 丽水市| 荔波县| 常州市| 恩平市| 甘泉县| 偏关县| 阜城县| 四平市| 象山县| 文成县| 平乡县| 庐江县| 桦南县| 南陵县| 平山县| 贡嘎县| 清镇市| 尤溪县| 城步| 德格县| 韶关市| 宜州市| 建德市| 上高县| 二连浩特市| 乌海市| 仁怀市| 清新县| 鄂托克旗| 当涂县|