Skip to content

Commit 060c9d9

Browse files
vickyydkikii16
andauthored
feat: 定义不进行失败计数的错误类型 (#159)
* solve Fix: resource has been exhausted counted as failure count * solve Fix: resource has been exhausted counted as failure count * Update provider.go * Update provider.go * Update provider.go * fix * fix2 * fix --------- Co-authored-by: kikii16 <[email protected]>
1 parent fa3e873 commit 060c9d9

File tree

3 files changed

+45
-6
lines changed

3 files changed

+45
-6
lines changed

internal/keypool/provider.go

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func (p *KeyProvider) SelectKey(groupID uint) (*models.APIKey, error) {
7373
}
7474

7575
// UpdateStatus 异步地提交一个 Key 状态更新任务。
76-
func (p *KeyProvider) UpdateStatus(apiKey *models.APIKey, group *models.Group, isSuccess bool) {
76+
func (p *KeyProvider) UpdateStatus(apiKey *models.APIKey, group *models.Group, isSuccess bool, errorMessage string) {
7777
go func() {
7878
keyHashKey := fmt.Sprintf("key:%d", apiKey.ID)
7979
activeKeysListKey := fmt.Sprintf("group:%d:active_keys", group.ID)
@@ -83,7 +83,7 @@ func (p *KeyProvider) UpdateStatus(apiKey *models.APIKey, group *models.Group, i
8383
logrus.WithFields(logrus.Fields{"keyID": apiKey.ID, "error": err}).Error("Failed to handle key success")
8484
}
8585
} else {
86-
if err := p.handleFailure(apiKey, group, keyHashKey, activeKeysListKey); err != nil {
86+
if err := p.handleFailure(apiKey, group, keyHashKey, activeKeysListKey, errorMessage); err != nil {
8787
logrus.WithFields(logrus.Fields{"keyID": apiKey.ID, "error": err}).Error("Failed to handle key failure")
8888
}
8989
}
@@ -117,6 +117,29 @@ func (p *KeyProvider) executeTransactionWithRetry(operation func(tx *gorm.DB) er
117117
return err
118118
}
119119

120+
// shouldCountFailure 判断错误是否应该计入失败次数
121+
func (p *KeyProvider) shouldCountFailure(errorMsg string) bool {
122+
if errorMsg == "" {
123+
return true // 没有错误信息时默认计数
124+
}
125+
126+
// 转换为小写进行匹配
127+
errorLower := strings.ToLower(errorMsg)
128+
129+
// 不计入失败次数的错误模式
130+
excludePatterns := []string{
131+
"resource has been exhausted (e.g. check quota).", // Resource has been exhausted (e.g. check quota).
132+
}
133+
134+
for _, pattern := range excludePatterns {
135+
if strings.Contains(errorLower, pattern) {
136+
return false
137+
}
138+
}
139+
140+
return true // 其他错误计入失败次数
141+
}
142+
120143
func (p *KeyProvider) handleSuccess(keyID uint, keyHashKey, activeKeysListKey string) error {
121144
keyDetails, err := p.store.HGetAll(keyHashKey)
122145
if err != nil {
@@ -163,7 +186,7 @@ func (p *KeyProvider) handleSuccess(keyID uint, keyHashKey, activeKeysListKey st
163186
})
164187
}
165188

166-
func (p *KeyProvider) handleFailure(apiKey *models.APIKey, group *models.Group, keyHashKey, activeKeysListKey string) error {
189+
func (p *KeyProvider) handleFailure(apiKey *models.APIKey, group *models.Group, keyHashKey, activeKeysListKey string, errorMessage string) error {
167190
keyDetails, err := p.store.HGetAll(keyHashKey)
168191
if err != nil {
169192
return fmt.Errorf("failed to get key details from store: %w", err)
@@ -175,6 +198,16 @@ func (p *KeyProvider) handleFailure(apiKey *models.APIKey, group *models.Group,
175198

176199
failureCount, _ := strconv.ParseInt(keyDetails["failure_count"], 10, 64)
177200

201+
// 判断是否应该计入失败次数
202+
shouldCount := p.shouldCountFailure(errorMessage)
203+
if !shouldCount {
204+
logrus.WithFields(logrus.Fields{
205+
"keyID": apiKey.ID,
206+
"errorMessage": errorMessage,
207+
}).Debug("Error not counted towards failure threshold")
208+
return nil // 不计入失败次数,直接返回
209+
}
210+
178211
// 获取该分组的有效配置
179212
blacklistThreshold := group.EffectiveConfig.BlacklistThreshold
180213

internal/keypool/validator.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,11 @@ func (s *KeyValidator) ValidateSingleKey(key *models.APIKey, group *models.Group
6161

6262
isValid, validationErr := ch.ValidateKey(ctx, key, group)
6363

64-
s.keypoolProvider.UpdateStatus(key, group, isValid)
64+
var errorMsg string
65+
if !isValid && validationErr != nil {
66+
errorMsg = validationErr.Error()
67+
}
68+
s.keypoolProvider.UpdateStatus(key, group, isValid, errorMsg)
6569

6670
if !isValid {
6771
logrus.WithFields(logrus.Fields{

internal/proxy/server.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,15 +195,14 @@ func (ps *ProxyServer) executeRequestWithRetry(
195195
return
196196
}
197197

198-
ps.keyProvider.UpdateStatus(apiKey, group, false)
199-
200198
var statusCode int
201199
var errorMessage string
202200
var parsedError string
203201

204202
if err != nil {
205203
statusCode = 500
206204
errorMessage = err.Error()
205+
parsedError = errorMessage // 网络错误直接使用原始错误信息
207206
logrus.Debugf("Request failed (attempt %d/%d) for key %s: %v", retryCount+1, cfg.MaxRetries, utils.MaskAPIKey(apiKey.KeyValue), err)
208207
} else {
209208
// HTTP-level error (status >= 400)
@@ -220,6 +219,9 @@ func (ps *ProxyServer) executeRequestWithRetry(
220219
logrus.Debugf("Request failed with status %d (attempt %d/%d) for key %s. Parsed Error: %s", statusCode, retryCount+1, cfg.MaxRetries, utils.MaskAPIKey(apiKey.KeyValue), parsedError)
221220
}
222221

222+
// 使用解析后的错误信息更新密钥状态
223+
ps.keyProvider.UpdateStatus(apiKey, group, false, parsedError)
224+
223225
newRetryErrors := append(retryErrors, types.RetryError{
224226
StatusCode: statusCode,
225227
ErrorMessage: errorMessage,

0 commit comments

Comments
 (0)