Refactor configuration and key management

- Removed key management configuration from .env.example and related code.
- Updated Makefile to load environment variables for HOST and PORT.
- Modified main.go to handle request logging with a wait group for graceful shutdown.
- Simplified dashboard statistics handler to focus on key counts and request metrics.
- Removed key manager implementation and related interfaces.
- Updated proxy server to use atomic counters for round-robin key selection.
- Cleaned up unused types and configurations in types.go.
- Added package-lock.json for frontend dependencies.
This commit is contained in:
tbphp
2025-06-30 22:09:16 +08:00
parent 5f0990f22b
commit b9a833ceab
10 changed files with 130 additions and 669 deletions

View File

@@ -8,6 +8,7 @@ import (
"gpt-load/internal/response"
"net/http"
"sync"
"sync/atomic"
"time"
"github.com/gin-gonic/gin"
@@ -18,7 +19,7 @@ import (
// ProxyServer represents the proxy server
type ProxyServer struct {
DB *gorm.DB
groupCounters sync.Map // For round-robin key selection
groupCounters sync.Map // map[uint]*atomic.Uint64
requestLogChan chan models.RequestLog
}
@@ -82,18 +83,22 @@ func (ps *ProxyServer) selectAPIKey(group *models.Group) (*models.APIKey, error)
return nil, fmt.Errorf("no active API keys available in group '%s'", group.Name)
}
// Get the current counter for the group
counter, _ := ps.groupCounters.LoadOrStore(group.ID, uint64(0))
currentCounter := counter.(uint64)
// Get or create a counter for the group. The value is a pointer to a uint64.
val, _ := ps.groupCounters.LoadOrStore(group.ID, new(atomic.Uint64))
counter := val.(*atomic.Uint64)
// Select the key and increment the counter
selectedKey := activeKeys[int(currentCounter%uint64(len(activeKeys)))]
ps.groupCounters.Store(group.ID, currentCounter+1)
// Atomically increment the counter and get the index for this request.
index := counter.Add(1) - 1
selectedKey := activeKeys[int(index%uint64(len(activeKeys)))]
return &selectedKey, nil
}
func (ps *ProxyServer) logRequest(c *gin.Context, group *models.Group, key *models.APIKey, startTime time.Time) {
// Update key stats based on request success
isSuccess := c.Writer.Status() < 400
go ps.updateKeyStats(key.ID, isSuccess)
logEntry := models.RequestLog{
ID: fmt.Sprintf("req_%d", time.Now().UnixNano()),
Timestamp: startTime,
@@ -113,6 +118,27 @@ func (ps *ProxyServer) logRequest(c *gin.Context, group *models.Group, key *mode
}
}
// updateKeyStats atomically updates the request and failure counts for a key
func (ps *ProxyServer) updateKeyStats(keyID uint, success bool) {
// Always increment the request count
updates := map[string]interface{}{
"request_count": gorm.Expr("request_count + 1"),
}
// Additionally, increment the failure count if the request was not successful
if !success {
updates["failure_count"] = gorm.Expr("failure_count + 1")
}
result := ps.DB.Model(&models.APIKey{}).Where("id = ?", keyID).Updates(updates)
if result.Error != nil {
logrus.WithFields(logrus.Fields{
"keyID": keyID,
"error": result.Error,
}).Error("Failed to update key stats")
}
}
// Close cleans up resources
func (ps *ProxyServer) Close() {
// Nothing to close for now