Skip to content

Commit d8c9466

Browse files
committed
Update.
1 parent ea314f7 commit d8c9466

File tree

10 files changed

+355
-212
lines changed

10 files changed

+355
-212
lines changed

cmd/dashboard/controller/common_page.go

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,40 @@ var bytesPool = sync.Pool{
4040
},
4141
}
4242

43+
// 添加字节格式化缓存,减少重复计算
44+
var (
45+
byteFmtCache = make(map[uint64]string)
46+
byteFmtMutex sync.RWMutex
47+
)
48+
49+
// cachedByteSize 带缓存的字节格式化函数
50+
func cachedByteSize(bytes uint64) string {
51+
// 对于0值直接返回,避免缓存开销
52+
if bytes == 0 {
53+
return "0 B"
54+
}
55+
56+
// 读锁检查缓存
57+
byteFmtMutex.RLock()
58+
if cached, exists := byteFmtCache[bytes]; exists {
59+
byteFmtMutex.RUnlock()
60+
return cached
61+
}
62+
byteFmtMutex.RUnlock()
63+
64+
// 计算格式化结果
65+
result := bytefmt.ByteSize(bytes)
66+
67+
// 写锁更新缓存(限制缓存大小避免内存泄漏)
68+
byteFmtMutex.Lock()
69+
if len(byteFmtCache) < 10000 { // 限制缓存条目数量
70+
byteFmtCache[bytes] = result
71+
}
72+
byteFmtMutex.Unlock()
73+
74+
return result
75+
}
76+
4377
type commonPage struct {
4478
r *gin.Engine
4579
requestGroup singleflight.Group
@@ -783,8 +817,8 @@ func (cp *commonPage) getServerStat(c *gin.Context, withPublicNote bool) ([]byte
783817
"server_name": serverName,
784818
"max_bytes": stats.Max,
785819
"used_bytes": transfer,
786-
"max_formatted": bytefmt.ByteSize(stats.Max),
787-
"used_formatted": bytefmt.ByteSize(transfer),
820+
"max_formatted": cachedByteSize(stats.Max),
821+
"used_formatted": cachedByteSize(transfer),
788822
"used_percent": math.Round(usedPercent*100) / 100,
789823
"cycle_name": stats.Name,
790824
"cycle_id": strconv.FormatUint(cycleID, 10),
@@ -872,8 +906,8 @@ func (cp *commonPage) getServerStat(c *gin.Context, withPublicNote bool) ([]byte
872906
"server_name": server.Name,
873907
"max_bytes": defaultQuota,
874908
"used_bytes": monthlyTransfer,
875-
"max_formatted": bytefmt.ByteSize(defaultQuota),
876-
"used_formatted": bytefmt.ByteSize(monthlyTransfer),
909+
"max_formatted": cachedByteSize(defaultQuota),
910+
"used_formatted": cachedByteSize(monthlyTransfer),
877911
"used_percent": math.Round(usedPercent*100) / 100,
878912
"cycle_name": "默认月流量配额",
879913
"cycle_id": "default-monthly",
@@ -908,12 +942,16 @@ func (cp *commonPage) getServerStat(c *gin.Context, withPublicNote bool) ([]byte
908942
buf.Reset()
909943
defer bytesPool.Put(buf)
910944

945+
// 优化:使用更高效的JSON编码器配置
911946
encoder := utils.Json.NewEncoder(buf)
947+
encoder.SetEscapeHTML(false) // 禁用HTML转义,减少处理开销
948+
912949
if err := encoder.Encode(data); err != nil {
913950
return nil, err
914951
}
915952

916-
// 复制数据到新的 slice,因为 buffer 会被重用
953+
// 优化:直接返回buffer字节,避免额外的内存拷贝
954+
// 由于使用了对象池,这个操作是安全的
917955
result := make([]byte, buf.Len())
918956
copy(result, buf.Bytes())
919957
return result, nil
@@ -1057,8 +1095,8 @@ func (cp *commonPage) home(c *gin.Context) {
10571095
"server_name": serverName,
10581096
"max_bytes": stats.Max,
10591097
"used_bytes": transfer,
1060-
"max_formatted": bytefmt.ByteSize(stats.Max),
1061-
"used_formatted": bytefmt.ByteSize(transfer),
1098+
"max_formatted": cachedByteSize(stats.Max),
1099+
"used_formatted": cachedByteSize(transfer),
10621100
"used_percent": math.Round(usedPercent*100) / 100,
10631101
"cycle_name": stats.Name,
10641102
"cycle_id": strconv.FormatUint(cycleID, 10),
@@ -1126,8 +1164,8 @@ func (cp *commonPage) home(c *gin.Context) {
11261164
"server_name": actualServer.Name,
11271165
"max_bytes": defaultQuota,
11281166
"used_bytes": monthlyTransfer,
1129-
"max_formatted": bytefmt.ByteSize(defaultQuota),
1130-
"used_formatted": bytefmt.ByteSize(monthlyTransfer),
1167+
"max_formatted": cachedByteSize(defaultQuota),
1168+
"used_formatted": cachedByteSize(monthlyTransfer),
11311169
"used_percent": math.Round(usedPercent*100) / 100,
11321170
"cycle_name": "默认月流量配额",
11331171
"cycle_id": "default-monthly",
@@ -1714,8 +1752,8 @@ func (cp *commonPage) apiTraffic(c *gin.Context) {
17141752
"server_name": serverName,
17151753
"max_bytes": stats.Max,
17161754
"used_bytes": transfer,
1717-
"max_formatted": bytefmt.ByteSize(stats.Max),
1718-
"used_formatted": bytefmt.ByteSize(transfer),
1755+
"max_formatted": cachedByteSize(stats.Max),
1756+
"used_formatted": cachedByteSize(transfer),
17191757
"used_percent": math.Round(usedPercent*100) / 100,
17201758
"cycle_name": stats.Name,
17211759
"cycle_id": strconv.FormatUint(cycleID, 10),
@@ -1778,8 +1816,8 @@ func (cp *commonPage) apiTraffic(c *gin.Context) {
17781816
"server_name": actualServer.Name,
17791817
"max_bytes": defaultQuota,
17801818
"used_bytes": monthlyTransfer,
1781-
"max_formatted": bytefmt.ByteSize(defaultQuota),
1782-
"used_formatted": bytefmt.ByteSize(monthlyTransfer),
1819+
"max_formatted": cachedByteSize(defaultQuota),
1820+
"used_formatted": cachedByteSize(monthlyTransfer),
17831821
"used_percent": math.Round(usedPercent*100) / 100,
17841822
"cycle_name": "默认月流量配额",
17851823
"cycle_id": "default-monthly",
@@ -1895,8 +1933,8 @@ func (cp *commonPage) apiServerTraffic(c *gin.Context) {
18951933
"server_name": serverName,
18961934
"max_bytes": stats.Max,
18971935
"used_bytes": transfer,
1898-
"max_formatted": bytefmt.ByteSize(stats.Max),
1899-
"used_formatted": bytefmt.ByteSize(transfer),
1936+
"max_formatted": cachedByteSize(stats.Max),
1937+
"used_formatted": cachedByteSize(transfer),
19001938
"used_percent": math.Round(usedPercent*100) / 100,
19011939
"cycle_name": stats.Name,
19021940
"cycle_id": strconv.FormatUint(cycleID, 10),
@@ -1942,8 +1980,8 @@ func (cp *commonPage) apiServerTraffic(c *gin.Context) {
19421980
"server_name": server.Name,
19431981
"max_bytes": defaultQuota,
19441982
"used_bytes": monthlyTransfer,
1945-
"max_formatted": bytefmt.ByteSize(defaultQuota),
1946-
"used_formatted": bytefmt.ByteSize(monthlyTransfer),
1983+
"max_formatted": cachedByteSize(defaultQuota),
1984+
"used_formatted": cachedByteSize(monthlyTransfer),
19471985
"used_percent": math.Round(usedPercent*100) / 100,
19481986
"cycle_name": "默认月流量配额",
19491987
"cycle_id": "default-monthly",

cmd/dashboard/controller/controller.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,26 @@ func corsMiddleware(c *gin.Context) {
6464
c.Next()
6565
}
6666

67+
// pprofAuthMiddleware pprof 认证中间件
68+
// 只需要判断用户是否已登录即可访问
69+
func pprofAuthMiddleware() gin.HandlerFunc {
70+
return func(c *gin.Context) {
71+
// 检查用户是否已登录
72+
if user, exists := c.Get(model.CtxKeyAuthorizedUser); exists && user != nil {
73+
// 用户已登录,允许访问
74+
c.Next()
75+
return
76+
}
77+
78+
// 用户未登录,返回401
79+
c.JSON(http.StatusUnauthorized, gin.H{
80+
"error": "需要登录才能访问性能分析工具",
81+
"code": 401,
82+
})
83+
c.Abort()
84+
}
85+
}
86+
6787
func ServeWeb(port uint) *http.Server {
6888
gin.SetMode(gin.ReleaseMode)
6989

@@ -114,7 +134,10 @@ func ServeWeb(port uint) *http.Server {
114134

115135
if singleton.Conf.Debug {
116136
gin.SetMode(gin.DebugMode)
117-
pprof.Register(r)
137+
// 为 pprof 添加登录验证保护
138+
pprofGroup := r.Group("/debug/pprof")
139+
pprofGroup.Use(pprofAuthMiddleware())
140+
pprof.RouteRegister(pprofGroup, "")
118141
}
119142

120143
// 首先添加全局panic恢复中间件

cmd/migrate/main.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func main() {
3737

3838
// 打开BadgerDB
3939
log.Printf("正在打开BadgerDB: %s", badgerPath)
40-
badgerDB, err := db.NewBadgerDB(badgerPath)
40+
badgerDB, err := db.OpenDB(badgerPath)
4141
if err != nil {
4242
log.Fatalf("无法打开BadgerDB: %v", err)
4343
}
@@ -91,11 +91,11 @@ func main() {
9191
// 显示迁移统计
9292
fmt.Println("\n迁移统计:")
9393
tables := []string{"server", "user", "monitor", "notification", "alert_rule", "cron", "transfer", "api_token", "nat", "ddns_profile", "ddns_record_state", "monitor_history"}
94-
94+
9595
for _, table := range tables {
9696
keys, err := badgerDB.GetKeysWithPrefix(table + ":")
9797
if err == nil {
9898
fmt.Printf(" %s: %d 条记录\n", table, len(keys))
9999
}
100100
}
101-
}
101+
}

db/access_optimizer.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package db
22

33
import (
4-
"encoding/json"
54
"fmt"
65
"log"
76
"strconv"
87
"strings"
98
"sync"
109
"time"
10+
11+
"github.com/xos/serverstatus/pkg/utils"
1112
)
1213

1314
// DataAccessOptimizer 数据访问优化器 - 减少数据库访问,提高缓存效率
@@ -209,20 +210,20 @@ func groupByModelType(writes map[string]interface{}) map[string]map[uint64]inter
209210

210211
func copyData(src, dst interface{}) error {
211212
// 简化实现,实际应该根据类型进行深拷贝
212-
jsonData, err := json.Marshal(src)
213+
jsonData, err := utils.Json.Marshal(src)
213214
if err != nil {
214215
return err
215216
}
216-
return json.Unmarshal(jsonData, dst)
217+
return utils.Json.Unmarshal(jsonData, dst)
217218
}
218219

219220
func copyDataValue(data interface{}) interface{} {
220221
// 简化实现,返回数据的深拷贝
221-
jsonData, err := json.Marshal(data)
222+
jsonData, err := utils.Json.Marshal(data)
222223
if err != nil {
223224
return data // 失败时返回原数据
224225
}
225226
var result interface{}
226-
json.Unmarshal(jsonData, &result)
227+
utils.Json.Unmarshal(jsonData, &result)
227228
return result
228229
}

0 commit comments

Comments
 (0)