# MeshRay Service 层架构详解 **文档版本**: v1.0 **更新时间**: 2026-03-24 **适用范围**: `internal/service/` 模块 --- ## 📊 Service 层在整体架构中的位置 ``` ┌─────────────────────────────────────────────┐ │ Web UI(Vue 3 + Element Plus) │ └────────────────┬────────────────────────────┘ │ REST API / WebSocket ┌────────────────▼────────────────────────────┐ │ API Handler(Gin 接入层) │ │ - network_handler.go │ │ - device_handler.go │ │ - user_handler.go │ │ - service_handler.go │ └────────────────┬────────────────────────────┘ │ 函数调用 ┌────────────────▼────────────────────────────┐ │ Service Layer(业务逻辑层)⭐核心 │ │ - NetworkService ← 组网管理 │ │ - DeviceService ← 设备管理 │ │ - PolicyService ← 策略管理 │ │ - ExternalService ← 外部服务管理 │ │ - UserService ← 用户认证 │ │ - MonitorService ← 监控告警 │ │ - DDNSService ← DDNS 同步 │ │ - AuditService ← 审计日志 │ └──────┬──────────────────────────────────────┘ │ ├──────────────────────────────────────┐ │ │ ┌──────▼──────┐ ┌────────▼────────┐ │ Store Layer │ │ Ctr Layer │ │ (数据持久化) │ │ (实时控制) │ │ │ │ │ │ - networks │ │ - wgctrl │ │ - devices │ │ - core gRPC │ │ - policies │ │ - 实时调度 │ │ - users │ │ │ │ - services │ │ │ └─────────────┘ └─────────────────┘ ``` **关键点**: - ✅ **Service 层是业务逻辑的核心** - ✅ **Ctr 层只是 Service 层调用的一个执行器** - ✅ **很多 Service 功能完全不依赖 Ctr**(如用户登录、策略校验) --- ## 🎯 Service 层模块划分 ### **完整的服务模块清单** ``` internal/service/ ├── service.go # Service 层总入口和依赖注入 │ type ServiceProvider struct { │ network *NetworkService │ device *DeviceService │ policy *PolicyService │ external *ExternalService │ user *UserService │ monitor *MonitorService │ ddns *DDNSService │ audit *AuditService │ } │ ├── network.go # 组网管理服务 │ ├── ListNetworks() []Network # 获取网络列表 │ ├── CreateNetwork() (*Network, error) # 创建网络 │ ├── DeleteNetwork() error # 删除网络 │ ├── UpdateNetwork() error # 更新网络配置 │ ├── GenerateMeshSeed() (*MeshSeed, error) # 生成 MeshSeed │ ├── ParseMeshSeed() (*MeshSeed, error) # 解析 MeshSeed │ └── JoinNetwork() error # 加入网络 │ ├── device.go # 设备管理服务 │ ├── ListDevices() []Device # 设备列表 │ ├── AddDevice() (*Device, error) # 添加设备 │ ├── RemoveDevice() error # 删除设备 │ ├── RegenerateKey() error # 重新生成密钥 │ ├── GetDeviceConfig() (*WGConfig, error) # 获取 WG 配置 │ └── ImportDevice() error # 导入现有设备 │ ├── policy.go # 策略管理服务 │ ├── ListPolicies() []Policy # 策略列表 │ ├── SetPolicy() error # 设置传输策略 │ ├── GetPolicy() (*Policy, error) # 获取策略 │ ├── ValidatePolicy() error # 验证策略合法性 │ ├── GetEffectivePolicy() (*Policy, error) # 获取生效策略 │ └── ResetPolicy() error # 重置策略 │ ├── external_service.go # 外部服务管理服务 │ ├── ListServices() []ExternalService # 服务列表 │ ├── AddService() error # 添加服务 │ ├── UpdateService() error # 更新服务 │ ├── DeleteService() error # 删除服务 │ ├── TestConnectivity() error # 测试连通性 │ ├── GetServiceSchema() (string, error) # 获取 JSON Schema │ └── ListByCategory() []ExternalService # 按分类筛选 │ ├── user.go # 用户认证服务 │ ├── Login() (string, error) # 登录 → JWT Token │ ├── Register() error # 注册 │ ├── ChangePassword() error # 修改密码 │ ├── VerifyToken() (*Claims, error) # 验证 JWT │ ├── RefreshToken() (string, error) # 刷新 Token │ └── GetUserByID() (*User, error) # 根据 ID 获取用户 │ ├── monitor.go # 监控告警服务 │ ├── GetSystemStats() (*SystemStats, error) # 系统统计 │ ├── GetNetworkStatus() (*NetworkStatus, error) # 网络状态 │ ├── CheckAlertRules() ([]Alert, error) # 检查告警规则 │ ├── SendAlert() error # 发送告警 │ ├── ListAlertRules() []AlertRule # 告警规则列表 │ └── AddAlertRule() error # 添加告警规则 │ ├── ddns.go # DDNS 服务 │ ├── SyncDDNS() error # 同步 DDNS 记录 │ ├── GetDDNSStatus() (*DDNSStatus, error) # 获取状态 │ ├── RefreshDDNS() error # 刷新记录 │ ├── TestDNSProvider() error # 测试 DNS 服务商 │ └── GetDDNSHistory() []DDNSRecord # 历史记录 │ └── audit.go # 审计日志服务 ├── LogAction() error # 记录操作日志 ├── ListAuditLogs() []AuditLog # 查询日志 ├── ExportAuditLogs() ([]byte, error) # 导出日志 ├── GetAuditStats() (*AuditStats, error) # 统计数据 └── CleanOldLogs() error # 清理旧日志 ``` --- ## 📋 每个 Service 的职责详解 ### **1. NetworkService - 组网管理** **职责**: - ✅ 组网的创建、删除、更新 - ✅ MeshSeed 的生成和解析 - ✅ 网络配置的持久化 - ✅ 调用 Ctr 执行实际操作 **核心方法示例**: ```go // CreateNetwork 创建网络 func (s *NetworkService) CreateNetwork(req CreateNetworkRequest) (*Network, error) { // ① 业务规则校验 if req.Name == "" { return nil, errors.New("组网名称不能为空") } // 检查名称是否重复 var existing Network err := s.store.DB().Where("name = ?", req.Name).First(&existing).Error if err == nil { return nil, errors.New("组网名称已存在") } // ② 数据生成 networkID := snowflake.Generate() secret := generateSecureSecret() // 32 字节随机 // ③ 保存到数据库 network := &model.Network{ ID: networkID, Name: req.Name, Secret: secret, Subnet: req.Subnet, STUNServers: []string{"stun.l.google.com:19302"}, CreatedAt: time.Now(), } err = s.store.DB().Create(network).Error if err != nil { return nil, err } // ④ 调用 ctr 执行(事务外,失败需回滚) err = s.ctrClient.CreateNetwork(networkID, network.ToConfig()) if err != nil { // 回滚:删除刚创建的 network s.store.DB().Delete(network) return nil, fmt.Errorf("调用 ctr 失败:%w", err) } return network, nil } // GenerateMeshSeed 生成组网凭证 func (s *NetworkService) GenerateMeshSeed(networkID uint64) (*MeshSeed, error) { // ① 查询网络信息 var network model.Network err := s.store.DB().First(&network, networkID).Error if err != nil { return nil, errors.New("网络不存在") } // ② 生成 SeedID(16 字节随机 Base64) seedID := generateRandomBase64(16) // ③ Ed25519 签名 signature := ed25519.Sign(privateKey, []byte(network.Secret)) // ④ AES-GCM 加密配置 ciphertext := aesGCM.Encrypt(network.ToJSON()) // ⑤ 构建 MeshSeed meshSeed := &MeshSeed{ SeedID: seedID, NetworkID: networkID, Signature: signature, Ciphertext: ciphertext, IssuedAt: time.Now(), ExpiresAt: time.Now().Add(365 * 24 * time.Hour), } // ⑥ 保存到数据库 s.store.DB().Create(&model.MeshSeed{ NetworkID: networkID, Data: meshSeed.ToJSON(), }) return meshSeed, nil // ✅ 完全不需要调用 ctr! } ``` --- ### **2. DeviceService - 设备管理** **职责**: - ✅ WireGuard 密钥对生成 - ✅ 设备信息管理 - ✅ WG 配置文件生成 - ✅ 调用 Ctr 添加 Peer **核心方法示例**: ```go // AddDevice 添加设备 func (s *DeviceService) AddDevice(networkID uint64, name string) (*Device, error) { // ① 查询网络 var network model.Network err := s.store.DB().First(&network, networkID).Error if err != nil { return nil, errors.New("网络不存在") } // ② 生成 WG 密钥对 privateKey, publicKey, err := wgtypes.GenerateKey() if err != nil { return nil, err } // ③ 分配 IP(从子网中自动分配) ip := allocateIP(network.Subnet) // ④ 生成设备 ID deviceID := snowflake.Generate() // ⑤ 保存到数据库 device := &model.Device{ ID: deviceID, NetworkID: networkID, Name: name, PublicKey: publicKey.String(), PrivateKey: encryptPrivateKey(privateKey), // 加密存储 IP: ip, AllowedIPs: []string{ip + "/32"}, } err = s.store.DB().Create(device).Error if err != nil { return nil, err } // ⑥ 调用 ctr 添加 Peer(可选,如果立即上线) if req.ImmediateConnect { err = s.ctrClient.AddPeer(networkID, device.PublicKey, device.AllowedIPs) if err != nil { s.store.DB().Delete(device) return nil, fmt.Errorf("调用 ctr 失败:%w", err) } } return device, nil } // GetDeviceConfig 获取设备配置(生成 WG 配置文件) func (s *DeviceService) GetDeviceConfig(deviceID uint64) (string, error) { // ① 查询设备信息 var device model.Device err := s.store.DB().Preload("Network").First(&device, deviceID).Error if err != nil { return "", errors.New("设备不存在") } // ② 解密私钥 privateKey := decryptPrivateKey(device.PrivateKey) // ③ 生成 WG 配置 config := fmt.Sprintf(`[Interface] PrivateKey = %s Address = %s ListenPort = 51820 [Peer] PublicKey = %s AllowedIPs = %s Endpoint = %s:51820 `, privateKey, device.IP, device.Network.PublicKey, device.AllowedIPs, device.Network.Endpoint) return config, nil // ✅ 纯业务逻辑,不需要调用 ctr! } ``` --- ### **3. UserService - 用户认证(完全不依赖 Ctr)** **职责**: - ✅ 用户注册、登录 - ✅ JWT Token 生成和验证 - ✅ 密码加密存储 - ✅ 审计日志记录 **核心方法示例**: ```go // Login 用户登录 func (s *UserService) Login(username, password string) (string, error) { // ① 查询用户 var user model.User err := s.store.DB().Where("username = ?", username).First(&user).Error if err != nil { return "", errors.New("用户名或密码错误") } // ② 验证密码(bcrypt) err = bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(password)) if err != nil { return "", errors.New("用户名或密码错误") } // ③ 生成 JWT Token claims := jwt.Claims{ UserID: user.ID, Username: user.Username, Role: user.Role, } token := jwt.GenerateToken(claims, jwtSecret, 24*time.Hour) // ④ 记录登录日志 s.auditService.LogAction(user.ID, "login", "用户登录成功") return token, nil // ✅ 完全不需要调用 ctr! } // Register 用户注册 func (s *UserService) Register(username, password, email string) error { // ① 检查用户名是否已存在 var existing model.User err := s.store.DB().Where("username = ?", username).First(&existing).Error if err == nil { return errors.New("用户名已存在") } // ② 密码加密(bcrypt) hash, err := bcrypt.GenerateFromPassword([]byte(password), 12) if err != nil { return err } // ③ 创建用户 user := &model.User{ Username: username, Email: email, PasswordHash: string(hash), Role: "user", } err = s.store.DB().Create(user).Error if err != nil { return err } // ④ 记录注册日志 s.auditService.LogAction(user.ID, "register", "用户注册成功") return nil // ✅ 完全不需要调用 ctr! } ``` --- ### **4. PolicyService - 策略管理(部分依赖 Ctr)** **职责**: - ✅ 9 层传输策略配置 - ✅ 策略合法性校验 - ✅ 策略持久化 - ✅ 调用 Ctr 应用策略 **核心方法示例**: ```go // SetPolicy 设置传输策略 func (s *PolicyService) SetPolicy(networkID uint64, policy PolicyConfig) error { // ① 业务规则校验 if err := s.validatePolicy(policy); err != nil { return fmt.Errorf("策略配置不合法:%w", err) } // ② 保存到数据库 policyModel := &model.Policy{ NetworkID: networkID, Config: policy.ToJSON(), UpdatedAt: time.Now(), } err := s.store.DB().Save(policyModel).Error if err != nil { return err } // ③ 调用 ctr 应用策略(可选,如果网络正在运行) if network.IsActive { err = s.ctrClient.UpdatePolicy(networkID, policy) if err != nil { return fmt.Errorf("应用策略失败:%w", err) } } return nil } // validatePolicy 验证策略合法性(纯业务逻辑) func (s *PolicyService) validatePolicy(policy PolicyConfig) error { // 检查至少启用了一层 if !policy.AnyLayerEnabled() { return errors.New("至少需要启用一层传输") } // 检查优先级顺序 if !policy.IsValidOrder() { return errors.New("传输层优先级顺序不合法") } // 检查 STUN/TURN 服务器配置 if policy.EnableDirectUDP && len(policy.STUNServers) == 0 { return errors.New("启用 Direct-UDP 需要配置 STUN 服务器") } if policy.EnableTURN && len(policy.TURNServers) == 0 { return errors.New("启用 TURN 需要配置 TURN 服务器") } return nil // ✅ 纯业务逻辑校验,不需要调用 ctr! } ``` --- ## 🔄 Service 层的通用模式 ### **标准操作流程** ```go func (s *XXXService) DoSomething(params Params) (Result, error) { // ① 业务规则校验 if err := s.validate(params); err != nil { return nil, err } // ② 数据生成/转换 data := generateData(params) // ③ 保存到数据库 err := s.store.DB().Create(&data).Error if err != nil { return nil, err } // ④ 调用 ctr 执行(可选,放在事务外) err = s.ctrClient.DoSomething(data.ID, data.Config) if err != nil { // 回滚:删除刚创建的数据 s.store.DB().Delete(&data) return nil, fmt.Errorf("调用 ctr 失败:%w", err) } return data, nil } ``` ### **不调用 Ctr 的场景** 以下场景**完全不需要调用 Ctr**: 1. ✅ **用户认证**:Login/Register/VerifyToken 2. ✅ **数据查询**:ListXXX/GetXXX 3. ✅ **配置生成**:GenerateMeshSeed/GetDeviceConfig 4. ✅ **策略校验**:ValidatePolicy 5. ✅ **日志审计**:LogAction/ListAuditLogs 6. ✅ **统计分析**:GetAuditStats/GetSystemStats --- ## 📊 Service 与 Ctr 的职责对比 | 维度 | Service 层 | Ctr 层 | |------|----------|--------| | **定位** | 业务逻辑核心 | 实时控制执行器 | | **职责** | 业务规则、数据生成、持久化 | 执行 WG/Core 操作 | | **依赖数据库** | ✅ 是(直接操作) | ❌ 否(通过参数接收) | | **依赖 Ctr** | ⚠️ 部分依赖 | ❌ 不依赖 Service | | **主动性** | ✅ 主动发起调用 | ❌ 被动执行 | | **可测试性** | ✅ 可 Mock Ctr | ✅ 可独立测试 | | **示例方法** | CreateNetwork
Login
GenerateMeshSeed | CreateDevice
AddPeer
CreateEngine | --- ## ✅ 总结 ### **Service 层的核心价值** 1. ✅ **业务逻辑的承载者** - 处理所有业务规则 - 生成和转换数据 - 持久化到数据库 2. ✅ **Ctr 层的调用者** - 决定何时调用 Ctr - 传递必要的参数 - 处理 Ctr 的返回结果 3. ✅ **前后端的桥梁** - 接收 API Handler 的请求 - 返回处理结果给 Handler - 对外暴露完整的业务能力 ### **设计原则** - ✅ **Service 层是核心**:所有业务逻辑都在这里 - ✅ **Ctr 层是工具**:只在需要实时控制时调用 - ✅ **保持解耦**:Service 层可以独立于 Ctr 测试 - ✅ **事务一致性**:Ctr 失败时需要回滚数据库 --- *文档版本:v1.0* *最后更新:2026-03-24* *维护者:MeshRay Team*