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

go rate 原生標(biāo)準(zhǔn)限速庫(kù)的使用

 更新時(shí)間:2025年05月25日 11:04:08   作者:NPE~  
本文主要介紹了Go標(biāo)準(zhǔn)庫(kù)golang.org/x/time/rate實(shí)現(xiàn)限流,采用令牌桶算法控制請(qǐng)求速率,提供Allow/Reserve/Wait方法,具有一定的參考價(jià)值,感興趣的可以了解一下

在我們實(shí)際生產(chǎn)開發(fā)過程中,不免存在一些高并發(fā)的場(chǎng)景,此時(shí)我們就需要對(duì)請(qǐng)求進(jìn)行限流,避免過高的QPS,影響我們服務(wù)器,導(dǎo)致服務(wù)出現(xiàn)波動(dòng)或不可用。

  • 對(duì)于go開發(fā)人員而言,golang標(biāo)準(zhǔn)庫(kù)就已經(jīng)為我們提供了現(xiàn)成的類庫(kù)golang.org/x/time/rate,我們只需直接調(diào)用即可。下面將為大家介紹該類庫(kù)的詳細(xì)用法。

文中代碼地址,歡迎大家??:https://github.com/ziyifast/ziyifast-code_instruction/tree/main/go-demo/go-rate

介紹

限流(Rate Limiting)是控制對(duì)某些資源訪問頻率的一種技術(shù)手段。在高并發(fā)的服務(wù)中,限流機(jī)制可以有效防止資源過載、服務(wù)崩潰,保障系統(tǒng)的穩(wěn)定性和可用性。Golang 官方標(biāo)準(zhǔn)庫(kù) golang.org/x/time/rate 提供了一個(gè)高效且易用的限流器(Rate Limiter),可以幫助開發(fā)者方便地實(shí)現(xiàn)限流功能。

原理:golang官方的類庫(kù)采用了令牌桶算法進(jìn)行限流。

  • 令牌桶算法(Token Bucket Algorithm):是一種常用的限流算法,它通過在固定時(shí)間間隔內(nèi)向“桶”中添加“令牌”,請(qǐng)求在處理前需要從桶中獲取令牌。如果桶中有足夠的令牌,請(qǐng)求被處理;否則,請(qǐng)求被拒絕或等待。
  • 速率(Rate):速率定義了令牌添加的速度,即每秒向桶中添加多少令牌。
  • 容量(Burst):容量定義了桶的大小,即桶中最多可以存儲(chǔ)多少令牌。它決定了在一段時(shí)間內(nèi)允許的最大突發(fā)請(qǐng)求數(shù)。

安裝

go get golang.org/x/time/rate

API介紹

rate.NewLimiter:創(chuàng)建限流器

創(chuàng)建限流器后,可以通過 Allow、Reserve、Wait 等方法請(qǐng)求許可

package main

import (
    "fmt"
    "golang.org/x/time/rate"
    "time"
)

func main() {
    // 每秒生成3個(gè)令牌,桶的容量為10個(gè)令牌
    // 相當(dāng)于每秒最多能處理三個(gè)請(qǐng)求,順時(shí)并發(fā)最多能處理10個(gè)請(qǐng)求
    limiter := rate.NewLimiter(3, 10)

    fmt.Println("Limiter created with rate 3 tokens per second and burst size of 10")
}

limiter.Allow():請(qǐng)求是否被允許/限流

Allow 方法立即返回一個(gè)布爾值,指示請(qǐng)求是否被允許

if limiter.Allow() {
    fmt.Println("Request allowed")
} else {
    fmt.Println("Request denied")
}

limiter.Reserve():返回值包含了許可時(shí)間和是否可用的信息

Reserve 方法返回一個(gè) Reservation 對(duì)象,包含了許可時(shí)間和是否可用的信息

reservation := limiter.Reserve()
if reservation.OK() {
    fmt.Println("Request reserved, delay:", reservation.Delay())
} else {
    fmt.Println("Request cannot be reserved")
}

