欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語言使用漏桶算法和令牌桶算法來實現(xiàn)API限流

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

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

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

限流的意義

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

兩種常見的限流算法

1.漏桶算法(Leaky Bucket)

漏桶算法將請求視為水滴,水滴先進入桶中,然后以固定的速率從桶中流出。如果請求的速率超過了桶的流出速率,多余的請求將會被丟棄。

這個算法的優(yōu)點很明顯,就是讓請求非常穩(wěn)定,但是缺點也很明顯,因為請求非常穩(wěn)定,就不適于一些秒殺等一些可能在某一段時間會有洪峰流量的場景。不太好適情況控制流量的進入。

2.令牌桶算法(Token Bucket)

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

代碼實現(xiàn)

在這個示例中,我們將展示如何在 Gin 框架中應(yīng)用這兩種算法來實現(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 使用漏桶算法來限制請求速率
func rateLimit1() func(ctx *gin.Context) {
	// 漏桶算法,第一個參數(shù)為兩滴水滴之間的時間間隔。
	// 此時表示兩滴水之間的時間間隔是 100 納秒
	rl := ratelimit1.New(100)

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

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

	return func(ctx *gin.Context) {
		// 嘗試取出令牌
		var num int64 = 1
		// 這里表示需要 num 個令牌和已經(jīng)取出的令牌數(shù)是否相等
		// 不相等,則表示超過了限流
                // 比如,假設(shè)每一個請求過來消耗2個令牌,但是從桶中取出的令牌個數(shù)為 1 ,那么則認為超過了限流(一般而言是一個請求消耗一個令牌,這里僅為舉例)
		if rl.TakeAvailable(num) != num {
			// 此次沒有取到令牌,說明超過了限流
			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()
}

代碼解析

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

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

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

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

Gin 路由配置

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

總結(jié)

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

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

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

相關(guān)文章

  • golang內(nèi)存對齊詳解

    golang內(nèi)存對齊詳解

    在golang中,每一種數(shù)據(jù)類型都有其對應(yīng)的數(shù)據(jù)類型大小,也就是占用了多少內(nèi)存空間,我們可以通過unsafe.Sizeof函數(shù),來確定一個變量占用的內(nèi)存字節(jié)數(shù),本文將詳細給大家介紹golang內(nèi)存對齊,需要的朋友可以參考下
    2023-10-10
  • Golang回調(diào)函數(shù)與閉包和接口函數(shù)的定義及使用介紹

    Golang回調(diào)函數(shù)與閉包和接口函數(shù)的定義及使用介紹

    這篇文章主要介紹了Golang回調(diào)函數(shù)與閉包和接口函數(shù)的定義及使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2023-05-05
  • golang中的net/http庫基本使用詳解

    golang中的net/http庫基本使用詳解

    今天給大家分享golang中的net/http庫基本使用方法,文章開頭給大家詳細介紹了標準庫net/http如何處理一個請求,結(jié)合實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • Golang使用Gin框架實現(xiàn)HTTP響應(yīng)格式統(tǒng)一處理

    Golang使用Gin框架實現(xiàn)HTTP響應(yīng)格式統(tǒng)一處理

    在gin框架中,我們可以定義一個中間件來處理統(tǒng)一的HTTP響應(yīng)格式,本文主要為大家介紹了具體是怎么定義實現(xiàn)這樣的中間件的,感興趣的小伙伴可以了解一下
    2023-07-07
  • Go string轉(zhuǎn)int,int64,int32及注意事項說明

    Go string轉(zhuǎn)int,int64,int32及注意事項說明

    這篇文章主要介紹了Go string轉(zhuǎn)int,int64,int32及注意事項說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • golang?http請求未釋放造成的錯誤問題

    golang?http請求未釋放造成的錯誤問題

    這篇文章主要介紹了golang?http請求未釋放造成的錯誤問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Go?gRPC進階教程gRPC轉(zhuǎn)換HTTP

    Go?gRPC進階教程gRPC轉(zhuǎn)換HTTP

    這篇文章主要為大家介紹了Go?gRPC進階教程gRPC轉(zhuǎn)換HTTP教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Golang 正則匹配效率詳解

    Golang 正則匹配效率詳解

    這篇文章主要介紹了Golang 正則匹配效率詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Golang?Template實現(xiàn)自定義函數(shù)的操作指南

    Golang?Template實現(xiàn)自定義函數(shù)的操作指南

    這篇文章主要為大家詳細介紹了Golang如何利用Template實現(xiàn)自定義函數(shù)的操作,文中的示例代碼簡潔易懂,感興趣的小伙伴可以跟隨小編一起學習一下
    2025-02-02
  • Go并發(fā)調(diào)用的超時處理的方法

    Go并發(fā)調(diào)用的超時處理的方法

    這篇文章主要介紹了Go并發(fā)調(diào)用的超時處理的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01

最新評論