performance.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package middleware
  2. import (
  3. "fmt"
  4. "net/http"
  5. "strings"
  6. "github.com/QuantumNous/new-api/common"
  7. "github.com/QuantumNous/new-api/types"
  8. "github.com/gin-gonic/gin"
  9. )
  10. // SystemPerformanceCheck 检查系统性能中间件
  11. func SystemPerformanceCheck() gin.HandlerFunc {
  12. return func(c *gin.Context) {
  13. // 仅检查 Relay 接口 (/v1, /v1beta 等)
  14. // 这里简单判断路径前缀,可以根据实际路由调整
  15. path := c.Request.URL.Path
  16. if strings.HasPrefix(path, "/v1/messages") {
  17. if err := checkSystemPerformance(); err != nil {
  18. c.JSON(err.StatusCode, gin.H{
  19. "error": err.ToClaudeError(),
  20. })
  21. c.Abort()
  22. return
  23. }
  24. } else {
  25. if err := checkSystemPerformance(); err != nil {
  26. c.JSON(err.StatusCode, gin.H{
  27. "error": err.ToOpenAIError(),
  28. })
  29. c.Abort()
  30. return
  31. }
  32. }
  33. c.Next()
  34. }
  35. }
  36. // checkSystemPerformance 检查系统性能是否超过阈值
  37. func checkSystemPerformance() *types.NewAPIError {
  38. config := common.GetPerformanceMonitorConfig()
  39. if !config.Enabled {
  40. return nil
  41. }
  42. status := common.GetSystemStatus()
  43. // 检查 CPU
  44. if config.CPUThreshold > 0 && int(status.CPUUsage) > config.CPUThreshold {
  45. return types.NewErrorWithStatusCode(
  46. fmt.Errorf("system cpu overloaded (current: %.1f%%, threshold: %d%%)", status.CPUUsage, config.CPUThreshold),
  47. "system_cpu_overloaded", http.StatusServiceUnavailable)
  48. }
  49. // 检查内存
  50. if config.MemoryThreshold > 0 && int(status.MemoryUsage) > config.MemoryThreshold {
  51. return types.NewErrorWithStatusCode(
  52. fmt.Errorf("system memory overloaded (current: %.1f%%, threshold: %d%%)", status.MemoryUsage, config.MemoryThreshold),
  53. "system_memory_overloaded", http.StatusServiceUnavailable)
  54. }
  55. // 检查磁盘
  56. if config.DiskThreshold > 0 && int(status.DiskUsage) > config.DiskThreshold {
  57. return types.NewErrorWithStatusCode(
  58. fmt.Errorf("system disk overloaded (current: %.1f%%, threshold: %d%%)", status.DiskUsage, config.DiskThreshold),
  59. "system_disk_overloaded", http.StatusServiceUnavailable)
  60. }
  61. return nil
  62. }