feat: 缓存代理keys

This commit is contained in:
tbphp
2025-07-24 21:53:00 +08:00
parent abb8fa1d19
commit c421123ab6
8 changed files with 38 additions and 9 deletions

View File

@@ -73,6 +73,8 @@ func (sm *SystemSettingsManager) Initialize(store store.Store, gm groupManager,
} }
} }
settings.ProxyKeysMap = utils.StringToSet(settings.ProxyKeys, ",")
sm.DisplaySystemConfig(settings) sm.DisplaySystemConfig(settings)
return settings, nil return settings, nil

View File

@@ -5,6 +5,7 @@ import (
"gpt-load/internal/models" "gpt-load/internal/models"
"gpt-load/internal/response" "gpt-load/internal/response"
"gpt-load/internal/utils" "gpt-load/internal/utils"
"strings"
"time" "time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@@ -51,6 +52,14 @@ func (s *Server) UpdateSettings(c *gin.Context) {
return return
} }
// Sanitize proxy_keys input
if proxyKeys, ok := settingsMap["proxy_keys"]; ok {
if proxyKeysStr, ok := proxyKeys.(string); ok {
cleanedKeys := utils.SplitAndTrim(proxyKeysStr, ",")
settingsMap["proxy_keys"] = strings.Join(cleanedKeys, ",")
}
}
// 更新配置 // 更新配置
if err := s.SettingsManager.UpdateSettings(settingsMap); err != nil { if err := s.SettingsManager.UpdateSettings(settingsMap); err != nil {
response.Error(c, app_errors.NewAPIError(app_errors.ErrDatabase, err.Error())) response.Error(c, app_errors.NewAPIError(app_errors.ErrDatabase, err.Error()))

View File

@@ -3,7 +3,6 @@ package middleware
import ( import (
"fmt" "fmt"
"slices"
"strings" "strings"
"time" "time"
@@ -11,7 +10,6 @@ import (
"gpt-load/internal/response" "gpt-load/internal/response"
"gpt-load/internal/services" "gpt-load/internal/services"
"gpt-load/internal/types" "gpt-load/internal/types"
"gpt-load/internal/utils"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@@ -156,16 +154,14 @@ func ProxyAuth(gm *services.GroupManager) gin.HandlerFunc {
return return
} }
// Check Group keys first // Then check System-wide keys (O(1) lookup)
groupKeys := utils.SplitAndTrim(group.ProxyKeys, ",") if _, ok := group.EffectiveConfig.ProxyKeysMap[key]; ok {
if slices.Contains(groupKeys, key) {
c.Next() c.Next()
return return
} }
// Then check System-wide keys // Check Group keys first (O(1) lookup)
systemKeys := utils.SplitAndTrim(group.EffectiveConfig.ProxyKeys, ",") if _, ok := group.ProxyKeysMap[key]; ok {
if slices.Contains(systemKeys, key) {
c.Next() c.Next()
return return
} }

View File

@@ -58,6 +58,9 @@ type Group struct {
LastValidatedAt *time.Time `json:"last_validated_at"` LastValidatedAt *time.Time `json:"last_validated_at"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"` UpdatedAt time.Time `json:"updated_at"`
// For cache
ProxyKeysMap map[string]struct{} `gorm:"-" json:"-"`
} }
// APIKey 对应 api_keys 表 // APIKey 对应 api_keys 表

View File

@@ -7,6 +7,7 @@ import (
"gpt-load/internal/models" "gpt-load/internal/models"
"gpt-load/internal/store" "gpt-load/internal/store"
"gpt-load/internal/syncer" "gpt-load/internal/syncer"
"gpt-load/internal/utils"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gorm.io/gorm" "gorm.io/gorm"
@@ -47,6 +48,7 @@ func (gm *GroupManager) Initialize() error {
for _, group := range groups { for _, group := range groups {
g := *group g := *group
g.EffectiveConfig = gm.settingsManager.GetEffectiveConfig(g.Config) g.EffectiveConfig = gm.settingsManager.GetEffectiveConfig(g.Config)
g.ProxyKeysMap = utils.StringToSet(g.ProxyKeys, ",")
groupMap[g.Name] = &g groupMap[g.Name] = &g
logrus.WithFields(logrus.Fields{ logrus.WithFields(logrus.Fields{
"group_name": g.Name, "group_name": g.Name,

View File

@@ -37,6 +37,9 @@ type SystemSettings struct {
KeyValidationIntervalMinutes int `json:"key_validation_interval_minutes" default:"60" name:"密钥验证间隔(分钟)" category:"密钥配置" desc:"后台验证密钥的默认间隔(分钟)。" validate:"min=30"` KeyValidationIntervalMinutes int `json:"key_validation_interval_minutes" default:"60" name:"密钥验证间隔(分钟)" category:"密钥配置" desc:"后台验证密钥的默认间隔(分钟)。" validate:"min=30"`
KeyValidationConcurrency int `json:"key_validation_concurrency" default:"10" name:"密钥验证并发数" category:"密钥配置" desc:"后台定时验证无效 Key 时的并发数。" validate:"min=1"` KeyValidationConcurrency int `json:"key_validation_concurrency" default:"10" name:"密钥验证并发数" category:"密钥配置" desc:"后台定时验证无效 Key 时的并发数。" validate:"min=1"`
KeyValidationTimeoutSeconds int `json:"key_validation_timeout_seconds" default:"20" name:"密钥验证超时(秒)" category:"密钥配置" desc:"后台定时验证单个 Key 时的 API 请求超时时间(秒)。" validate:"min=5"` KeyValidationTimeoutSeconds int `json:"key_validation_timeout_seconds" default:"20" name:"密钥验证超时(秒)" category:"密钥配置" desc:"后台定时验证单个 Key 时的 API 请求超时时间(秒)。" validate:"min=5"`
// For cache
ProxyKeysMap map[string]struct{} `json:"-"`
} }
// ServerConfig represents server configuration // ServerConfig represents server configuration

View File

@@ -23,7 +23,7 @@ func GenerateSettingsMetadata(s *types.SystemSettings) []models.SystemSettingInf
fieldValue := v.Field(i) fieldValue := v.Field(i)
jsonTag := field.Tag.Get("json") jsonTag := field.Tag.Get("json")
if jsonTag == "" { if jsonTag == "" || jsonTag == "-" {
continue continue
} }

View File

@@ -40,3 +40,17 @@ func SplitAndTrim(s string, sep string) []string {
return result return result
} }
// StringToSet converts a separator-delimited string into a set
func StringToSet(s string, sep string) map[string]struct{} {
parts := SplitAndTrim(s, sep)
if len(parts) == 0 {
return nil
}
set := make(map[string]struct{}, len(parts))
for _, part := range parts {
set[part] = struct{}{}
}
return set
}