performance.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. package controller
  2. import (
  3. "net/http"
  4. "os"
  5. "runtime"
  6. "time"
  7. "github.com/QuantumNous/new-api/common"
  8. "github.com/gin-gonic/gin"
  9. )
  10. // PerformanceStats 性能统计信息
  11. type PerformanceStats struct {
  12. // 缓存统计
  13. CacheStats common.DiskCacheStats `json:"cache_stats"`
  14. // 系统内存统计
  15. MemoryStats MemoryStats `json:"memory_stats"`
  16. // 磁盘缓存目录信息
  17. DiskCacheInfo DiskCacheInfo `json:"disk_cache_info"`
  18. // 磁盘空间信息
  19. DiskSpaceInfo DiskSpaceInfo `json:"disk_space_info"`
  20. // 配置信息
  21. Config PerformanceConfig `json:"config"`
  22. }
  23. // MemoryStats 内存统计
  24. type MemoryStats struct {
  25. // 已分配内存(字节)
  26. Alloc uint64 `json:"alloc"`
  27. // 总分配内存(字节)
  28. TotalAlloc uint64 `json:"total_alloc"`
  29. // 系统内存(字节)
  30. Sys uint64 `json:"sys"`
  31. // GC 次数
  32. NumGC uint32 `json:"num_gc"`
  33. // Goroutine 数量
  34. NumGoroutine int `json:"num_goroutine"`
  35. }
  36. // DiskCacheInfo 磁盘缓存目录信息
  37. type DiskCacheInfo struct {
  38. // 缓存目录路径
  39. Path string `json:"path"`
  40. // 目录是否存在
  41. Exists bool `json:"exists"`
  42. // 文件数量
  43. FileCount int `json:"file_count"`
  44. // 总大小(字节)
  45. TotalSize int64 `json:"total_size"`
  46. }
  47. // DiskSpaceInfo 磁盘空间信息
  48. type DiskSpaceInfo struct {
  49. // 总空间(字节)
  50. Total uint64 `json:"total"`
  51. // 可用空间(字节)
  52. Free uint64 `json:"free"`
  53. // 已用空间(字节)
  54. Used uint64 `json:"used"`
  55. // 使用百分比
  56. UsedPercent float64 `json:"used_percent"`
  57. }
  58. // PerformanceConfig 性能配置
  59. type PerformanceConfig struct {
  60. // 是否启用磁盘缓存
  61. DiskCacheEnabled bool `json:"disk_cache_enabled"`
  62. // 磁盘缓存阈值(MB)
  63. DiskCacheThresholdMB int `json:"disk_cache_threshold_mb"`
  64. // 磁盘缓存最大大小(MB)
  65. DiskCacheMaxSizeMB int `json:"disk_cache_max_size_mb"`
  66. // 磁盘缓存路径
  67. DiskCachePath string `json:"disk_cache_path"`
  68. // 是否在容器中运行
  69. IsRunningInContainer bool `json:"is_running_in_container"`
  70. }
  71. // GetPerformanceStats 获取性能统计信息
  72. func GetPerformanceStats(c *gin.Context) {
  73. // 不再每次获取统计都全量扫描磁盘,依赖原子计数器保证性能
  74. // 仅在系统启动或显式清理时同步
  75. cacheStats := common.GetDiskCacheStats()
  76. // 获取内存统计
  77. var memStats runtime.MemStats
  78. runtime.ReadMemStats(&memStats)
  79. // 获取磁盘缓存目录信息
  80. diskCacheInfo := getDiskCacheInfo()
  81. // 获取配置信息
  82. diskConfig := common.GetDiskCacheConfig()
  83. config := PerformanceConfig{
  84. DiskCacheEnabled: diskConfig.Enabled,
  85. DiskCacheThresholdMB: diskConfig.ThresholdMB,
  86. DiskCacheMaxSizeMB: diskConfig.MaxSizeMB,
  87. DiskCachePath: diskConfig.Path,
  88. IsRunningInContainer: common.IsRunningInContainer(),
  89. }
  90. // 获取磁盘空间信息
  91. diskSpaceInfo := getDiskSpaceInfo()
  92. stats := PerformanceStats{
  93. CacheStats: cacheStats,
  94. MemoryStats: MemoryStats{
  95. Alloc: memStats.Alloc,
  96. TotalAlloc: memStats.TotalAlloc,
  97. Sys: memStats.Sys,
  98. NumGC: memStats.NumGC,
  99. NumGoroutine: runtime.NumGoroutine(),
  100. },
  101. DiskCacheInfo: diskCacheInfo,
  102. DiskSpaceInfo: diskSpaceInfo,
  103. Config: config,
  104. }
  105. c.JSON(http.StatusOK, gin.H{
  106. "success": true,
  107. "data": stats,
  108. })
  109. }
  110. // ClearDiskCache 清理不活跃的磁盘缓存
  111. func ClearDiskCache(c *gin.Context) {
  112. // 清理超过 10 分钟未使用的缓存文件
  113. // 10 分钟是一个安全的阈值,确保正在进行的请求不会被误删
  114. err := common.CleanupOldDiskCacheFiles(10 * time.Minute)
  115. if err != nil {
  116. common.ApiError(c, err)
  117. return
  118. }
  119. c.JSON(http.StatusOK, gin.H{
  120. "success": true,
  121. "message": "不活跃的磁盘缓存已清理",
  122. })
  123. }
  124. // ResetPerformanceStats 重置性能统计
  125. func ResetPerformanceStats(c *gin.Context) {
  126. common.ResetDiskCacheStats()
  127. c.JSON(http.StatusOK, gin.H{
  128. "success": true,
  129. "message": "统计信息已重置",
  130. })
  131. }
  132. // ForceGC 强制执行 GC
  133. func ForceGC(c *gin.Context) {
  134. runtime.GC()
  135. c.JSON(http.StatusOK, gin.H{
  136. "success": true,
  137. "message": "GC 已执行",
  138. })
  139. }
  140. // getDiskCacheInfo 获取磁盘缓存目录信息
  141. func getDiskCacheInfo() DiskCacheInfo {
  142. // 使用统一的缓存目录
  143. dir := common.GetDiskCacheDir()
  144. info := DiskCacheInfo{
  145. Path: dir,
  146. Exists: false,
  147. }
  148. entries, err := os.ReadDir(dir)
  149. if err != nil {
  150. return info
  151. }
  152. info.Exists = true
  153. info.FileCount = 0
  154. info.TotalSize = 0
  155. for _, entry := range entries {
  156. if entry.IsDir() {
  157. continue
  158. }
  159. info.FileCount++
  160. if fileInfo, err := entry.Info(); err == nil {
  161. info.TotalSize += fileInfo.Size()
  162. }
  163. }
  164. return info
  165. }