Golang implements IP current limiting
With the rapid development of the Internet and mobile Internet, servers are facing increasing pressure. How to limit client requests to the server and avoid server crashes has become a big problem. In actual projects, we often need to limit the number of IP requests to ensure the availability of the website.
Here, we will introduce how to use Golang to implement IP current limiting. In general, we will use the token bucket algorithm to implement current limiting based on IP address. The token bucket algorithm is a flow control algorithm that allows a certain number of requests to pass within a certain period of time and limits the request flow within a period of time.
Implementation details
The token bucket algorithm puts tokens into the bucket at a constant rate. The token bucket has a capacity limit, which means that the number of tokens in the bucket will not exceed the capacity. For each request, a token is removed from the bucket. If there is no token in the bucket, the request cannot go through.
In order to implement current limiting based on IP address, we need to create a token bucket for each IP address. Each token bucket has a maximum capacity and a constant speed. When a request comes, we remove a token from the token bucket and reject the request if there is no token in the bucket.
Based on this, we can define an IP current limiter:
type IPRateLimiter struct { limiterBuckets map[string]*rate.Limiter mu *sync.Mutex r rate.Limit b int }
Among them, limiterBuckets is a mapping that maps string IP addresses to token buckets. mu is a mutex, r is the rate at which the rate limiter puts tokens per second, and b is the capacity of the token bucket.
In order to create a token bucket for each IP address, we define a function NewIPRateLimiter:
func NewIPRateLimiter(r rate.Limit, b int) *IPRateLimiter { return &IPRateLimiter{ limiterBuckets: make(map[string]*rate.Limiter), mu: &sync.Mutex{}, r: r, b: b, } } func (i *IPRateLimiter) AddIP(ip string) *rate.Limiter { i.mu.Lock() defer i.mu.Unlock() limiter := rate.NewLimiter(i.r, i.b) i.limiterBuckets[ip] = limiter return limiter }
The AddIP function is used to create a token bucket for the IP address. If a token bucket was created for this IP address, the existing token bucket is returned, otherwise a new token bucket is created and returned.
Finally, we can implement HTTP middleware to limit the number of requests to an IP address:
func (i *IPRateLimiter) Limit(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ip := r.RemoteAddr limiter, ok := i.limiterBuckets[ip] if !ok { limiter = i.AddIP(ip) } if !limiter.Allow() { http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests) return } next.ServeHTTP(w, r) }) }
This middleware allows requests to pass at a specified rate and capacity. If the number of requests exceeds capacity, HTTP error code 429 (Too Many Requests) is returned.
The complete code is as follows:
package main import ( "net/http" "strconv" "sync" "golang.org/x/time/rate" ) type IPRateLimiter struct { limiterBuckets map[string]*rate.Limiter mu *sync.Mutex r rate.Limit b int } func NewIPRateLimiter(r rate.Limit, b int) *IPRateLimiter { return &IPRateLimiter{ limiterBuckets: make(map[string]*rate.Limiter), mu: &sync.Mutex{}, r: r, b: b, } } func (i *IPRateLimiter) AddIP(ip string) *rate.Limiter { i.mu.Lock() defer i.mu.Unlock() limiter := rate.NewLimiter(i.r, i.b) i.limiterBuckets[ip] = limiter return limiter } func (i *IPRateLimiter) Limit(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ip := r.RemoteAddr limiter, ok := i.limiterBuckets[ip] if !ok { limiter = i.AddIP(ip) } if !limiter.Allow() { http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests) return } next.ServeHTTP(w, r) }) } func IndexHandler(w http.ResponseWriter, r *http.Request) { w.Write([]byte("welcome.")) } func main() { limit := rate.Limit(10) // 速率,每秒放入令牌的数量 capacity := 100 // 容量,桶的大小 ipRateLimiter := NewIPRateLimiter(limit, capacity) http.Handle("/", ipRateLimiter.Limit(http.HandlerFunc(IndexHandler))) err := http.ListenAndServe(":8080", nil) if err != nil { panic(err) } }
In this example, we allow 10 tokens per second and limit the bucket capacity to 100. This means that the limiter can handle up to 10 requests per second, but will fail if the requests to the same IP address reach 100. At the same time, we define a simple handler that will respond to "Welcome".
Conclusion
In this article, we use Golang to implement IP current limiting and use the token bucket algorithm to limit the request rate of each IP address. This method can implement a simple and effective current limiting mechanism, and can be easily implemented in Golang. This can be a very useful technique when you are writing highly concurrent network applications.
The above is the detailed content of Golang implements IP current limiting. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics





OpenSSL, as an open source library widely used in secure communications, provides encryption algorithms, keys and certificate management functions. However, there are some known security vulnerabilities in its historical version, some of which are extremely harmful. This article will focus on common vulnerabilities and response measures for OpenSSL in Debian systems. DebianOpenSSL known vulnerabilities: OpenSSL has experienced several serious vulnerabilities, such as: Heart Bleeding Vulnerability (CVE-2014-0160): This vulnerability affects OpenSSL 1.0.1 to 1.0.1f and 1.0.2 to 1.0.2 beta versions. An attacker can use this vulnerability to unauthorized read sensitive information on the server, including encryption keys, etc.

The library used for floating-point number operation in Go language introduces how to ensure the accuracy is...

Queue threading problem in Go crawler Colly explores the problem of using the Colly crawler library in Go language, developers often encounter problems with threads and request queues. �...

This article introduces a variety of methods and tools to monitor PostgreSQL databases under the Debian system, helping you to fully grasp database performance monitoring. 1. Use PostgreSQL to build-in monitoring view PostgreSQL itself provides multiple views for monitoring database activities: pg_stat_activity: displays database activities in real time, including connections, queries, transactions and other information. pg_stat_replication: Monitors replication status, especially suitable for stream replication clusters. pg_stat_database: Provides database statistics, such as database size, transaction commit/rollback times and other key indicators. 2. Use log analysis tool pgBadg

Backend learning path: The exploration journey from front-end to back-end As a back-end beginner who transforms from front-end development, you already have the foundation of nodejs,...

The difference between string printing in Go language: The difference in the effect of using Println and string() functions is in Go...

The problem of using RedisStream to implement message queues in Go language is using Go language and Redis...

Under the BeegoORM framework, how to specify the database associated with the model? Many Beego projects require multiple databases to be operated simultaneously. When using Beego...
