ソースを参照

wip:搜索并发限制调整

wangshan 1 年間 前
コミット
9e1ae99064

+ 8 - 2
jyBXCore/rpc/etc/bxcore.yaml

@@ -16,15 +16,21 @@ LabelUrl:
 DefaultSearchCacheTime: 24
 LimitSearchText:
   Flag: true
-  Count: 40
+  Count: 200
   TimeOut: 60
   Percentage: 80
-  NoLogin: 1
+  NoLogin: 5
   UserIds:
     - 581858dbc9ebc2132200002e
     - 5cc02842c9ebc2227593893d
   Msg: f 开关状态:%s //-2 从配置文件重置,-1 关闭,1 打开<br><br>c 并发数:%d //-2 不限制并发数,-1 无条件直接限制,>0 限制并发数<br><br>t 个人查询限制时间:%ds //-1 不限制<br><br>
   LimitKey: mobile_limit_%s
+  ForPayer: 2
+  WebhookURL:
+    - https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=78864582-d770-452f-a55d-e8d17c647f31
+  LimitItems:
+    - detail
+    - filetext
 SearchTypeSwitch: true
 FileSignBool: true
 PaySearchLimit:

+ 13 - 12
jyBXCore/rpc/init/init.go

@@ -15,18 +15,19 @@ import (
 )
 
 var (
-	configFile     = flag.String("cf", "etc/bxcore.yaml", "the config file")
-	C              config.Config
-	dbFile         = flag.String("df", "etc/db.yaml", "the db file")
-	DB             config.Db
-	logFile        = flag.String("lf", "etc/logs.yaml", "the logs file")
-	logc           entity.Logc
-	propertyFile   = flag.String("pf", "etc/property.yaml", "the logs file")
-	Property       map[string][]string
-	SearchLimitKey = "jy_limitSearchText_new" // 全文或附件搜索限制
-	Middleground   *middleground.Middleground
-	Search_Thread  chan bool
-	ReqLimitInit   *ReqLimit
+	configFile            = flag.String("cf", "etc/bxcore.yaml", "the config file")
+	C                     config.Config
+	dbFile                = flag.String("df", "etc/db.yaml", "the db file")
+	DB                    config.Db
+	logFile               = flag.String("lf", "etc/logs.yaml", "the logs file")
+	logc                  entity.Logc
+	propertyFile          = flag.String("pf", "etc/property.yaml", "the logs file")
+	Property              map[string][]string
+	SearchLimitKey        = "jy_limitSearchText_new"     // 全文或附件搜索限制
+	SearchLimitKeyNoLogin = "jy_limitSearchText_noLogin" //未登录
+	Middleground          *middleground.Middleground
+	Search_Thread         chan bool
+	ReqLimitInit          *ReqLimit
 )
 
 type ReqLimit struct {

+ 3 - 0
jyBXCore/rpc/internal/config/config.go

@@ -24,6 +24,9 @@ type Config struct {
 		UserIds    []string
 		Msg        string
 		LimitKey   string
+		ForPayer   int
+		WebhookURL []string
+		LimitItems []string
 	}
 	SearchTypeSwitch bool //标题和正文 同时查询,关键词>1;是否优化查询只查正文(正文包含标题)
 	FileSignBool     bool //IC.C.FileSignBool列表是否显示附件标识开关

+ 11 - 1
jyBXCore/rpc/internal/logic/getsearchlistlogic.go

@@ -155,7 +155,17 @@ func (l *GetSearchListLogic) GetSearchList(in *bxcore.SearchReq) (*bxcore.Search
 	searchLimit := util.IsSearchLimit(strings.Split(in.SelectType, ","))
 	//全文检索限制
 	if searchLimit {
-		res.IsLimit = util.IsLimited(in.LimitFlag, in.UserId, in.UserType != "fType", in.IsNew)
+		//res.IsLimit = util.IsLimited(in.LimitFlag, in.UserId, in.UserType != "fType", in.IsNew)
+		res.IsLimit = util.CheckLimit(util.UserIdentMap[func(userId string, isPay bool) string {
+			switch {
+			case isPay:
+				return "payer"
+			case userId != "":
+				return "free"
+			default:
+				return "noLogin"
+			}
+		}(in.UserId, in.IsPay)], in.LimitFlag, in.IsNew)
 		if res.IsLimit == 1 { //没有被限制
 			defer util.Limit()
 		}

+ 94 - 2
jyBXCore/rpc/util/limitSearchText.go

@@ -3,14 +3,14 @@ package util
 import (
 	MC "app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/redis"
-	"fmt"
 	IC "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/rpc/init"
+	"fmt"
 )
 
 // 标讯搜索:全文搜索和附件搜索限制
 func IsSearchLimit(searchItems []string) bool {
 	for _, searchItem := range searchItems {
-		if searchItem == "detail" || searchItem == "filetext" {
+		if LimitItemsMap[searchItem] {
 			return true
 		}
 	}
@@ -23,6 +23,12 @@ func LimitSearchInit() {
 		for i := 0; i < IC.C.LimitSearchText.Count; i++ {
 			redis.RPUSH("other", IC.SearchLimitKey, 1)
 		}
+		if limitItems := IC.C.LimitSearchText.LimitItems; len(limitItems) > 0 {
+			LimitItemsMap = map[string]bool{}
+			for _, v := range IC.C.LimitSearchText.LimitItems {
+				LimitItemsMap[v] = true
+			}
+		}
 	}
 }
 
@@ -92,3 +98,89 @@ func IsCanLogin(userId string) bool {
 	}
 	return false
 }
+
+var (
+	UserIdentMap = map[string]int{
+		"payer":   1,
+		"free":    2,
+		"noLogin": 3,
+	}
+	LimitItemsMap = map[string]bool{
+		"detail":   true,
+		"filetext": true,
+	}
+)
+
+/*
+限制正文、附件查询
+return 1 正常
+return -1 抱歉!由于系统繁忙暂时无法进行搜索,请1分钟后再试!
+return -2 抱歉!由于系统繁忙暂时无法进行搜索,请稍后再试!
+userIdent 未登录用户是;cookie 中存的标识;登录用户是UserId
+*/
+func CheckLimit(userType int, userIdent string, isNew bool) (state int64) {
+	if !IC.C.LimitSearchText.Flag {
+		state = 1
+		return
+	}
+	var limitCount = int(redis.LLEN("other", IC.SearchLimitKey))
+	switch IC.C.LimitSearchText.Count {
+	case -2: //不限制
+		state = 1
+		return
+	case -1:
+		state = -2
+		return
+	default:
+		if limitCount <= 0 {
+			state = -1
+			return
+		}
+	}
+	//同一用户 -- 请求频次 在IC.C.LimitSearchText.TimeOut内 不允许多次请求
+	if IC.C.LimitSearchText.TimeOut > 0 {
+		if isNew {
+			if limitCount <= IC.C.LimitSearchText.Count/2 {
+				timeLimit, _ := redis.Exists("other", fmt.Sprintf(IC.C.LimitSearchText.LimitKey, userIdent))
+				if timeLimit {
+					state = -1
+					return
+				}
+			}
+		}
+		redis.Put("other", fmt.Sprintf(IC.C.LimitSearchText.LimitKey, userIdent), 1, IC.C.LimitSearchText.TimeOut)
+	}
+	//userType 用户标识:1:付费用户;2:免费用户;3:未登录用户;
+	switch userType {
+	case 1:
+		if limitCount > 0 {
+			state = 1
+		}
+	default:
+		state = -2
+		if limitCount > IC.C.LimitSearchText.ForPayer {
+			switch userType {
+			case 2:
+				quota := limitCount * IC.C.LimitSearchText.Percentage / 100
+				if quota > 0 {
+					state = 1
+				} else {
+					state = -1
+				}
+			case 3:
+				quota := limitCount * IC.C.LimitSearchText.NoLogin / 100
+				if quota > 0 {
+					state = 1
+				} else {
+					state = -1
+				}
+			}
+		}
+	}
+	//两套负载 同一套并发池
+	pollLimit := redis.LPOP("other", IC.SearchLimitKey)
+	if MC.IntAll(pollLimit) <= 0 {
+		state = -2
+	}
+	return
+}

+ 46 - 0
jyBXCore/rpc/util/warn.go

@@ -0,0 +1,46 @@
+package util
+
+import (
+	IC "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/rpc/init"
+	"bytes"
+	"encoding/json"
+	"github.com/zeromicro/go-zero/core/logx"
+	"net/http"
+)
+
+// TODO docin 更新保存异常告警
+func SendMsgByWXURL(msg string) {
+	logx.Info("warn msg:", msg)
+	if len(IC.C.LimitSearchText.WebhookURL) > 0 {
+		for _, url := range IC.C.LimitSearchText.WebhookURL {
+			if ok := SendBot(url, msg); !ok {
+				logx.Info("数据加载异常 企业微信机器人提醒失败--:", url, msg)
+			}
+		}
+	}
+}
+
+func SendBot(webhookURL, msg string) (b bool) {
+	// 构造请求体
+	payload := map[string]interface{}{
+		"msgtype": "text",
+		"text": map[string]string{
+			"content": msg,
+		},
+	}
+	// 转换为 JSON 字符串
+	payloadBytes, err := json.Marshal(payload)
+	if err != nil {
+		logx.Info("Error :", err.Error())
+		return
+	}
+	// 发送 POST 请求
+	resp, err := http.Post(webhookURL, "application/json", bytes.NewReader(payloadBytes))
+	if err != nil {
+		logx.Info("Error :", err.Error())
+		return
+	}
+	defer resp.Body.Close()
+	b = true
+	return
+}