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

golang實(shí)現(xiàn)ip訪問(wèn)限制及提交次數(shù)

 更新時(shí)間:2024年10月21日 14:06:38   作者:Ai編碼助手  
在?Web?應(yīng)用中,通常會(huì)需要對(duì)?IP?訪問(wèn)進(jìn)行限制以及控制提交次數(shù),本文將使用中間件或者基于?Redis?這樣的緩存服務(wù)來(lái)實(shí)現(xiàn),感興趣的可以了解下

在 Web 應(yīng)用中,通常會(huì)需要對(duì) IP 訪問(wèn)進(jìn)行限制以及控制提交次數(shù),以防止惡意攻擊(例如暴力破解、DoS攻擊、API濫用等)。為了實(shí)現(xiàn)這一功能,我們可以結(jié)合 Golang 的特性,使用中間件或者基于 Redis 這樣的緩存服務(wù)來(lái)實(shí)現(xiàn) IP 限制和提交次數(shù)的控制。

實(shí)現(xiàn)步驟

  • IP 訪問(wèn)限制:對(duì)每個(gè) IP 的訪問(wèn)頻次進(jìn)行限制,比如每個(gè) IP 每分鐘只能訪問(wèn)某個(gè)接口 10 次。超過(guò)限制后,返回錯(cuò)誤信息(例如 429 Too Many Requests)。
  • 提交次數(shù)限制:通過(guò)限制某個(gè)時(shí)間段內(nèi)某個(gè) IP 的提交次數(shù),防止暴力破解或者濫用接口。
  • Redis(或其他存儲(chǔ)系統(tǒng))作為計(jì)數(shù)器:為了更好地實(shí)現(xiàn)這種限制,可以使用 Redis 等緩存系統(tǒng)來(lái)存儲(chǔ) IP 的訪問(wèn)記錄、提交次數(shù)等,因?yàn)?Redis 的性能和易用性使它成為理想的選擇。

核心概念

  • Rate Limiting(限流):根據(jù) IP 限制某個(gè)時(shí)間段內(nèi)的訪問(wèn)次數(shù)。
  • 請(qǐng)求次數(shù)計(jì)數(shù):對(duì)每個(gè) IP 進(jìn)行計(jì)數(shù),并基于計(jì)數(shù)來(lái)判斷是否超過(guò)限制。
  • 時(shí)間窗口:設(shè)置一定的時(shí)間窗口(例如一分鐘或五分鐘),在這個(gè)時(shí)間段內(nèi)統(tǒng)計(jì) IP 的訪問(wèn)次數(shù)。

使用 Golang 及 Redis 實(shí)現(xiàn) IP 訪問(wèn)限制和提交次數(shù)限制

這里我們使用 Redis 來(lái)存儲(chǔ)和控制訪問(wèn)次數(shù),并結(jié)合 Go 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 IP 訪問(wèn)限制中間件。

依賴(lài)庫(kù)

你可以使用 Redis 官方的 Go 客戶端 go-redis 來(lái)連接 Redis 進(jìn)行操作。先安裝這個(gè)庫(kù):

go get github.com/go-redis/redis/v8

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

下面的代碼演示了如何使用 Redis 來(lái)實(shí)現(xiàn) IP 訪問(wèn)限制和提交次數(shù)限制。

package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"strconv"
	"time"

	"github.com/go-redis/redis/v8"
)

// Redis client
var rdb *redis.Client

// 初始化 Redis 客戶端
func initRedis() {
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379", // Redis 地址
		Password: "",               // Redis 密碼(如果有)
		DB:       0,                // 使用的 Redis 數(shù)據(jù)庫(kù)
	})
}

// 獲取客戶端的 IP 地址
func getIP(r *http.Request) string {
	// 嘗試從 X-Forwarded-For 或 X-Real-IP 獲取真實(shí) IP
	ip := r.Header.Get("X-Forwarded-For")
	if ip == "" {
		ip = r.Header.Get("X-Real-IP")
	}
	if ip == "" {
		ip = r.RemoteAddr
	}
	return ip
}

