Skip to content

Commit aa9b9b8

Browse files
committed
feat: 实例缓存逻辑,缓解sqlite压力
1 parent 85b2bb1 commit aa9b9b8

File tree

15 files changed

+3149
-571
lines changed

15 files changed

+3149
-571
lines changed

cmd/server/main.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"NodePassDash/internal/nodepass"
1010
"NodePassDash/internal/router"
1111
"NodePassDash/internal/servicecache"
12+
"NodePassDash/internal/tunnelcache"
1213

1314
// "NodePassDash/internal/lifecycle"
1415
log "NodePassDash/internal/log"
@@ -225,6 +226,13 @@ func initializeServices(sseDebugLog bool) (*gorm.DB, *auth.Service, *endpoint.Se
225226
}
226227
log.Infof("✅ Service内存缓存初始化成功,已加载 %d 个服务", servicecache.Shared.Count())
227228

229+
// 初始化Tunnel内存缓存
230+
if err := tunnelcache.InitShared(gormDB); err != nil {
231+
log.Errorf("初始化Tunnel内存缓存失败: %v", err)
232+
return nil, nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("初始化Tunnel缓存失败: %v", err)
233+
}
234+
log.Infof("✅ Tunnel内存缓存初始化成功,已加载 %d 个隧道", tunnelcache.Shared.Count())
235+
228236
// 初始化其他服务
229237
endpointService := endpoint.NewService(gormDB)
230238
tunnelService := tunnel.NewService(gormDB)
@@ -328,6 +336,25 @@ func startBackgroundServices(gormDB *gorm.DB, sseService *sse.Service, sseManage
328336
}()
329337
log.Info("Service缓存定时持久化任务已启动(间隔: 30秒)")
330338

