参考链接
代码总意
在模拟演示并发请求的情况下,然后来限制用户1s内只能请求3,如果请求超过3次,则返回错误的提示信息,
代码实现
- main.go
package main
import (
"net/http"
"sync"
)
func main() {
wg := sync.WaitGroup{}
wg.Add(5)
go func(){
defer wg.Done()
http.Get("http://localhost:8080/user/query")
}()
go func(){
defer wg.Done()
http.Get("http://localhost:8080/user/query")
}()
go func(){
defer wg.Done()
http.Get("http://localhost:8080/user/query")
}()
go func(){
defer wg.Done()
http.Get("http://localhost:8080/user/query")
}()
go func(){
defer wg.Done()
http.Get("http://localhost:8080/user/query")
}()
wg.Wait()
}
- router.go
package main
import (
"fmt"
"net/http"
"sync"
"time"
)
var myServer = MyServer{}
func main() {
//这样就把请求转换到了你的myServer的ServerHttp函数来处理了
_ = http.ListenAndServe(":8080",myServer)
}
type MyServer struct {}
type RequestCountTime struct {
//请求的词素
count int64
//最后的访问时间
lastTime int64
}
//所有的请求的
func (recv MyServer)ServeHTTP(resp http.ResponseWriter, req *http.Request){
//拦截
filterRequest(resp,req)
}
func query(resp http.ResponseWriter, req *http.Request){
_,_ = fmt.Fprint(resp,req.URL.Path)
}
func get(resp http.ResponseWriter, req *http.Request){
_,_ = fmt.Fprint(resp,req.URL.Path)
}
//key : uid+url
//value : RequestCountTime
var cacheMap = make(map[string]RequestCountTime)
var mu = sync.Mutex{}
const(
ONE_SECOND = 1
REQUEST_COUNT = 3
)
//限制用户的每秒的请求的次数,1s10次的频率
func filterRequest(resp http.ResponseWriter,req *http.Request){
uid := "userXPH123"
reqUrl := req.URL.Path
key := uid+reqUrl
mu.Lock()
value,ok := cacheMap[key]
fmt.Println("value的值——> ",value)
//在cacheMap中有
if ok{
//看该请求是否在这1s内,如果不在则请零
//如果在,则看该请求的次数是否超过限制的请求次数
//(当前请求的时间-最后一次访问的时间) > 1s || 请求次数 > 限制次数
//则返回错误
res := time.Now().Unix() - value.lastTime
fmt.Println("访问时间——>",res,ONE_SECOND)
if time.Duration(res) >=ONE_SECOND || value.count >= REQUEST_COUNT{
fmt.Println("对不起你的请求此时已超限")
_, _ = fmt.Fprint(resp,"对不起你的请求此时已超限")
return
}
value.count++
cacheMap[key] = value
}else{
//如果去不到值则是第一次访问
cacheMap[key] = RequestCountTime{count:1,lastTime:time.Now().Unix()}
}
mu.Unlock()
fmt.Println(reqUrl)
switch reqUrl {
case "/user/query":
query(resp,req)
case "/user/get":
get(resp,req)
default:
_,_ = fmt.Fprint(resp,"找不到请求资源")
}
}
版权声明:本文为heart66_A原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。