// 中間件:IP 訪問(wèn)限制
func rateLimitMiddleware(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		ctx := context.Background()
		ip := getIP(r)
		key := "rate_limit:" + ip

		// 獲取 Redis 中的訪問(wèn)次數(shù)
		count, err := rdb.Get(ctx, key).Result()
		if err == redis.Nil {
			// 如果沒(méi)有記錄,設(shè)置計(jì)數(shù)為1,并設(shè)置過(guò)期時(shí)間
			err := rdb.Set(ctx, key, 1, time.Minute).Err() // 1 分鐘限制
			if err != nil {
				http.Error(w, "Redis error", http.StatusInternalServerError)
				return
			}
		} else if err != nil {
			http.Error(w, "Redis error", http.StatusInternalServerError)
			return
		} else {
			// 將訪問(wèn)次數(shù)轉(zhuǎn)換為整數(shù)
			countInt, _ := strconv.Atoi(count)
			if countInt >= 10 { // 假設(shè)限制為每分鐘最多10次
				http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
				return
			}

			// 遞增計(jì)數(shù)
			rdb.Incr(ctx, key)
		}

		next.ServeHTTP(w, r)
	}
}

// 示例處理器:提交處理
func submitHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Request successful")
}

func main() {
	// 初始化 Redis
	initRedis()

	// 創(chuàng)建 HTTP 服務(wù)器并添加中間件
	http.HandleFunc("/submit", rateLimitMiddleware(submitHandler))

	log.Println("Server is running on port 8080...")
	http.ListenAndServe(":8080", nil)
}

代碼解析

Redis 客戶端初始化

  • 使用 redis.NewClient() 初始化 Redis 客戶端。
  • 通過(guò) rdb.Set()rdb.Get() 來(lái)操作 Redis 中的計(jì)數(shù)器。

IP 獲取

通過(guò) getIP() 函數(shù)獲取請(qǐng)求的客戶端 IP 地址。該函數(shù)嘗試從請(qǐng)求頭中的 X-Forwarded-ForX-Real-IP 獲取真實(shí)的 IP。如果沒(méi)有,則使用 RemoteAddr

Rate Limiting 中間件

  • rateLimitMiddleware() 是核心的中間件函數(shù),負(fù)責(zé)限制每個(gè) IP 的訪問(wèn)次數(shù)。它使用 Redis 來(lái)存儲(chǔ)每個(gè) IP 的訪問(wèn)計(jì)數(shù)和限流時(shí)間窗口(這里設(shè)置為 1 分鐘)。
  • 當(dāng) IP 的訪問(wèn)次數(shù)超過(guò)限制時(shí),返回 HTTP 狀態(tài)碼 429 Too Many Requests。

處理請(qǐng)求

  • submitHandler() 是一個(gè)簡(jiǎn)單的示例處理器,處理成功的請(qǐng)求。
  • 訪問(wèn) /submit 時(shí),經(jīng)過(guò)中間件限制后,正常情況下返回 "Request successful"。

改進(jìn)與擴(kuò)展

  • 動(dòng)態(tài)調(diào)整限流策略: 可以根據(jù)不同的用戶類(lèi)型、不同的 API 路徑動(dòng)態(tài)調(diào)整限流策略。例如,VIP 用戶可能會(huì)有更高的訪問(wèn)頻次。
  • IP 黑名單: 通過(guò) Redis 或其他存儲(chǔ)系統(tǒng)維護(hù)一個(gè)黑名單,遇到黑名單中的 IP 可以直接拒絕請(qǐng)求。
  • 按時(shí)間窗口的限流算法: 你可以采用滑動(dòng)窗口、漏桶算法、令牌桶算法等更復(fù)雜的限流算法來(lái)實(shí)現(xiàn)更靈活的控制。
  • 使用 Redis Expire 特性: 在 Redis 中使用 SetEX(帶過(guò)期時(shí)間的鍵設(shè)置)或 TTL 來(lái)確保計(jì)數(shù)器可以自動(dòng)重置,避免手動(dòng)管理。
  • 日志記錄與報(bào)警: 可以結(jié)合日志系統(tǒng),在某個(gè) IP 頻繁觸發(fā)限制時(shí)記錄日志或發(fā)送報(bào)警信息。

通過(guò) Golang 和 Redis 的結(jié)合,可以輕松實(shí)現(xiàn) IP 訪問(wèn)限制和提交次數(shù)控制。Redis 的高性能特性使其非常適合用作限流計(jì)數(shù)器的存儲(chǔ)。在實(shí)際應(yīng)用中,可以根據(jù)需要擴(kuò)展該方案,例如使用不同的限流算法、結(jié)合 IP 黑名單等。

