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

go基于Gin框架的HTTP接口限速實(shí)踐

 更新時(shí)間:2023年09月04日 08:53:24   作者:海風(fēng)極客  
HTTP接口在各個(gè)業(yè)務(wù)模塊之間扮演著重要的角色,本文主要介紹了go基于Gin框架的HTTP接口限速實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下

在當(dāng)今的微服務(wù)架構(gòu)和RESTful API主導(dǎo)的時(shí)代,HTTP接口在各個(gè)業(yè)務(wù)模塊之間扮演著重要的角色。隨著業(yè)務(wù)規(guī)模的不斷擴(kuò)大,接口的訪問(wèn)頻率和負(fù)載也隨之增加。為了確保系統(tǒng)的穩(wěn)定性和性能,接口限速成了一個(gè)重要的話題。

1 接口限速的使用場(chǎng)景

接口限速的使用場(chǎng)景主要涉及以下幾種情況:

  • 防止API濫用:在某些情況下,如果沒有有效的限速機(jī)制,惡意用戶可能會(huì)無(wú)限制地調(diào)用API,導(dǎo)致系統(tǒng)過(guò)載。通過(guò)接口限速,我們可以限制每個(gè)用戶對(duì)特定接口的訪問(wèn)頻率,從而防止API濫用。
  • 保護(hù)服務(wù)穩(wěn)定性:在某些情況下,某些高頻調(diào)用可能會(huì)給后端服務(wù)帶來(lái)巨大的壓力,影響服務(wù)的穩(wěn)定性和性能。通過(guò)接口限速,我們可以限制對(duì)這些接口的訪問(wèn)頻率,從而保護(hù)服務(wù)的穩(wěn)定性。
  • 資源合理分配:在一些情況下,我們需要對(duì)系統(tǒng)資源進(jìn)行合理的分配,確保每個(gè)用戶都能得到公平的資源使用。通過(guò)接口限速,我們可以根據(jù)用戶的請(qǐng)求頻率進(jìn)行資源分配,從而保證公平性。

2 限速不同與限流

接口限速和限流是兩個(gè)不同的概念,雖然它們都是用來(lái)控制流量和保護(hù)系統(tǒng)的手段,但它們的目的和實(shí)現(xiàn)方式有所不同。

接口限速主要是限制接口的訪問(wèn)速度,避免過(guò)快的請(qǐng)求頻率對(duì)系統(tǒng)造成壓力。它關(guān)注的是單個(gè)接口的訪問(wèn)速率,比如每秒可以訪問(wèn)多少次,而限流則是關(guān)注系統(tǒng)的整體流量,限制單位時(shí)間內(nèi)系統(tǒng)的總訪問(wèn)量。

限速通常是通過(guò)在接口上設(shè)置速率限制來(lái)實(shí)現(xiàn)的,例如使用令牌桶算法或漏桶算法等。它的主要目的是防止單個(gè)接口的過(guò)快訪問(wèn),以保護(hù)系統(tǒng)的穩(wěn)定性和性能。

而限流則是通過(guò)一系列機(jī)制來(lái)限制單位時(shí)間內(nèi)系統(tǒng)的總訪問(wèn)量,以防止系統(tǒng)過(guò)載。常見的限流算法包括令牌桶算法、漏桶算法和熱點(diǎn)參數(shù)等。它的主要目的是保護(hù)整個(gè)系統(tǒng),避免因?yàn)樵L問(wèn)量過(guò)大而出現(xiàn)崩潰或性能下降的情況。

在實(shí)現(xiàn)方面,限速通常是在應(yīng)用程序或API網(wǎng)關(guān)層面實(shí)現(xiàn)的,而限流則可能需要涉及到整個(gè)系統(tǒng)的架構(gòu)和設(shè)計(jì)。

雖然接口限速和限流的目的和實(shí)現(xiàn)方式有所不同,但它們都是為了控制流量和保護(hù)系統(tǒng)的穩(wěn)定性和性能。在實(shí)際應(yīng)用中,我們可以根據(jù)實(shí)際情況選擇合適的限速和限流策略,以實(shí)現(xiàn)最佳的流量控制效果。

3 Gin框架接口限速實(shí)踐

基于limiter插件的GitHub地址:github.com/ulule/limiter

3.1 基本使用

package main
import (
   "fmt"
   "log"
   "net/http"
   "github.com/gin-gonic/gin"
   "github.com/redis/go-redis/v9"
   "github.com/ulule/limiter/v3"
   mgin "github.com/ulule/limiter/v3/drivers/middleware/gin"
   sredis "github.com/ulule/limiter/v3/drivers/store/redis"
)
func main() {
   // Define a limit rate to 4 requests per hour.
   rate, err := limiter.NewRateFromFormatted("4-M")
   if err != nil {
      log.Fatal(err)
      return
   }
   // Create a redis client.
   option, err := redis.ParseURL("redis://localhost:6379/0")
   if err != nil {
      log.Fatal(err)
      return
   }
   client := redis.NewClient(option)
   // Create a store with the redis client.
   store, err := sredis.NewStoreWithOptions(client, limiter.StoreOptions{
      Prefix:   "limiter_gin_example",
      MaxRetry: 3,
   })
   if err != nil {
      log.Fatal(err)
      return
   }
   // Create a new middleware with the limiter instance.
   middleware := mgin.NewMiddleware(limiter.New(store, rate))
   // Launch a simple server.
   router := gin.Default()
   router.ForwardedByClientIP = true
   router.Use(middleware)
   router.GET("/", index)
   log.Fatal(router.Run(":8081"))
}
func index(c *gin.Context) {
   c.JSON(http.StatusOK, "This is my gin api...")
}

3.2 引入自定義攔截處理器

package main
import (
   "fmt"
   "log"
   "net/http"
   "github.com/gin-gonic/gin"
   "github.com/redis/go-redis/v9"
   "github.com/ulule/limiter/v3"
   mgin "github.com/ulule/limiter/v3/drivers/middleware/gin"
   sredis "github.com/ulule/limiter/v3/drivers/store/redis"
)
func main() {
   rate, err := limiter.NewRateFromFormatted("4-M")
   if err != nil {
      log.Fatal(err)
      return
   }
   option, err := redis.ParseURL("redis://localhost:6379/0")
   if err != nil {
      log.Fatal(err)
      return
   }
   client := redis.NewClient(option)
   store, err := sredis.NewStoreWithOptions(client, limiter.StoreOptions{
      Prefix:   "limiter_gin_example",
      MaxRetry: 3,
   })
   if err != nil {
      log.Fatal(err)
      return
   }
   //自定義攔截處理器
   opt := mgin.WithLimitReachedHandler(ExceededHandler)
   middleware := mgin.NewMiddleware(limiter.New(store, rate), opt)
   router := gin.Default()
   router.ForwardedByClientIP = true
   router.Use(middleware)
   router.GET("/", index)
   log.Fatal(router.Run(":8081"))
}
func ExceededHandler(c *gin.Context) {
   c.JSON(200, "This is mu custom ExceededHandler...")
}
func index(c *gin.Context) {
   c.JSON(http.StatusOK, "This is my gin api...")
}

返回結(jié)果:

3.3 不同接口區(qū)分速率

我們假設(shè)系統(tǒng)有兩個(gè)接口:

  • /fast : 每分鐘允許10次訪問(wèn)
  • /slow : 每分鐘允許1次訪問(wèn)

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

package main
import (
   "fmt"
   "log"
   "net/http"
   "github.com/gin-gonic/gin"
   "github.com/redis/go-redis/v9"
   "github.com/ulule/limiter/v3"
   mgin "github.com/ulule/limiter/v3/drivers/middleware/gin"
   sredis "github.com/ulule/limiter/v3/drivers/store/redis"
)
var (
   fastTime = 0
   slowTime = 0
)
func FastApi(c *gin.Context) {
   fastTime += 1
   c.JSON(200, fmt.Sprintf("This is fast api... %d", fastTime))
}
func SlowApi(c *gin.Context) {
   slowTime += 1
   c.JSON(200, fmt.Sprintf("This is slow api... %d", slowTime))
}
func main() {
   fastRate, err := limiter.NewRateFromFormatted("10-M")
   if err != nil {
      log.Fatal(err)
      return
   }
   slowRate, err := limiter.NewRateFromFormatted("1-M")
   if err != nil {
      log.Fatal(err)
      return
   }
   option, err := redis.ParseURL("redis://localhost:6379/0")
   if err != nil {
      log.Fatal(err)
      return
   }
   client := redis.NewClient(option)
   storeFast, err := sredis.NewStoreWithOptions(client, limiter.StoreOptions{Prefix: "limiter_gin_example_fast", MaxRetry: 3})
   if err != nil {
      log.Fatal(err)
      return
   }
   storeSlow, err := sredis.NewStoreWithOptions(client, limiter.StoreOptions{Prefix: "limiter_gin_example_slow", MaxRetry: 3})
   if err != nil {
      log.Fatal(err)
      return
   }
   //自定義攔截處理器
   opt := mgin.WithLimitReachedHandler(ExceededHandler)
   middlewareFast := mgin.NewMiddleware(limiter.New(storeFast, fastRate), opt)
   middlewareSlow := mgin.NewMiddleware(limiter.New(storeSlow, slowRate), opt)
   router := gin.Default()
   router.ForwardedByClientIP = true
   router.Use(func(c *gin.Context) {
      if c.Request.RequestURI == "/fast" {
         middlewareFast(c)
         return
      }
      if c.Request.RequestURI == "/slow" {
         middlewareSlow(c)
         return
      }
   })
   router.GET("/fast", FastApi)
   router.GET("/slow", SlowApi)
   log.Fatal(router.Run(":8081"))
}
func ExceededHandler(c *gin.Context) {
   c.JSON(200, "This is mu custom ExceededHandler...")
}

4 小總結(jié)

