ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Ρ ΡΠ°Π·ΡΠ΅ΡΠ°Ρ Π΄ΠΎ 2000 ΡΠ΅ΠΊΡΡΠΈΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠΉ ΠΈ ΠΎΡΠΊΠ»ΠΎΠ½ΡΡ Π»ΠΈΡΠ½ΠΈΠ΅ Π·Π°ΠΏΡΠΎΡΡ.
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π½Π°ΠΏΠΈΡΠ°ΡΡ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΠΎΠ΅ ΠΠ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΏΡΡΠ°Π΅ΡΡΡ Π²ΡΡΠ°Π²Π»ΡΡΡ Π² Π±ΡΡΠ΅ΡΠΈΠ·ΠΎΠ²Π°Π½Π½ΡΠΉ ΠΊΠ°Π½Π°Π» ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π·, ΠΊΠΎΠ³Π΄Π° ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ Π½ΠΎΠ²ΠΎΠ΅ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅.
(ΡΡΠΎ ΠΏΡΠΎΡΡΠΎ Π΄ΠΎΠΊΠ°Π·Π°ΡΠ΅Π»ΡΡΡΠ²ΠΎ ΠΊΠΎΠ½ΡΠ΅ΠΏΡΠΈΠΈ, Π½Π΅ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΡΠΉ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡ)
func LimitMiddleware() gin.HandlerFunc {
// create a buffered channel with 2000 spaces
semaphore := make(chan bool, 2000)
return func (c *gin.Context) {
select {
case semaphore <- true: // Try putting a new val into our semaphore
// Ok, managed to get a space in queue. execute the handler
c.Next()
// Don't forget to release a handle
<-semaphore
default:
// Buffer full, so drop the connection. Return whatever status you want here
return
}
}
}
@wangcn Π― Π½Π°ΠΏΠΈΡΠ°Π» ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΠΎΠ΅ ΠΠ Π΄Π»Ρ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ gin, ΡΡΠΎΠ±Ρ ΠΎΠ³ΡΠ°Π½ΠΈΡΠΈΡΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠ΅ΠΊΡΡΠΈΡ Π·Π°ΠΏΡΠΎΡΠΎΠ², ΠΈ ΠΎΠ½ΠΎ ΠΌΠΎΠΆΠ΅Ρ Π»ΡΡΡΠ΅ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ Π»ΠΈΠΌΠΈΡ Π·Π°ΠΏΡΠΎΡΠΎΠ² ΠΏΡΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ ΠΏΠ°Π½ΠΈΠΊΠΈ, Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΅Π³ΠΎ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
package main
import (
"github.com/easonlin404/limit"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.Use(limit.Limit(200)) // limit the number of current requests
r.GET("/", func(c *gin.Context) {
// your code
})
r.Run()
}
ΠΠ΄Π΅ΡΡ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΏΡΠ΅Π΄ΠΏΠΎΡΡΠΈΡΠ΅Π»ΡΠ½Π΅Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ sync/atomic
ΡΠ°ΠΊ ΠΊΠ°ΠΊ Π²Ρ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΠ΅.
Π‘Π°ΠΌΡΠΉ ΠΏΠΎΠ»Π΅Π·Π½ΡΠΉ ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠΉ
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π½Π°ΠΏΠΈΡΠ°ΡΡ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΠΎΠ΅ ΠΠ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΏΡΡΠ°Π΅ΡΡΡ Π²ΡΡΠ°Π²Π»ΡΡΡ Π² Π±ΡΡΠ΅ΡΠΈΠ·ΠΎΠ²Π°Π½Π½ΡΠΉ ΠΊΠ°Π½Π°Π» ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π·, ΠΊΠΎΠ³Π΄Π° ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ Π½ΠΎΠ²ΠΎΠ΅ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅.
(ΡΡΠΎ ΠΏΡΠΎΡΡΠΎ Π΄ΠΎΠΊΠ°Π·Π°ΡΠ΅Π»ΡΡΡΠ²ΠΎ ΠΊΠΎΠ½ΡΠ΅ΠΏΡΠΈΠΈ, Π½Π΅ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΡΠΉ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡ)