Files
dushixiang 787fa6918d feat: WebSocket 消息可靠投递(纯内存事件队列)
- agent 数据写入增加 10s 超时,写失败立即断连重连,消除无超时写卡死期间快照被覆盖的静默丢失
- 事件类消息(SSH登录/防篡改/指令响应/监控检测)改走内存 outbox:seq + 服务端累计 ack + 断线重放,上限 1024 条溢出丢最旧,重启清空(可接受)
- 注册请求携带 BootID 会话标识:探针重启后 seq 从 1 重新分配,服务端据此重置确认位点,避免新消息被旧位点误判为重复而丢弃
- server 读循环与处理解耦(per-agent 有序队列 + 串行 worker),慢处理不再阻塞 TCP 读取,队列满断连由探针重放兜底
- 修复探针快速重连时旧连接误注销新连接的竞态(此前会闪断新连接)
- IsAgentEnabled 加 3s TTL 缓存,禁用立即失效;pong 在线状态写库去抖(首次 + 5 分钟心跳刷新)
- VM 写超时默认 30s -> 10s,快速失败配合重放兜底

新旧版本双向兼容:注册响应 Reliable 字段协商,旧 server 下探针自动降级直发
2026-08-30 22:30:41 +08:00

135 lines
4.1 KiB
Go

//go:build wireinject
// +build wireinject
package internal
import (
"time"
"github.com/google/wire"
"github.com/pika-monitor/pika/internal/config"
"github.com/pika-monitor/pika/internal/handler"
"github.com/pika-monitor/pika/internal/service"
"github.com/pika-monitor/pika/internal/vmclient"
"github.com/pika-monitor/pika/internal/websocket"
"go.uber.org/zap"
"gorm.io/gorm"
)
// InitializeApp 初始化应用
func InitializeApp(logger *zap.Logger, db *gorm.DB, cfg *config.AppConfig) (*AppComponents, error) {
wire.Build(
// VictoriaMetrics Client
provideVMClient,
service.NewAccountService,
service.NewAgentService,
service.NewUserService,
service.NewOIDCService,
service.NewGitHubOAuthService,
service.NewApiKeyService,
service.NewAlertService,
service.NewAlertRuleService,
service.NewPropertyService,
service.NewNotificationService,
service.NewMonitorService,
service.NewTamperService,
service.NewTrafficService,
service.NewMetricService,
service.NewGeoIPService,
service.NewDDNSService,
service.NewSSHLoginService,
service.NewPublicIPService,
service.NewThemeService,
service.NewNotifier,
// WebSocket Manager
websocket.NewManager,
// Handlers
handler.NewAgentHandler,
handler.NewAlertHandler,
handler.NewAlertRuleHandler,
handler.NewPropertyHandler,
handler.NewMonitorHandler,
handler.NewApiKeyHandler,
handler.NewAccountHandler,
handler.NewTamperHandler,
handler.NewDNSProviderHandler,
handler.NewDDNSHandler,
handler.NewSSHLoginHandler,
handler.NewThemeHandler,
handler.NewWebHandler,
// App Components
wire.Struct(new(AppComponents), "*"),
)
return nil, nil
}
// AppComponents 应用组件
type AppComponents struct {
AccountHandler *handler.AccountHandler
AgentHandler *handler.AgentHandler
ApiKeyHandler *handler.ApiKeyHandler
AlertHandler *handler.AlertHandler
AlertRuleHandler *handler.AlertRuleHandler
PropertyHandler *handler.PropertyHandler
MonitorHandler *handler.MonitorHandler
TamperHandler *handler.TamperHandler
DNSProviderHandler *handler.DNSProviderHandler
DDNSHandler *handler.DDNSHandler
SSHLoginHandler *handler.SSHLoginHandler
ThemeHandler *handler.ThemeHandler
WebHandler *handler.WebHandler
AgentService *service.AgentService
TrafficService *service.TrafficService
MetricService *service.MetricService
AlertService *service.AlertService
AlertRuleService *service.AlertRuleService
PropertyService *service.PropertyService
MonitorService *service.MonitorService
ApiKeyService *service.ApiKeyService
TamperService *service.TamperService
DDNSService *service.DDNSService
SSHLoginService *service.SSHLoginService
PublicIPService *service.PublicIPService
ThemeService *service.ThemeService
WSManager *websocket.Manager
VMClient *vmclient.VMClient
}
// provideVMClient 提供 VictoriaMetrics 客户端
func provideVMClient(cfg *config.AppConfig, logger *zap.Logger) *vmclient.VMClient {
// 写入超时默认 10s:VM 抖动时快速失败,未确认消息由探针重放
// 机制兜底,避免 30s 级别的停滞阻塞探针消息的串行处理
const defaultWriteTimeout = 10 * time.Second
// 检查配置
if cfg.VictoriaMetrics == nil || !cfg.VictoriaMetrics.Enabled {
logger.Info("VictoriaMetrics is not enabled, using default configuration")
// 返回一个默认配置的客户端(用于本地开发)
return vmclient.NewVMClient("http://localhost:8428", defaultWriteTimeout, 60*time.Second)
}
// 使用配置创建客户端
writeTimeout := time.Duration(cfg.VictoriaMetrics.WriteTimeout) * time.Second
if writeTimeout == 0 {
writeTimeout = defaultWriteTimeout
}
queryTimeout := time.Duration(cfg.VictoriaMetrics.QueryTimeout) * time.Second
if queryTimeout == 0 {
queryTimeout = 60 * time.Second
}
logger.Info("VictoriaMetrics client initialized",
zap.String("url", cfg.VictoriaMetrics.URL),
zap.Duration("writeTimeout", writeTimeout),
zap.Duration("queryTimeout", queryTimeout))
return vmclient.NewVMClient(cfg.VictoriaMetrics.URL, writeTimeout, queryTimeout)
}