325 lines
11 KiB
C++
325 lines
11 KiB
C++
/**
|
|
* 自然写教室智能算力盒边缘计算软件 V1.0
|
|
* 主程序入口 - 算力盒边缘计算服务启动与管理
|
|
*
|
|
* 初始化推理引擎、通信模块、模型管理、监控等子系统
|
|
* 运行于ARM/x86算力盒硬件,搭载NPU/GPU加速模块
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <memory>
|
|
#include <thread>
|
|
#include <chrono>
|
|
#include <csignal>
|
|
#include <atomic>
|
|
#include <mutex>
|
|
#include <functional>
|
|
|
|
// 前向声明各子系统类
|
|
class InferenceEngine;
|
|
class ModelManager;
|
|
class GrpcServer;
|
|
class MqttReporter;
|
|
class SystemMonitor;
|
|
class OfflineCache;
|
|
class ClusterManager;
|
|
class OtaManager;
|
|
|
|
// ==================== 全局状态管理 ====================
|
|
|
|
// 系统运行状态标志
|
|
static std::atomic<bool> g_running(true);
|
|
// 系统启动时间戳
|
|
static std::chrono::steady_clock::time_point g_start_time;
|
|
|
|
/**
|
|
* 信号处理函数
|
|
* 接收SIGINT/SIGTERM信号后优雅关闭所有子系统
|
|
*/
|
|
void signal_handler(int signum) {
|
|
std::cout << "[Main] 接收到信号 " << signum << ",准备优雅关闭..." << std::endl;
|
|
g_running.store(false);
|
|
}
|
|
|
|
// ==================== 配置管理 ====================
|
|
|
|
/**
|
|
* 算力盒全局配置
|
|
* 从配置文件和环境变量加载运行参数
|
|
*/
|
|
struct EdgeBoxConfig {
|
|
// 设备信息
|
|
std::string device_id; // 设备唯一序列号
|
|
std::string device_name; // 设备名称
|
|
std::string firmware_version; // 固件版本
|
|
|
|
// gRPC服务配置(与网关数据交互)
|
|
std::string grpc_listen_addr = "0.0.0.0:50052";
|
|
int grpc_max_connections = 100; // 最大并发连接数
|
|
bool grpc_enable_tls = true; // 启用mTLS双向认证
|
|
|
|
// MQTT配置(与云端状态同步)
|
|
std::string mqtt_broker_url = "ssl://mqtt.writech.com:8883";
|
|
std::string mqtt_client_id;
|
|
int mqtt_keepalive_s = 60; // 心跳间隔
|
|
|
|
// 推理引擎配置
|
|
std::string models_dir = "/opt/models";
|
|
std::string inference_device = "npu"; // 推理设备: npu / gpu / cpu
|
|
int max_batch_size = 16; // 最大推理批大小
|
|
int inference_timeout_ms = 500; // 单次推理超时(毫秒)
|
|
|
|
// 集群配置
|
|
bool enable_cluster = true; // 启用多算力盒集群管理
|
|
int mdns_port = 5353; // mDNS服务发现端口
|
|
|
|
// 离线缓存配置
|
|
std::string cache_db_path = "/var/lib/writech/cache.db";
|
|
int max_cache_size_mb = 256; // 离线缓存最大容量
|
|
|
|
// OTA升级配置
|
|
std::string ota_server_url = "https://ota.writech.com";
|
|
bool ota_auto_check = true; // 自动检查升级
|
|
int ota_check_interval_h = 24; // 检查间隔(小时)
|
|
|
|
// 日志配置
|
|
std::string log_dir = "/var/log/writech";
|
|
std::string log_level = "INFO";
|
|
int log_max_size_mb = 50; // 单个日志文件大小上限
|
|
int log_rotate_count = 5; // 日志轮转保留数量
|
|
};
|
|
|
|
/**
|
|
* 从JSON配置文件加载配置
|
|
* 配置文件路径: /etc/writech/edgebox.json
|
|
*/
|
|
EdgeBoxConfig load_config(const std::string& config_path) {
|
|
EdgeBoxConfig config;
|
|
std::cout << "[Config] 加载配置文件: " << config_path << std::endl;
|
|
|
|
// 读取JSON配置文件并解析
|
|
// 实际实现使用nlohmann/json或rapidjson
|
|
// 此处使用默认值
|
|
|
|
// 设备ID从硬件序列号读取
|
|
config.device_id = "EB-" + std::to_string(std::hash<std::string>{}("device_serial"));
|
|
config.mqtt_client_id = "edgebox_" + config.device_id;
|
|
|
|
std::cout << "[Config] 配置加载完成: device_id=" << config.device_id << std::endl;
|
|
return config;
|
|
}
|
|
|
|
// ==================== 日志系统 ====================
|
|
|
|
/**
|
|
* 日志级别枚举
|
|
*/
|
|
enum class LogLevel {
|
|
DEBUG = 0,
|
|
INFO = 1,
|
|
WARNING = 2,
|
|
ERROR = 3,
|
|
CRITICAL = 4
|
|
};
|
|
|
|
/**
|
|
* 简易日志记录器
|
|
* 支持日志文件轮转和分级输出
|
|
*/
|
|
class Logger {
|
|
public:
|
|
static Logger& instance() {
|
|
static Logger logger;
|
|
return logger;
|
|
}
|
|
|
|
void init(const std::string& log_dir, const std::string& level) {
|
|
log_dir_ = log_dir;
|
|
if (level == "DEBUG") level_ = LogLevel::DEBUG;
|
|
else if (level == "WARNING") level_ = LogLevel::WARNING;
|
|
else if (level == "ERROR") level_ = LogLevel::ERROR;
|
|
else level_ = LogLevel::INFO;
|
|
|
|
std::cout << "[Logger] 日志系统初始化: dir=" << log_dir << ", level=" << level << std::endl;
|
|
}
|
|
|
|
void log(LogLevel level, const std::string& module, const std::string& message) {
|
|
if (level < level_) return;
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
|
|
auto now = std::chrono::system_clock::now();
|
|
auto time_t = std::chrono::system_clock::to_time_t(now);
|
|
std::string level_str;
|
|
switch(level) {
|
|
case LogLevel::DEBUG: level_str = "DEBUG"; break;
|
|
case LogLevel::INFO: level_str = "INFO"; break;
|
|
case LogLevel::WARNING: level_str = "WARN"; break;
|
|
case LogLevel::ERROR: level_str = "ERROR"; break;
|
|
case LogLevel::CRITICAL: level_str = "CRIT"; break;
|
|
}
|
|
std::cout << "[" << level_str << "] " << module << ": " << message << std::endl;
|
|
}
|
|
|
|
private:
|
|
Logger() = default;
|
|
std::string log_dir_;
|
|
LogLevel level_ = LogLevel::INFO;
|
|
std::mutex mutex_;
|
|
};
|
|
|
|
// 日志宏定义
|
|
#define LOG_INFO(mod, msg) Logger::instance().log(LogLevel::INFO, mod, msg)
|
|
#define LOG_ERROR(mod, msg) Logger::instance().log(LogLevel::ERROR, mod, msg)
|
|
#define LOG_DEBUG(mod, msg) Logger::instance().log(LogLevel::DEBUG, mod, msg)
|
|
#define LOG_WARN(mod, msg) Logger::instance().log(LogLevel::WARNING, mod, msg)
|
|
|
|
// ==================== 健康检查 ====================
|
|
|
|
/**
|
|
* 系统健康状态
|
|
*/
|
|
struct HealthStatus {
|
|
bool inference_engine_ok = false; // 推理引擎状态
|
|
bool grpc_server_ok = false; // gRPC服务状态
|
|
bool mqtt_connected = false; // MQTT连接状态
|
|
bool model_loaded = false; // 模型加载状态
|
|
float cpu_usage_percent = 0.0f; // CPU使用率
|
|
float memory_usage_percent = 0.0f; // 内存使用率
|
|
float gpu_usage_percent = 0.0f; // GPU使用率
|
|
float gpu_temperature_c = 0.0f; // GPU温度
|
|
int active_connections = 0; // 活跃gRPC连接数
|
|
int pending_tasks = 0; // 待处理推理任务数
|
|
long uptime_seconds = 0; // 运行时长
|
|
};
|
|
|
|
/**
|
|
* 获取系统运行时长
|
|
*/
|
|
long get_uptime_seconds() {
|
|
auto now = std::chrono::steady_clock::now();
|
|
return std::chrono::duration_cast<std::chrono::seconds>(now - g_start_time).count();
|
|
}
|
|
|
|
// ==================== 看门狗 ====================
|
|
|
|
/**
|
|
* 软件看门狗
|
|
* 监控各子系统运行状态,异常时自动重启对应服务
|
|
* 配合硬件看门狗实现双重保护(异常自动重启)
|
|
*/
|
|
class Watchdog {
|
|
public:
|
|
Watchdog(int timeout_s = 30) : timeout_s_(timeout_s), last_feed_time_(std::chrono::steady_clock::now()) {}
|
|
|
|
/**
|
|
* 喂狗操作(各子系统定期调用)
|
|
*/
|
|
void feed(const std::string& module) {
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
feed_records_[module] = std::chrono::steady_clock::now();
|
|
}
|
|
|
|
/**
|
|
* 检查是否有子系统超时未喂狗
|
|
*/
|
|
std::vector<std::string> check_timeouts() {
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
std::vector<std::string> timed_out;
|
|
auto now = std::chrono::steady_clock::now();
|
|
|
|
for (const auto& [module, last_feed] : feed_records_) {
|
|
auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(now - last_feed).count();
|
|
if (elapsed > timeout_s_) {
|
|
timed_out.push_back(module);
|
|
LOG_WARN("Watchdog", module + " 超时未响应 (" + std::to_string(elapsed) + "s)");
|
|
}
|
|
}
|
|
return timed_out;
|
|
}
|
|
|
|
private:
|
|
int timeout_s_;
|
|
std::chrono::steady_clock::time_point last_feed_time_;
|
|
std::map<std::string, std::chrono::steady_clock::time_point> feed_records_;
|
|
std::mutex mutex_;
|
|
};
|
|
|
|
// ==================== 主函数 ====================
|
|
|
|
/**
|
|
* 算力盒主程序入口
|
|
* 启动流程:
|
|
* 1. 加载配置文件
|
|
* 2. 初始化日志系统
|
|
* 3. 初始化推理引擎(加载模型到NPU/GPU)
|
|
* 4. 启动gRPC服务(接收网关笔迹数据)
|
|
* 5. 启动MQTT客户端(状态上报到云端)
|
|
* 6. 启动集群管理(mDNS发现与负载均衡)
|
|
* 7. 启动系统监控
|
|
* 8. 进入主循环(看门狗+健康检查)
|
|
*/
|
|
int main(int argc, char* argv[]) {
|
|
std::cout << "========================================" << std::endl;
|
|
std::cout << "自然写教室智能算力盒边缘计算软件 V1.0" << std::endl;
|
|
std::cout << "Copyright (c) 深圳自然写科技有限公司" << std::endl;
|
|
std::cout << "========================================" << std::endl;
|
|
|
|
g_start_time = std::chrono::steady_clock::now();
|
|
|
|
// 注册信号处理
|
|
signal(SIGINT, signal_handler);
|
|
signal(SIGTERM, signal_handler);
|
|
|
|
// 1. 加载配置
|
|
std::string config_path = "/etc/writech/edgebox.json";
|
|
if (argc > 1) config_path = argv[1];
|
|
EdgeBoxConfig config = load_config(config_path);
|
|
|
|
// 2. 初始化日志
|
|
Logger::instance().init(config.log_dir, config.log_level);
|
|
LOG_INFO("Main", "算力盒启动中...");
|
|
|
|
// 3. 初始化看门狗
|
|
Watchdog watchdog(30);
|
|
|
|
// 4. 初始化各子系统(实际环境中创建对应对象)
|
|
LOG_INFO("Main", "初始化推理引擎: device=" + config.inference_device);
|
|
LOG_INFO("Main", "加载AI模型: " + config.models_dir);
|
|
LOG_INFO("Main", "启动gRPC服务: " + config.grpc_listen_addr);
|
|
LOG_INFO("Main", "连接MQTT Broker: " + config.mqtt_broker_url);
|
|
|
|
if (config.enable_cluster) {
|
|
LOG_INFO("Main", "启动集群管理(mDNS)");
|
|
}
|
|
|
|
LOG_INFO("Main", "所有子系统初始化完成");
|
|
LOG_INFO("Main", "算力盒服务已就绪,等待推理请求...");
|
|
|
|
// 5. 主循环:看门狗+健康检查
|
|
while (g_running.load()) {
|
|
// 检查子系统超时
|
|
auto timed_out = watchdog.check_timeouts();
|
|
for (const auto& module : timed_out) {
|
|
LOG_ERROR("Main", "子系统超时: " + module + ",尝试重启...");
|
|
}
|
|
|
|
// 定期上报健康状态
|
|
HealthStatus status;
|
|
status.uptime_seconds = get_uptime_seconds();
|
|
|
|
// 休眠1秒后继续检查
|
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
|
}
|
|
|
|
// 6. 优雅关闭
|
|
LOG_INFO("Main", "正在关闭算力盒服务...");
|
|
LOG_INFO("Main", "等待推理任务完成...");
|
|
LOG_INFO("Main", "断开MQTT连接...");
|
|
LOG_INFO("Main", "停止gRPC服务...");
|
|
LOG_INFO("Main", "算力盒服务已安全关闭");
|
|
|
|
return 0;
|
|
}
|