limiter.Wait(ctx):阻塞當(dāng)前協(xié)程,直到允許請(qǐng)求或上下文取消

Wait 方法阻塞當(dāng)前協(xié)程,直到允許請(qǐng)求或上下文取消

ctx := context.Background()
if err := limiter.Wait(ctx); err == nil {
    fmt.Println("Request allowed after wait")
} else {
    fmt.Println("Request denied:", err)
}

實(shí)戰(zhàn)使用

并發(fā)處理任務(wù)

一段時(shí)間內(nèi),限制服務(wù)器處理任務(wù)數(shù)

// Demo_CurrentHandleWorks 模擬并發(fā)處理任務(wù)
func Demo_CurrentHandleWorks() {
	var wg sync.WaitGroup
	numWorkers := 5 // 模擬5個(gè)并發(fā)請(qǐng)求
	// 構(gòu)造限流器:每10s向桶中新增一個(gè)令牌,桶里最多能存放2個(gè)令牌 => 每10s能處理一個(gè)任務(wù),一定時(shí)間內(nèi)最多能處理2個(gè)任務(wù)(令牌有剩余)
	var l = rate.NewLimiter(rate.Every(time.Second*10), 2)
	for i := 1; i <= numWorkers; i++ {
		wg.Add(1)
		go worker(i, &wg, l)
	}

	wg.Wait()
}

func worker(id int, wg *sync.WaitGroup, limiter *rate.Limiter) {
	defer wg.Done()
	if limiter.Allow() {
		fmt.Printf("Worker %d processed at %s\n", id, time.Now().Format("15:04:05.000"))
	} else {
		fmt.Printf("Worker %d rejected at %s\n", id, time.Now().Format("15:04:05.000"))
	}
}

HTTP服務(wù)請(qǐng)求限流

當(dāng)我們通過jmeter/腳本/連續(xù)刷新頁(yè)面并發(fā)請(qǐng)求測(cè)試時(shí),發(fā)現(xiàn)在1s內(nèi),服務(wù)器最多只能處理2個(gè)請(qǐng)求,其余請(qǐng)求都不會(huì)被處理,會(huì)返回Too Many Requests。

// Demo_CurrentHandleWithHTTP 模擬HTTP請(qǐng)求限流
func Demo_CurrentHandleWithHTTP() {
	// 每秒最多處理 1 個(gè)請(qǐng)求,允許突發(fā) 2 個(gè)請(qǐng)求
	limiter := rate.NewLimiter(1, 2)
	http.HandleFunc("/", func(w http.ResponseWriter, request *http.Request) {
		if limiter.Allow() {
			fmt.Fprintln(w, "Request allowed")
		} else {
			http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
		}
	})
	fmt.Println("Server started at :8080")
	_ = http.ListenAndServe(":8080", nil)
}

正常請(qǐng)求:

在這里插入圖片描述

頻繁請(qǐng)求(超過頻次):

在這里插入圖片描述

模擬等待耗時(shí)任務(wù)處理

可用于限制資源(文件)的訪問,避免資源(文件)被頻繁訪問造成性能問題。

func Demo_HandleWorkWithWait() {
	// 創(chuàng)建一個(gè)限速器,每3秒允許1個(gè)事件
	limiter := rate.NewLimiter(rate.Every(3*time.Second), 1)

	// 模擬10次對(duì)資源的訪問
	for i := 0; i < 10; i++ {
		// 使用limiter.Wait(ctx)等待,直到可以訪問資源(訪問文件/執(zhí)行數(shù)據(jù)庫(kù)查詢等)
		if err := limiter.Wait(context.Background()); err != nil {
			log.Fatalf("Failed to wait for rate limiter: %v", err)
		}
		// 訪問資源
		fmt.Printf("Accessing resource at %v\n", time.Now())
	}
}