到此這篇關(guān)于golang實(shí)現(xiàn)ip訪問(wèn)限制及提交次數(shù)的文章就介紹到這了,更多相關(guān)go ip訪問(wèn)限制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • go語(yǔ)言VScode?see?'go?help?modules'?(exit?status?1)問(wèn)題的解決過(guò)程

    go語(yǔ)言VScode?see?'go?help?modules'?(exit?statu

    最近上手學(xué)習(xí)go語(yǔ)言,準(zhǔn)備在VSCode上寫(xiě)程序的時(shí)候卻發(fā)現(xiàn)出了一點(diǎn)問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于go語(yǔ)言VScode?see?'go?help?modules'(exit?status?1)問(wèn)題的解決過(guò)程,需要的朋友可以參考下
    2022-07-07
  • 詳解Golang中的通道機(jī)制與應(yīng)用

    詳解Golang中的通道機(jī)制與應(yīng)用

    這篇文章主要來(lái)和大家一起深入探討了Go語(yǔ)言中通道(Channel)的各個(gè)方面,文章詳細(xì)解析了通道的類(lèi)型、操作方法以及垃圾回收機(jī)制,有需要的可以了解下
    2023-10-10
  • Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)中math模塊詳細(xì)功能介紹與示例代碼

    Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)中math模塊詳細(xì)功能介紹與示例代碼

    Go語(yǔ)言的標(biāo)準(zhǔn)庫(kù)math提供了一系列基礎(chǔ)數(shù)學(xué)函數(shù)和常量,用于進(jìn)行科學(xué)計(jì)算、幾何計(jì)算和其他數(shù)學(xué)相關(guān)的操作,這篇文章主要介紹了Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)中math模塊詳細(xì)功能介紹與示例代碼,需要的朋友可以參考下
    2025-03-03
  • Go語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單留言板的方法

    Go語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單留言板的方法

    這篇文章主要介紹了Go語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單留言板的方法,涉及數(shù)據(jù)庫(kù)、模板頁(yè)面元素等留言板相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • Golang連接PostgreSQL基本操作的實(shí)現(xiàn)

    Golang連接PostgreSQL基本操作的實(shí)現(xiàn)

    PostgreSQL是常見(jiàn)的免費(fèi)的大型關(guān)系型數(shù)據(jù)庫(kù),本文主要介紹了Golang連接PostgreSQL基本操作的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • Go語(yǔ)言中切片使用的注意事項(xiàng)小結(jié)

    Go語(yǔ)言中切片使用的注意事項(xiàng)小結(jié)

    切片是引用類(lèi)型,相信對(duì)大家來(lái)說(shuō)都不陌生,下面這篇文章主要給大家總結(jié)介紹了關(guān)于Go語(yǔ)言中切片使用的一些注意事項(xiàng),文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • go開(kāi)發(fā)中引用靜態(tài)庫(kù).a文件的方法

    go開(kāi)發(fā)中引用靜態(tài)庫(kù).a文件的方法

    這篇文章主要介紹了go開(kāi)發(fā)中引用靜態(tài)庫(kù).a文件的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Go如何優(yōu)雅的使用字節(jié)池示例詳解

    Go如何優(yōu)雅的使用字節(jié)池示例詳解

    在編程開(kāi)發(fā)中,我們經(jīng)常會(huì)需要頻繁創(chuàng)建和銷(xiāo)毀同類(lèi)對(duì)象的情形,這樣的操作很可能會(huì)對(duì)性能造成影響,這時(shí)常用的優(yōu)化手段就是使用對(duì)象池(object pool),這篇文章主要給大家介紹了關(guān)于Go如何優(yōu)雅的使用字節(jié)池的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • Golang中 import cycle not allowed 問(wèn)題的解決方法

    Golang中 import cycle not allowed 問(wèn)題

    這篇文章主要介紹了Golang中 import cycle not allowed 問(wèn)題的解決方法,問(wèn)題從描述到解決都非常詳細(xì),需要的小伙伴可以參考一下
    2022-03-03
  • Go-Web框架中AOP方案的實(shí)現(xiàn)方式

    Go-Web框架中AOP方案的實(shí)現(xiàn)方式

    本文主要介紹了Go-Web框架中AOP方案的實(shí)現(xiàn)方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06

最新評(píng)論

吴堡县| 东辽县| 江城| 隆昌县| 温泉县| 云龙县| 凤庆县| 万盛区| 定远县| 射阳县| 汤原县| 吴堡县| 肥城市| 手机| 大足县| 滕州市| 泰宁县| 桐乡市| 永昌县| 凤凰县| 蛟河市| 深泽县| 丹棱县| 烟台市| 龙岩市| 富源县| 乌拉特中旗| 壶关县| 健康| 宜兰县| 宜春市| 西乌珠穆沁旗| 辛集市| 曲靖市| 大洼县| 旺苍县| 潢川县| 贡山| 古丈县| 深州市| 犍为县|