|
@@ -0,0 +1,73 @@
|
|
|
+---
|
|
|
+title: golang 重复提交和流量限制
|
|
|
+date: 2020-07-08 12:00:00
|
|
|
+tags: Golang
|
|
|
+---
|
|
|
+
|
|
|
+### 写的比较粗糙,有错误的地方希望指正,不会英语,部分变量用拼音命名,打扰了
|
|
|
+
|
|
|
+``` go
|
|
|
+//LimitInfo 限制对象
|
|
|
+type LimitInfo struct {
|
|
|
+ Time int64
|
|
|
+ Count int64
|
|
|
+ Name string
|
|
|
+ LimitType int //1 流量控制,2 并发控制
|
|
|
+ LimitKey string //限制key
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+//Limit 限制方法
|
|
|
+func (l *LimitInfo) Limit() bool {
|
|
|
+ limit := true
|
|
|
+ key := "limit-key-" + l.LimitKey
|
|
|
+ c := redisutil.Pool.Get()
|
|
|
+ defer c.Close()
|
|
|
+ result, errRedis := c.Do("Incr", key)
|
|
|
+ if errRedis != nil {
|
|
|
+ log.Info(l.Name, " ,key:", key, ", errRedis=[", errRedis, "]")
|
|
|
+ limit = false
|
|
|
+ }
|
|
|
+ count, errorcase := redis.Int64(result, nil)
|
|
|
+ if errorcase != nil {
|
|
|
+ log.Info(l.Name, " ,key:", key, " ,errorcase=[", errorcase, "]")
|
|
|
+ limit = false
|
|
|
+ }
|
|
|
+ if l.LimitType == 1 { //LimitType 1 是流量控制
|
|
|
+ if count == 1 {
|
|
|
+ if _, errExpire := c.Do("expire", key, l.Time); errExpire != nil {
|
|
|
+ log.Info(l.Name, " ,key:", key, " ,errExpire=[", errExpire, "]")
|
|
|
+ limit = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if l.LimitType == 2 { //LimitType 2 是并发控制,防重复提交
|
|
|
+ if _, errExpire := c.Do("expire", key, l.Time); errExpire != nil {
|
|
|
+ log.Info(l.Name, " ,key:", key, " ,errExpire=[", errExpire, "]")
|
|
|
+ limit = false
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //未做限制
|
|
|
+ limit = true
|
|
|
+ }
|
|
|
+ if count > l.Count {
|
|
|
+ limit = false
|
|
|
+ log.Info(l.Name, " ,key:", key, " ,err=[out limit] ,limit:", l.Count)
|
|
|
+ }
|
|
|
+ return limit
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## 使用如下:
|
|
|
+
|
|
|
+``` go
|
|
|
+redisutil.Pool = redisutil.NewPool(*redisutil.RedisServer)
|
|
|
+ info := &LimitInfo{
|
|
|
+ //10秒
|
|
|
+ Time: 10,
|
|
|
+ Count: 10,
|
|
|
+ Name: "请求限制0001",
|
|
|
+ LimitType: 1,
|
|
|
+ LimitKey: "aaronwei-tensec-",
|
|
|
+ }
|
|
|
+info.Limit()
|
|
|
+```
|