Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk menggunakan fungsi pelayan HTTP dalam bahasa Go untuk melaksanakan fungsi pengehad semasa penghalaan dinamik?

Bagaimana untuk menggunakan fungsi pelayan HTTP dalam bahasa Go untuk melaksanakan fungsi pengehad semasa penghalaan dinamik?

王林
王林asal
2023-08-02 22:31:511289semak imbas

Cara menggunakan fungsi pelayan HTTP dalam bahasa Go untuk melaksanakan fungsi mengehadkan aliran penghalaan dinamik

Pengenalan:
Dalam proses pembangunan sebenar, kita sering perlu mengawal aliran antara muka API aplikasi web untuk memastikan sistem tidak dibanjiri oleh permintaan jahat. Bahasa Go menyediakan set lengkap fungsi pelayan HTTP Kita boleh menggunakan fungsi ini untuk melaksanakan fungsi pengehad semasa penghalaan dinamik.

Artikel ini akan memperkenalkan cara menggunakan fungsi pelayan HTTP dalam bahasa Go, digabungkan dengan algoritma pengehad semasa yang biasa digunakan, untuk melaksanakan fungsi pengehad semasa penghalaan dinamik.

1. Apakah yang mengehadkan arus penghalaan dinamik?
Penghadan semasa penghalaan dinamik merujuk kepada menetapkan had atas kadar permintaan yang berbeza untuk laluan yang berbeza (URI) Apabila bilangan permintaan untuk laluan tertentu melebihi had atas, pelayan akan menolak permintaan untuk laluan ini.

2. Gunakan Http.HandlerFunc untuk melaksanakan penghalaan dinamik dan pengehadan semasa
Pakej net/http dalam bahasa Go menyediakan fungsi HandleFunc untuk penghalaan permintaan kepada pemprosesan tertentu Secara Fungsi. Kita boleh melaksanakan fungsi mengehadkan semasa penghalaan dinamik dalam fungsi HandleFunc. net/http包提供了HandleFunc函数,用于将请求路由到特定的处理函数上。我们可以在HandleFunc函数中实现动态路由的限流功能。

package main

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

// 路由统计信息
type RouteStats struct {
    Count      int       // 当前请求数
    LastAccess time.Time // 最近一次访问时间
}

// 路由限流器
type RouteLimiter struct {
    stats      map[string]*RouteStats // 路由统计信息
    maxReq     int                    // 最大请求数
    interval   time.Duration          // 统计时间间隔
    expiration time.Duration          // 统计信息过期时间
    lock       sync.Mutex             // 互斥锁
}

// 初始化路由限流器
func NewRouteLimiter(maxReq int, interval, expiration time.Duration) *RouteLimiter {
    return &RouteLimiter{
        stats:      make(map[string]*RouteStats),
        maxReq:     maxReq,
        interval:   interval,
        expiration: expiration,
    }
}

// 中间件,负责限流检查
func (rl *RouteLimiter) LimitHandler(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 获取路由
        route := r.URL.Path

        rl.lock.Lock()

        // 如果路由不存在,初始化统计信息
        if _, ok := rl.stats[route]; !ok {
            rl.stats[route] = &RouteStats{Count: 0}
        }

        stats := rl.stats[route]
        rl.lock.Unlock()

        // 检查请求数是否超过上限
        if stats.Count >= rl.maxReq {
            w.WriteHeader(http.StatusTooManyRequests)
            return
        }

        // 更新统计信息
        stats.Count++
        stats.LastAccess = time.Now()

        // 定时清理过期的统计信息
        go func() {
            time.Sleep(rl.expiration)
            rl.lock.Lock()
            defer rl.lock.Unlock()

            if time.Since(stats.LastAccess) >= rl.expiration {
                delete(rl.stats, route)
            }
        }()

        // 调用下一个处理程序
        next.ServeHTTP(w, r)
    })
}

// 处理路由
func handleRoute(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello, World!")
}

func main() {
    // 创建路由限流器
    limiter := NewRouteLimiter(10, time.Minute, time.Hour)

    // 设置路由处理函数
    http.HandleFunc("/", limiter.LimitHandler(http.HandlerFunc(handleRoute)))

    // 启动HTTP服务器
    http.ListenAndServe(":8080", nil)
}

上述代码首先定义了一个RouteStats结构体,用于存储路由的统计信息,包括请求数和最近访问时间。然后定义了一个RouteLimiter结构体,用于存储所有路由的统计信息,并提供限流功能的实现。

NewRouteLimiter函数用于初始化一个RouteLimiter对象,参数maxReq表示每个路由的最大请求数,interval表示统计时间间隔,expiration表示统计信息的过期时间。

LimitHandler方法是一个中间件,用于对每个请求进行限流检查。它首先获取请求的路由,然后检查该路由的请求数是否超过上限。如果超过上限,返回HTTP 429 Too Many Requests响应;否则更新统计信息,并定时清理过期的统计信息。

handleRoute函数为示例路由处理函数,这里简单返回一个 "Hello, World!" 字符串。

main函数中,我们创建了一个RouteLimiter对象,并设置了10个请求/分钟的限流策略。然后使用http.HandleFuncrrreee

Kod di atas mula-mula mentakrifkan struktur RouteStats, yang digunakan untuk menyimpan statistik penghalaan, termasuk bilangan permintaan dan masa akses terkini. Kemudian struktur RouteLimiter ditakrifkan untuk menyimpan maklumat statistik semua laluan dan menyediakan pelaksanaan fungsi mengehadkan semasa.


Fungsi NewRouteLimiter digunakan untuk memulakan objek RouteLimiter Parameter maxReq mewakili bilangan maksimum permintaan untuk setiap laluan dan selang mewakili selang masa statistik, dan luput mewakili masa tamat tempoh maklumat statistik.

Kaedah LimitHandler ialah perisian tengah yang digunakan untuk menyemak had semasa setiap permintaan. Ia mula-mula mendapat laluan yang diminta dan kemudian menyemak sama ada bilangan permintaan untuk laluan itu melebihi had atas. Jika melebihi had atas, respons HTTP 429 Too Many Requests dikembalikan jika tidak, statistik dikemas kini dan statistik tamat tempoh dikosongkan dengan kerap.

Fungsi handleRoute ialah contoh fungsi pemprosesan laluan, yang hanya mengembalikan rentetan "Hello, World!"

🎜Dalam fungsi utama, kami mencipta objek RouteLimiter dan menetapkan dasar pengehadan semasa sebanyak 10 permintaan/minit. Kemudian gunakan http.HandleFunc untuk mengaitkan penghalaan dan perisian tengah mengehadkan semasa, dan akhirnya mulakan pelayan HTTP. 🎜🎜3. Kesimpulan🎜Menggunakan fungsi pelayan HTTP dalam bahasa Go, kami boleh melaksanakan fungsi pengehad semasa penghalaan dinamik dengan mudah. Dengan menyesuaikan perisian tengah dan pengehad aliran, kami boleh mengawal aliran laluan berbeza secara fleksibel untuk memastikan kestabilan dan keselamatan sistem. 🎜🎜Dalam aplikasi sebenar, kami boleh menyesuaikan strategi pengehad semasa yang berbeza mengikut keperluan perniagaan, seperti pemprosesan pengehad semasa yang disesuaikan berdasarkan identiti pengguna, kaedah permintaan, parameter permintaan, dsb. 🎜🎜(Tamat)🎜

Atas ialah kandungan terperinci Bagaimana untuk menggunakan fungsi pelayan HTTP dalam bahasa Go untuk melaksanakan fungsi pengehad semasa penghalaan dinamik?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn