Initial commit

This commit is contained in:
2026-06-30 15:14:37 +08:00
commit 15dab96872
311 changed files with 95639 additions and 0 deletions
+489
View File
@@ -0,0 +1,489 @@
# MeshRay gRPC 架构真相与最终修复方案
**发现时间**: 2026-03-24
**状态**: 🔴 **确认问题存在** - 需要修复
**关键发现**: Ctr 只有 Core 客户端,没有 gRPC 服务器
---
## 🚨 最终确认:gRPC 服务器确实未启动
### **代码证据**
```go
// internal/ctr/ctr.go:33-46
func NewCtr(name string, networkID uint64, config *CtrConfig, logger *zap.Logger) (*Ctr, error) {
ctr := &Ctr{
name: name,
networkID: networkID,
config: config,
logger: logger,
coreClients: make(map[string]*CoreClient), // ← 只有客户端
}
// 初始化 WireGuard 管理器
ctr.wgManager = NewWGManager(logger)
return ctr, nil // ← 没有创建 gRPC 服务器
}
```
**搜索结果**:
```bash
grep -r "grpc.NewServer" internal/ctr/ # ❌ 无结果
grep -r "RegisterCoreService" internal/ctr/ # ❌ 无结果
grep -r "Serve(lis)" internal/ctr/ # ❌ 无结果
```
**结论**:
-**gRPC 服务器确实未启动** - 审查报告正确
-`core/grpc_service.go` 的实现无处可用
-`core/client/core_client.go` 会连接失败
---
## 🏗️ 架构分析:谁应该在 gRPC 两端?
### **当前架构(错误的)**
```
┌─────────────┐
│ Core │ ← gRPC 服务端(core/grpc_service.go
│ (库) │ 但没有人启动它!
└─────────────┘
│ gRPC 调用(127.0.0.1:50051
┌─────────────┐
│ Ctr │ ← gRPC 客户端(core/client/core_client.go
│ (调度中心) │ 尝试连接但会失败
└─────────────┘
```
### **正确的架构**
```
┌─────────────────────────────────┐
│ APIServer │
│ (internal/api/server.go) │
│ │
│ ┌───────────┐ ┌────────────┐ │
│ │ Ctr │ │ GRPCServer │ │
│ │(调度中心) │ │ (服务端) │ │
│ │ │ │ │ │
│ │ ┌───────┐ │ │ ┌────────┐ │ │
│ │ │Core │ │ │ │Core │ │ │
│ │ │Client │ │ │ │Service │ │ │
│ │ │(客户端)│ │ │ │(服务端)│ │ │
│ │ └───────┘ │ │ └────────┘ │ │
│ └───────────┘ └────────────┘ │
└─────────────────────────────────┘
↑ ↑
│ │
└──────┬─────────┘
127.0.0.1:50051
┌─────────────┐
│ Core │ ← 作为独立进程运行
│ (可选项) │ 或通过库集成
└─────────────┘
```
**关键点**:
1. ✅ Ctr 和 gRPC Server 都在 APIServer 内部
2. ✅ Ctr 的 Core Client 连接到 gRPC Server
3. ✅ gRPC Server 使用 `core/grpc_service.go` 的实现
4. ✅ Core 可以作为库(集成到进程内)或独立进程
---
## 💡 两种可行的架构方案
### **方案 A: 进程内集成(推荐)**
**特点**: Core 作为库集成到 meshray 进程中
```go
// internal/api/server.go
type APIServer struct {
engine *gin.Engine
config *config.Config
logger *zap.Logger
// Ctr 层
ctrClient *ctr.Ctr
// gRPC 服务器
grpcServer *grpc.Server
coreInst *core.Core // Core 实例(库)
}
func (s *APIServer) Start() error {
// 1. 创建 Core 实例(作为库)
s.coreInst = core.NewCore(s.logger)
// 2. 创建 gRPC 服务器
lis, err := net.Listen("tcp", ":50051")
if err != nil {
panic(fmt.Sprintf("无法监听 50051 端口:%v", err))
}
s.grpcServer = grpc.NewServer()
// 3. 注册 Core 服务(使用 core/grpc_service.go
coreService := core.NewCoreServiceServer(s.coreInst, s.logger)
core.RegisterCoreService(s.grpcServer, coreService)
// 4. 启动 gRPC 服务器
go func() {
s.logger.Info("启动 gRPC 服务器", zap.Int("port", 50051))
if err := s.grpcServer.Serve(lis); err != nil {
s.logger.Error("gRPC 服务器错误", zap.Error(err))
}
}()
// 5. 创建 Ctr(会自动连接 127.0.0.1:50051
s.ctrClient, err = ctr.NewCtr("default", 1, &ctr.CtrConfig{GRPCPort: 50051}, s.logger)
if err != nil {
panic(fmt.Sprintf("初始化 ctr 失败:%v", err))
}
// 6. 启动 HTTP 服务器
return s.engine.Run(":8080")
}
```
**优点**:
- ✅ 简单直接,无需额外进程
- ✅ 部署方便(单个二进制文件)
- ✅ 通信高效(进程内调用)
**缺点**:
- ❌ Core 和 API 耦合在同一进程
---
### **方案 B: 独立 Core 进程(微服务)**
**特点**: Core 作为独立进程运行
```bash
# 启动 Core 服务
./meshray-core --grpc-port=50051 &
# 启动 API 服务器
./meshray-api serve
```
**优点**:
- ✅ 完全解耦
- ✅ 可以独立扩展
- ✅ 符合微服务架构
**缺点**:
- ❌ 部署复杂(需要管理两个进程)
- ❌ 需要额外的进程监控
---
## 🎯 推荐方案:进程内集成(方案 A)
### **理由**
1. ✅ 符合当前项目结构(Core 在 `core/` 目录作为库)
2. ✅ 部署简单(用户只需运行一个命令)
3. ✅ 性能更好(无网络开销)
4. ✅ 调试方便(单进程日志)
---
## 📝 详细修复步骤
### **步骤 1: 修改 internal/api/server.go**
```go
package api
import (
"context"
"fmt"
"net"
"time"
"git.zkcoi.com/zkcoi/meshray/core"
"git.zkcoi.com/zkcoi/meshray/internal/ctr"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"google.golang.org/grpc"
)
type APIServer struct {
engine *gin.Engine
config *config.Config
logger *zap.Logger
store *store.Store
// Ctr 层
ctrClient *ctr.Ctr
// gRPC 服务器
grpcServer *grpc.Server
coreInst *core.Core
}
func NewAPIServer(cfg *config.Config) (*APIServer, error) {
// ... 现有代码 ...
return &APIServer{
engine: engine,
config: cfg,
logger: logger,
store: store,
// ctrClient 和 grpcServer 在 Start 中初始化
}, nil
}
func (s *APIServer) Start() error {
s.logger.Info("启动 MeshRay 服务器",
zap.String("mode", s.config.Server.Mode),
zap.Int("http_port", s.config.Server.Port))
// ========== P1: 启动 gRPC 服务器(为 Core 提供服务)==========
if err := s.startGRPCServer(); err != nil {
return fmt.Errorf("启动 gRPC 服务器失败:%w", err)
}
// ========== P2: 初始化 Ctr 并注入到 Service 层 ==========
var err error
s.ctrClient, err = ctr.NewCtr("default", 1, &ctr.CtrConfig{GRPCPort: 50051}, s.logger)
if err != nil {
s.logger.Error("初始化 meshray-ctr 失败", zap.Error(err))
panic(fmt.Sprintf("初始化 ctr 失败:%v", err))
}
// ... 后续 Service 层初始化 ...
// ========== P3: 启动 HTTP 服务器 ==========
addr := fmt.Sprintf(":%d", s.config.Server.Port)
if err := s.engine.Run(addr); err != nil {
return fmt.Errorf("启动 HTTP 服务器失败:%w", err)
}
return nil
}
// startGRPCServer 启动 gRPC 服务器(为 Core 提供服务)
func (s *APIServer) startGRPCServer() error {
s.logger.Info("正在启动 gRPC 服务器",
zap.Int("port", 50051))
// 1. 创建 Core 实例(作为库)
s.coreInst = core.NewCore(s.logger)
// 2. 创建 gRPC 服务器
lis, err := net.Listen("tcp", ":50051")
if err != nil {
return fmt.Errorf("无法监听 50051 端口:%w", err)
}
s.grpcServer = grpc.NewServer()
// 3. 注册 Core 服务(使用 core/grpc_service.go
coreService := core.NewCoreServiceServer(s.coreInst, s.logger)
core.RegisterCoreService(s.grpcServer, coreService)
// 4. 在后台启动 gRPC 服务器
go func() {
s.logger.Info("gRPC 服务器已启动",
zap.Int("port", 50051),
zap.String("service", "CoreService"))
if err := s.grpcServer.Serve(lis); err != nil {
s.logger.Error("gRPC 服务器错误", zap.Error(err))
}
}()
// 5. 等待 gRPC 服务器就绪(最多 3 秒)
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
conn, err := grpc.DialContext(ctx, "127.0.0.1:50051", grpc.WithInsecure())
if err != nil {
return fmt.Errorf("gRPC 服务器未就绪:%w", err)
}
conn.Close()
s.logger.Info("gRPC 服务器验证成功")
return nil
}
// Stop 停止服务器
func (s *APIServer) Stop() error {
s.logger.Info("正在停止 MeshRay 服务器...")
// 1. 停止 Ctr
if s.ctrClient != nil {
if err := s.ctrClient.Stop(); err != nil {
s.logger.Error("停止 Ctr 失败", zap.Error(err))
}
}
// 2. 停止 gRPC 服务器
if s.grpcServer != nil {
s.grpcServer.GracefulStop()
}
// 3. 停止 Core 实例
if s.coreInst != nil {
// TODO: Core 实例清理
}
s.logger.Info("MeshRay 服务器已停止")
return nil
}
```
---
### **步骤 2: 验证修复**
```bash
# 编译项目
cd e:\Project\MeshRay
go build -o meshray.exe
# 运行测试
./meshray.exe serve
# 预期输出:
# [INFO] 正在启动 gRPC 服务器 port=50051
# [INFO] gRPC 服务器已启动 port=50051 service=CoreService
# [INFO] gRPC 服务器验证成功
# [INFO] 启动 MeshRay 服务器 mode=release http_port=8080
```
---
### **步骤 3: 删除未使用文件**
```bash
# 删除未使用的文件
rm internal/ctr/wg_manager.go
rm internal/ctr/wg_go_process.go
rm core/pool/connpool.go
rm pkg/meshseed/meshseed.go
# 保留 watchdog.go(标记为未来功能)
# 在 internal/ctr/watchdog.go 顶部添加注释:
// ⏳ TODO: 启用 Watchdog 监控功能
```
---
### **步骤 4: 注入 SystemConfigService**
```go
// internal/api/server.go:178 后添加
// 初始化 SystemConfigService
s.systemConfigService = service.NewSystemConfigService(s.store, s.logger)
```
---
### **步骤 5: 清理未使用常量/函数**
编辑以下文件,删除未使用的定义:
1. `internal/ctr/types.go:25` - 删除 `ErrCodeWGModeUnavailable`
2. `internal/service/network.go:208` - 删除 `generateNetworkSecret`
3. `internal/ctr/wg_detect.go:154` - 删除 `GetRecommendedWGMode`
---
## 📊 修复后的架构
```
┌─────────────────────────────────────┐
│ APIServer │
│ │
│ ┌──────────────────────────────┐ │
│ │ gRPC Server (:50051) │ │
│ │ ┌────────────────────────┐ │ │
│ │ │ CoreServiceServer │ │ │
│ │ │ - CreateEngine │ │ │
│ │ │ - Start │ │ │
│ │ │ - Stop │ │ │
│ │ │ - GetStatus │ │ │
│ │ └────────────────────────┘ │ │
│ └──────────────────────────────┘ │
│ ↑ │
│ │ gRPC 调用 │
│ ↓ │
│ ┌──────────────────────────────┐ │
│ │ Ctr (调度中心) │ │
│ │ ┌────────────────────────┐ │ │
│ │ │ CoreClient │ │ │
│ │ │ - 连接到 127.0.0.1:50051│ │ │
│ │ └────────────────────────┘ │ │
│ └──────────────────────────────┘ │
│ │
│ ┌──────────────────────────────┐ │
│ │ WGManager │ │
│ │ - tunDevice 引用 │ │
│ │ - wgDevice 引用 │ │
│ │ - 跨平台支持 │ │
│ └──────────────────────────────┘ │
└─────────────────────────────────────┘
│ HTTP/REST API
┌─────────────────────────────────────┐
│ Web UI (Vue 3) │
└─────────────────────────────────────┘
```
---
## 📋 验收清单
### **核心功能**
- ✅ gRPC 服务器成功启动在 50051 端口
- ✅ CoreClient 成功连接到 gRPC 服务器
-`CreateEngine` gRPC 调用返回成功
-`Start` gRPC 调用返回成功
- ✅ 日志显示完整的启动流程
### **代码清理**
- ✅ 删除 4 个未使用文件
- ✅ 删除 4 个未使用常量/函数
- ✅ SystemConfigService 正确注入
### **文档完善**
- ✅ 5 个预留模型都有注释
- ✅ 架构文档反映真实实现
---
## 🎯 总结
### **问题根源**
- ❌ Ctr 只有 Core 客户端,没有服务端
-`core/grpc_service.go` 的实现无处可用
- ❌ CoreClient 连接 127.0.0.1:50051 会失败
### **修复方案**
- ✅ 在 APIServer 中启动 gRPC 服务器
- ✅ 使用 `core/grpc_service.go` 的实现
- ✅ Core 作为库集成到进程中
### **技术价值**
- ✅ 解决了核心架构问题
- ✅ 使 Core 层功能真正可用
- ✅ 统一了进程内通信
- ✅ 简化了部署流程
---
**修复完成时间**: 预计 2-3 小时
**状态**: 📋 **等待实施**
**优先级**: 🔴 **P0 - 必须立即修复**