接口限速是保護(hù)系統(tǒng)穩(wěn)定性和API的重要手段。在實(shí)際應(yīng)用中,我們需要根據(jù)實(shí)際情況選擇合適的限速方法,實(shí)現(xiàn)對(duì)接口的全面限速。通過(guò)接口限速,我們可以提高系統(tǒng)的穩(wěn)定性、保護(hù)API、提高用戶體驗(yàn)等。

到此這篇關(guān)于go基于Gin框架的HTTP接口限速實(shí)踐的文章就介紹到這了,更多相關(guān)Gin HTTP接口限速內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語(yǔ)言實(shí)現(xiàn)彩色輸出示例詳解

    Go語(yǔ)言實(shí)現(xiàn)彩色輸出示例詳解

    這篇文章主要為大家介紹了Go語(yǔ)言實(shí)現(xiàn)彩色輸出示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • golang如何判斷文件是否存在

    golang如何判斷文件是否存在

    判斷一個(gè)文件是否存在是一個(gè)相當(dāng)常見的需求,在golang中也有多種方案實(shí)現(xiàn)這一功能,下面就跟隨小編一起學(xué)習(xí)一下具體的實(shí)現(xiàn)方法吧
    2024-11-11
  • golang?db事務(wù)的統(tǒng)一封裝的實(shí)現(xiàn)

    golang?db事務(wù)的統(tǒng)一封裝的實(shí)現(xiàn)

    這篇文章主要介紹了golang db事務(wù)的統(tǒng)一封裝的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • 深入了解Golang官方container/heap用法

    深入了解Golang官方container/heap用法

    在?Golang?的標(biāo)準(zhǔn)庫(kù)?container?中,包含了幾種常見的數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn),其實(shí)是非常好的學(xué)習(xí)材料。今天我們就來(lái)看看?container/heap?的源碼,了解一下官方的同學(xué)是怎么設(shè)計(jì),我們作為開發(fā)者又該如何使用
    2022-10-10
  • Go代碼格式化gofmt的使用方法實(shí)例

    Go代碼格式化gofmt的使用方法實(shí)例

    Golang制定了統(tǒng)一的官方代碼風(fēng)格,并推出gofmt工具(go fmt)來(lái)幫助開發(fā)人員格式化代碼到統(tǒng)一的風(fēng)格,下面這篇文章主要給大家介紹了關(guān)于Go代碼格式化gofmt的使用方法,需要的朋友可以參考下
    2023-04-04
  • Go中l(wèi)og包異或組合配置妙用詳解

    Go中l(wèi)og包異或組合配置妙用詳解

    在 Go 語(yǔ)言的 log 包中,使用“位運(yùn)算相或” (|) 來(lái)配置日志的 flag,可以讓我們靈活地組合多種日志信息輸出選項(xiàng),下面我們就來(lái)看看這種方法的好處和原理吧
    2024-11-11
  • Golang?基于flag庫(kù)實(shí)現(xiàn)一個(gè)簡(jiǎn)單命令行工具

    Golang?基于flag庫(kù)實(shí)現(xiàn)一個(gè)簡(jiǎn)單命令行工具

    這篇文章主要介紹了Golang基于flag庫(kù)實(shí)現(xiàn)一個(gè)簡(jiǎn)單命令行工具,Golang標(biāo)準(zhǔn)庫(kù)中的flag庫(kù)提供了解析命令行選項(xiàng)的能力,我們可以基于此來(lái)開發(fā)命令行工具,下文詳細(xì)介紹。需要的小伙伴可以參考一下
    2022-08-08
  • 一文精通管理多版本Go安裝教程

    一文精通管理多版本Go安裝教程

    這篇文章主要為大家介紹了一文精通管理多版本Go安裝教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • golang實(shí)現(xiàn)微信小程序商城后臺(tái)系統(tǒng)(moshopserver)

    golang實(shí)現(xiàn)微信小程序商城后臺(tái)系統(tǒng)(moshopserver)

    這篇文章主要介紹了golang實(shí)現(xiàn)微信小程序商城后臺(tái)系統(tǒng)(moshopserver),本文通過(guò)截圖實(shí)例代碼的形式給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Golang的循環(huán)語(yǔ)句和循環(huán)控制語(yǔ)句詳解

    Golang的循環(huán)語(yǔ)句和循環(huán)控制語(yǔ)句詳解

    循環(huán)語(yǔ)句為了簡(jiǎn)化程序中有規(guī)律的重復(fù)性操作,需要用到循環(huán)語(yǔ)句,和其他大多數(shù)編程語(yǔ)言一樣,GO的循環(huán)語(yǔ)句有for循環(huán),不同的是沒有while循環(huán),而循環(huán)控制語(yǔ)句可以改變循環(huán)語(yǔ)句的執(zhí)行過(guò)程,下面給大家介紹下go循環(huán)語(yǔ)句和循環(huán)控制語(yǔ)句的相關(guān)知識(shí),一起看看吧
    2021-11-11

最新評(píng)論