全部代碼

Github:https://github.com/ziyifast/ziyifast-code_instruction/tree/main/go-demo/go-rat

參考文章:
https://cloud.tencent.com/developer/article/2429254
https://www.cnblogs.com/gnivor/p/10623028.html

到此這篇關(guān)于go rate 原生標(biāo)準(zhǔn)限速庫(kù)的使用的文章就介紹到這了,更多相關(guān)go rate 原生標(biāo)準(zhǔn)限速庫(kù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語(yǔ)言下載網(wǎng)絡(luò)圖片或文件的方法示例

    Go語(yǔ)言下載網(wǎng)絡(luò)圖片或文件的方法示例

    這篇文章主要介紹了Go語(yǔ)言下載網(wǎng)絡(luò)圖片或文件的方法示例,文中通過示例代碼介紹的非常詳細(xì),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2018-12-12
  • 圖文詳解Go程序如何編譯并運(yùn)行起來(lái)的

    圖文詳解Go程序如何編譯并運(yùn)行起來(lái)的

    Go語(yǔ)言這兩年在語(yǔ)言排行榜上的上升勢(shì)頭非常猛,Go語(yǔ)言雖然是靜態(tài)編譯型語(yǔ)言,但是它卻擁有腳本化的語(yǔ)法,下面這篇文章主要給大家介紹了關(guān)于Go程序如何編譯并運(yùn)行起來(lái)的相關(guān)資料,需要的朋友可以參考下
    2024-05-05
  • Golang信號(hào)量設(shè)計(jì)實(shí)現(xiàn)示例詳解

    Golang信號(hào)量設(shè)計(jì)實(shí)現(xiàn)示例詳解

    這篇文章主要為大家介紹了Golang信號(hào)量設(shè)計(jì)實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • go語(yǔ)言匿名函數(shù)的使用

    go語(yǔ)言匿名函數(shù)的使用

    今天小編就為大家分享一篇關(guān)于go語(yǔ)言匿名函數(shù)的使用,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-04-04
  • GO制作微信機(jī)器人的流程分析

    GO制作微信機(jī)器人的流程分析

    這篇文章主要介紹了利用go制作微信機(jī)器人,本文主要包括項(xiàng)目基礎(chǔ)配置及詳細(xì)代碼講解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • Go?使用xorm操作mysql詳情

    Go?使用xorm操作mysql詳情

    這篇文章主要介紹了Go?使用xorm操作mysql詳情,golang?orm?庫(kù)?xorm?的使用和項(xiàng)目結(jié)構(gòu)。更多詳細(xì)neural,需要的小伙伴可以參考下面文章內(nèi)容
    2022-01-01
  • Golang中基于HTTP協(xié)議的網(wǎng)絡(luò)服務(wù)

    Golang中基于HTTP協(xié)議的網(wǎng)絡(luò)服務(wù)

    HTTP協(xié)議是基于TCP/IP協(xié)議棧的,并且它也是一個(gè)面向普通文本的協(xié)議。這篇文章主要詳細(xì)介紹了Golang中基于HTTP協(xié)議的網(wǎng)絡(luò)服務(wù),感興趣的小伙伴可以借鑒一下
    2023-04-04
  • 深入了解Golang中的Slice底層實(shí)現(xiàn)

    深入了解Golang中的Slice底層實(shí)現(xiàn)

    本文主要為大家詳細(xì)介紹了Golang中slice的底層實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2023-02-02
  • go語(yǔ)言的變量定義示例詳解

    go語(yǔ)言的變量定義示例詳解

    這篇文章主要為大家介紹了go語(yǔ)言的變量定義示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Golang中匿名組合實(shí)現(xiàn)偽繼承的方法

    Golang中匿名組合實(shí)現(xiàn)偽繼承的方法

    這篇文章主要介紹了Golang中匿名組合實(shí)現(xiàn)偽繼承的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2018-08-08

最新評(píng)論