339+
// 启动Tunnel缓存定时持久化任务(每30秒持久化一次变更)
340+
go func() {
341+
ticker := time.NewTicker(30 * time.Second)
342+
defer ticker.Stop()
343+
344+
for range ticker.C {
345+
if err := tunnelcache.Shared.PersistIfNeeded(gormDB); err != nil {
346+
log.Errorf("❌ 持久化Tunnel缓存失败: %v", err)
347+
} else {
348+
stats := tunnelcache.Shared.GetStats()
349+
dirtyCount := stats["dirty_count"].(int)
350+
if dirtyCount > 0 {
351+
log.Debugf("💾 持久化了 %d 个变更的隧道", dirtyCount)
352+
}
353+
}
354+
}
355+
}()
356+
log.Info("Tunnel缓存定时持久化任务已启动(间隔: 30秒)")
357+
331358
// 启动SSE相关服务
332359
go func() {
333360
sseManager.StartDaemon()
@@ -374,6 +401,14 @@ func gracefulShutdown(server *http.Server, gormDB *gorm.DB, trafficScheduler *da
374401
log.Infof("✅ Service缓存已成功关闭并持久化")
375402
}
376403

404+
// 3. 持久化Tunnel缓存(保证数据不丢失)
405+
log.Infof("💾 正在持久化Tunnel缓存...")
406+
if err := tunnelcache.Shared.Shutdown(gormDB); err != nil {
407+
log.Errorf("❌ 关闭Tunnel缓存失败: %v", err)
408+
} else {
409+
log.Infof("✅ Tunnel缓存已成功关闭并持久化")
410+
}
411+
377412
// 关闭增强系统(暂时注释掉)
378413
// if err := lifecycleManager.Shutdown(); err != nil {
379414
// log.Errorf("增强系统关闭失败: %v", err)

go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
module NodePassDash
22

3-
go 1.23.0
3+
go 1.24.0
44

5-
toolchain go1.23.10
5+
toolchain go1.24.10
66

77
require (
88
github.com/gin-gonic/gin v1.10.1
@@ -43,6 +43,7 @@ require (
4343
github.com/ugorji/go/codec v1.2.12 // indirect
4444
golang.org/x/arch v0.8.0 // indirect
4545
golang.org/x/net v0.40.0 // indirect
46+
golang.org/x/sync v0.18.0 // indirect
4647
golang.org/x/sys v0.34.0 // indirect
4748
golang.org/x/text v0.25.0 // indirect
4849
google.golang.org/protobuf v1.34.1 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqj
9090
golang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
9191
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
9292
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
93+
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
94+
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
9395
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
9496
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
9597
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

internal/endpoint/service_test.go

Lines changed: 0 additions & 156 deletions
This file was deleted.

internal/endpointcache/shared.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,15 @@ func (s *EndpointShared) UpdateTunnelCount(id int64, count int64) {
250250
return
251251
}
252252

253+
// 更新隧道计数
254+
// var count1 int64
255+
// if err := db.Find(&models.Tunnel{}).Where("endpoint_id = ?", id).Count(&count1).Error; err != nil {
256+
// log.Errorf("[API] 查询端点 %d 隧道计数失败: %v", id, err)
257+
// } else {
258+
// endpointcache.Shared.UpdateTunnelCount(id, count)
259+
// log.Debugf("[API] 端点 %d 隧道计数已更新为: %d (已缓存)", id, count)
260+
// }
261+
253262
// 只更新隧道数量字段
254263
endpoint.TunnelCount = count
255264
endpoint.UpdatedAt = time.Now()

internal/services/service.go

Lines changed: 32 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"strings"
1313
"time"
1414

15+
"golang.org/x/sync/errgroup"
1516
"gorm.io/gorm"
1617
)
1718

@@ -162,52 +163,51 @@ func (s *ServiceImpl) AssembleService(req *AssembleServiceRequest) error {
162163
return nil
163164
}
164165

165-
// StartService 启动服务(启动 client 和 server 实例)
166-
func (s *ServiceImpl) StartService(sid string) error {
167-
service, err := s.GetServiceByID(sid)
168-
if err != nil {
169-
return fmt.Errorf("获取服务失败: %w", err)
170-
}
166+
// controlServiceInstances 并行控制服务的客户端和服务端实例
167+
// action: "start", "stop", "restart"
168+
func (s *ServiceImpl) controlServiceInstances(service *models.Services, action string) error {
169+
var g errgroup.Group
171170

172-
// 启动客户端实例
171+
// 并行控制客户端实例
173172
if service.ClientInstanceId != nil && service.ClientEndpointId != nil {
174-
if _, err := nodepass.ControlInstance(*service.ClientEndpointId, *service.ClientInstanceId, "start"); err != nil {
175-
return fmt.Errorf("启动客户端实例失败: %w", err)
176-
}
173+
g.Go(func() error {
174+
if _, err := nodepass.ControlInstance(*service.ClientEndpointId, *service.ClientInstanceId, action); err != nil {
175+
return fmt.Errorf("%s客户端实例失败: %w", action, err)
176+
}
177+
return nil
178+
})
177179
}
178180

179-
// 启动服务端实例(如果存在)
181+
// 并行控制服务端实例(如果存在)
180182
if service.ServerInstanceId != nil && service.ServerEndpointId != nil {
181-
if _, err := nodepass.ControlInstance(*service.ServerEndpointId, *service.ServerInstanceId, "start"); err != nil {
182-
return fmt.Errorf("启动服务端实例失败: %w", err)
183-
}
183+
g.Go(func() error {
184+
if _, err := nodepass.ControlInstance(*service.ServerEndpointId, *service.ServerInstanceId, action); err != nil {
185+
return fmt.Errorf("%s服务端实例失败: %w", action, err)
186+
}
187+
return nil
188+
})
184189
}
185190

186-
return nil
191+
// 等待所有goroutine完成
192+
return g.Wait()
187193
}
188194

189-
// StopService 停止服务(停止 client 和 server 实例)
190-
func (s *ServiceImpl) StopService(sid string) error {
195+
// StartService 启动服务(启动 client 和 server 实例)
196+
func (s *ServiceImpl) StartService(sid string) error {
191197
service, err := s.GetServiceByID(sid)
192198
if err != nil {
193199
return fmt.Errorf("获取服务失败: %w", err)
194200
}
201+
return s.controlServiceInstances(service, "start")
202+
}
195203

196-
// 停止客户端实例
197-
if service.ClientInstanceId != nil && service.ClientEndpointId != nil {
198-
if _, err := nodepass.ControlInstance(*service.ClientEndpointId, *service.ClientInstanceId, "stop"); err != nil {
199-
return fmt.Errorf("停止客户端实例失败: %w", err)
200-
}
201-
}
202-
203-
// 停止服务端实例(如果存在)
204-
if service.ServerInstanceId != nil && service.ServerEndpointId != nil {
205-
if _, err := nodepass.ControlInstance(*service.ServerEndpointId, *service.ServerInstanceId, "stop"); err != nil {
206-
return fmt.Errorf("停止服务端实例失败: %w", err)
207-
}
204+
// StopService 停止服务(停止 client 和 server 实例)
205+
func (s *ServiceImpl) StopService(sid string) error {
206+
service, err := s.GetServiceByID(sid)
207+
if err != nil {
208+
return fmt.Errorf("获取服务失败: %w", err)
208209
}
209-
210-
return nil
210+
return s.controlServiceInstances(service, "stop")
211211
}
212212

213213
// RestartService 重启服务(重启 client 和 server 实例)
@@ -216,22 +216,7 @@ func (s *ServiceImpl) RestartService(sid string) error {
216216
if err != nil {
217217
return fmt.Errorf("获取服务失败: %w", err)
218218
}
219-
220-
// 重启客户端实例
221-
if service.ClientInstanceId != nil && service.ClientEndpointId != nil {
222-
if _, err := nodepass.ControlInstance(*service.ClientEndpointId, *service.ClientInstanceId, "restart"); err != nil {
223-
return fmt.Errorf("重启客户端实例失败: %w", err)
224-
}
225-
}
226-
227-
// 重启服务端实例(如果存在)
228-
if service.ServerInstanceId != nil && service.ServerEndpointId != nil {
229-
if _, err := nodepass.ControlInstance(*service.ServerEndpointId, *service.ServerInstanceId, "restart"); err != nil {
230-
return fmt.Errorf("重启服务端实例失败: %w", err)
231-
}
232-
}
233-
234-
return nil
219+
return s.controlServiceInstances(service, "restart")
235220
}
236221

237222
// DeleteService 删除服务(先删除实例再删除服务记录)

0 commit comments

Comments
 (0)