Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Cara menggunakan konteks untuk melaksanakan pengehadan aliran permintaan dalam Go

Cara menggunakan konteks untuk melaksanakan pengehadan aliran permintaan dalam Go

王林
王林asal
2023-07-21 10:13:23752semak imbas

Cara menggunakan konteks untuk melaksanakan pengehadan aliran permintaan dalam Go

Apabila membangunkan aplikasi web, kita selalunya perlu mengehadkan kekerapan akses kepada sumber atau antara muka tertentu untuk mengelakkan lebihan pelayan atau serangan berniat jahat. Dalam bahasa Go, kami boleh menggunakan kata kunci konteks dan pergi untuk melaksanakan pengehadan aliran permintaan.

Apakah konteks?
Dalam bahasa Go, konteks ialah mekanisme penghantaran nilai merentas fungsi dan Goroutine. Ia menyediakan cara untuk menghantar nilai khusus permintaan merentas pelbagai rantai panggilan fungsi dan antara Goroutine yang berbeza. Konteks biasanya digunakan untuk menghantar maklumat konteks permintaan semasa pemprosesan permintaan, seperti ID permintaan, maklumat pengesahan pengguna, dsb.

Di bawah ini kami akan menunjukkan cara menggunakan konteks untuk melaksanakan fungsi pengehad semasa permintaan. Kami akan menggunakan pakej golang.org/x/time/rate untuk melaksanakan algoritma baldi token. Algoritma baldi token ialah algoritma yang digunakan untuk mengawal kekerapan akses Ia berdasarkan idea mudah: sistem meletakkan token ke dalam baldi pada kadar tetap Setiap permintaan menggunakan satu token , permintaan seterusnya akan dihadkan.

Pertama, kita perlu memperkenalkan perpustakaan yang diperlukan:

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

Kemudian, kita perlu menentukan struktur untuk menyimpan peraturan pengehad kadar yang diminta dan contoh baldi token:

type RateLimiter struct {
    limiter *rate.Limiter
}

func NewRateLimiter(rateLimiter rate.Limit, burst int) *RateLimiter {
    return &RateLimiter{
        limiter: rate.NewLimiter(rateLimiter, burst),
    }
}

Seterusnya, dalam fungsi pemproses yang mengendalikan permintaan, kita boleh menggunakan konteks untuk mengehadkan kekerapan akses permintaan:

func (rl *RateLimiter) handleRequest(w http.ResponseWriter, r *http.Request) {
    // 使用context.WithValue方法将RateLimiter的实例存放到context中
    ctx := context.WithValue(r.Context(), "rateLimiter", rl)

    // 检查当前请求是否达到了限流的阈值
    if rl.limiter.Allow() {
        // 允许访问
        fmt.Fprintf(w, "Hello, World!")
    } else {
        // 请求被限制
        http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
    }
}

Akhir sekali, kami perlu mencipta pelayan http dan menetapkan fungsi pemprosesan permintaan:

func main() {
    // 创建一个令牌桶实例,允许每秒钟产生10个令牌,桶的最大容量为20
    rateLimiter := NewRateLimiter(rate.Every(time.Second), 20)

    // 创建一个http服务器
    server := http.Server{
        Addr:    ":8080",
        Handler: http.HandlerFunc(rateLimiter.handleRequest),
    }

    // 启动服务器
    server.ListenAndServe()
}

Kini, kami telah menyelesaikan fungsi menggunakan konteks untuk melaksanakan pengehadan aliran permintaan dalam Go . Dengan menggunakan konteks, anda boleh dengan mudah meluluskan peraturan pendikitan dan kejadian baldi token semasa pemprosesan permintaan. Jika permintaan melebihi ambang had semasa, kod status HTTP yang sesuai dan mesej ralat boleh dikembalikan.

Ringkasan
Artikel ini memperkenalkan cara menggunakan konteks untuk melaksanakan fungsi mengehadkan permintaan semasa dalam bahasa Go. Dengan menggunakan konteks dan algoritma baldi token, kami boleh mengehadkan kekerapan akses kepada sumber atau antara muka tertentu dengan mudah, dengan itu melindungi pelayan daripada permintaan berniat jahat.

Contoh kod:

package main

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

type RateLimiter struct {
    limiter *rate.Limiter
}

func NewRateLimiter(rateLimiter rate.Limit, burst int) *RateLimiter {
    return &RateLimiter{
        limiter: rate.NewLimiter(rateLimiter, burst),
    }
}

func (rl *RateLimiter) handleRequest(w http.ResponseWriter, r *http.Request) {
    ctx := context.WithValue(r.Context(), "rateLimiter", rl)

    if rl.limiter.Allow() {
        fmt.Fprintf(w, "Hello, World!")
    } else {
        http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
    }
}

func main() {
    rateLimiter := NewRateLimiter(rate.Every(time.Second), 20)

    server := http.Server{
        Addr:    ":8080",
        Handler: http.HandlerFunc(rateLimiter.handleRequest),
    }

    server.ListenAndServe()
}

Saya harap artikel ini dapat membantu anda melaksanakan fungsi pengehadan semasa dalam bahasa Go. Sudah tentu, ini hanyalah contoh mudah, dan logik perniagaan yang lebih kompleks mungkin diperlukan dalam amalan. Walau bagaimanapun, dengan memahami prinsip asas dan menggunakan konteks, anda boleh mengembangkan dan mengoptimumkan sewajarnya mengikut senario sebenar. Saya mengucapkan selamat maju jaya menggunakan bahasa Go!

Atas ialah kandungan terperinci Cara menggunakan konteks untuk melaksanakan pengehadan aliran permintaan dalam Go. 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