删除废弃的API和架构文档
This commit is contained in:
331
docs/operations/SECURITY.md
Normal file
331
docs/operations/SECURITY.md
Normal file
@@ -0,0 +1,331 @@
|
||||
# 安全指南
|
||||
|
||||
## 概述
|
||||
|
||||
本文档为宁夏智慧养殖监管平台提供全面的安全指导,包括安全漏洞报告、安全最佳实践、以及系统安全配置建议。
|
||||
|
||||
## 漏洞报告
|
||||
|
||||
### 报告渠道
|
||||
|
||||
**如果您发现安全漏洞,请不要在公开渠道(如 GitHub Issues)报告。**
|
||||
|
||||
请通过以下私密渠道报告:
|
||||
- 📧 **安全邮箱**: security@nxxmdata.com
|
||||
- 🔒 **加密通信**: 支持 PGP 加密
|
||||
|
||||
### 报告内容
|
||||
|
||||
请在安全报告中包含以下信息:
|
||||
|
||||
1. **漏洞类型** (SQL注入、XSS、CSRF等)
|
||||
2. **影响范围** (影响的组件、用户类型、严重程度)
|
||||
3. **复现步骤** (详细的复现步骤)
|
||||
4. **概念验证** (代码示例或截图)
|
||||
5. **建议修复方案** (如果有修复建议请提供)
|
||||
|
||||
### 响应承诺
|
||||
|
||||
| 严重程度 | 确认时间 | 修复时间 |
|
||||
|---------|---------|---------|
|
||||
| 严重 | 4 小时 | 24-48 小时 |
|
||||
| 高 | 24 小时 | 3-7 天 |
|
||||
| 中 | 72 小时 | 1-4 周 |
|
||||
| 低 | 1 周 | 1-3 个月 |
|
||||
|
||||
## 认证与授权
|
||||
|
||||
### JWT Token 安全
|
||||
|
||||
```javascript
|
||||
// 安全的 JWT 配置
|
||||
const jwtConfig = {
|
||||
secret: process.env.JWT_SECRET, // 至少 64 字符的强密钥
|
||||
algorithm: 'HS256',
|
||||
expiresIn: '24h',
|
||||
issuer: 'nxxmdata-api',
|
||||
audience: 'nxxmdata-client'
|
||||
};
|
||||
```
|
||||
|
||||
### 密码安全
|
||||
|
||||
- 最低长度 8 位
|
||||
- 必须包含大小写字母、数字和特殊字符
|
||||
- 使用 bcrypt 加密存储
|
||||
- 盐值强度至少为 12
|
||||
|
||||
### 权限控制
|
||||
|
||||
实施基于角色的访问控制 (RBAC):
|
||||
- **admin**: 系统管理员权限
|
||||
- **manager**: 养殖场管理员权限
|
||||
- **operator**: 操作员权限
|
||||
- **viewer**: 只读权限
|
||||
|
||||
## 数据安全
|
||||
|
||||
### 输入验证
|
||||
|
||||
所有用户输入必须经过严格验证:
|
||||
|
||||
```javascript
|
||||
// SQL 注入防护 - 使用参数化查询
|
||||
const getFarms = async (status) => {
|
||||
return await Farm.findAll({
|
||||
where: { status } // Sequelize 自动参数化
|
||||
});
|
||||
};
|
||||
|
||||
// XSS 防护 - 输入转义
|
||||
const validator = require('validator');
|
||||
const sanitizedInput = validator.escape(userInput);
|
||||
```
|
||||
|
||||
### 数据加密
|
||||
|
||||
- 敏感数据字段加密存储
|
||||
- 数据库连接使用 SSL/TLS
|
||||
- 文件传输使用 HTTPS
|
||||
|
||||
## 网络安全
|
||||
|
||||
### HTTPS 配置
|
||||
|
||||
强制使用 HTTPS:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name nxxmdata.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
# 其他 SSL 配置...
|
||||
}
|
||||
```
|
||||
|
||||
### 安全头配置
|
||||
|
||||
```nginx
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header Strict-Transport-Security "max-age=63072000";
|
||||
add_header Content-Security-Policy "default-src 'self'";
|
||||
```
|
||||
|
||||
### 速率限制
|
||||
|
||||
```javascript
|
||||
const rateLimit = require('express-rate-limit');
|
||||
|
||||
// API 速率限制
|
||||
const apiLimiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 分钟
|
||||
max: 100, // 每 IP 最多 100 请求
|
||||
message: 'Too many requests, please try again later'
|
||||
});
|
||||
|
||||
// 登录限制更严格
|
||||
const loginLimiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000,
|
||||
max: 5 // 每 IP 最多 5 次登录尝试
|
||||
});
|
||||
```
|
||||
|
||||
## 部署安全
|
||||
|
||||
### Docker 安全
|
||||
|
||||
```dockerfile
|
||||
# 使用非特权用户
|
||||
FROM node:18-alpine
|
||||
RUN adduser -S node -u 1001
|
||||
USER node
|
||||
|
||||
# 只读文件系统
|
||||
# docker run --read-only --tmpfs /tmp myapp
|
||||
```
|
||||
|
||||
### 环境变量
|
||||
|
||||
```bash
|
||||
# 使用强密钥
|
||||
JWT_SECRET=随机生成的64字符密钥
|
||||
DB_PASSWORD=强密码
|
||||
ENCRYPTION_KEY=32字节hex密钥
|
||||
|
||||
# 生产环境配置
|
||||
NODE_ENV=production
|
||||
LOG_LEVEL=warn
|
||||
```
|
||||
|
||||
### 服务器加固
|
||||
|
||||
```bash
|
||||
# 防火墙配置
|
||||
ufw default deny incoming
|
||||
ufw default allow outgoing
|
||||
ufw allow ssh
|
||||
ufw allow 80/tcp
|
||||
ufw allow 443/tcp
|
||||
ufw enable
|
||||
|
||||
# SSH 安全
|
||||
sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
|
||||
sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
|
||||
```
|
||||
|
||||
## 依赖安全
|
||||
|
||||
### 定期审计
|
||||
|
||||
```bash
|
||||
# 检查已知漏洞
|
||||
npm audit
|
||||
|
||||
# 修复漏洞
|
||||
npm audit fix
|
||||
|
||||
# 更新依赖
|
||||
npm update
|
||||
```
|
||||
|
||||
### 自动化扫描
|
||||
|
||||
在 CI/CD 流程中集成安全扫描:
|
||||
|
||||
```yaml
|
||||
# .github/workflows/security.yml
|
||||
name: Security Scan
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
security:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Run npm audit
|
||||
run: npm audit --audit-level high
|
||||
```
|
||||
|
||||
## 监控与日志
|
||||
|
||||
### 安全事件监控
|
||||
|
||||
```javascript
|
||||
// 记录安全相关事件
|
||||
const logSecurityEvent = (event, details) => {
|
||||
securityLogger.warn({
|
||||
event,
|
||||
timestamp: new Date().toISOString(),
|
||||
ip: details.ip,
|
||||
userAgent: details.userAgent,
|
||||
details
|
||||
});
|
||||
};
|
||||
|
||||
// 监控异常登录
|
||||
if (failedAttempts > 3) {
|
||||
logSecurityEvent('MULTIPLE_LOGIN_FAILURES', {
|
||||
ip: req.ip,
|
||||
attempts: failedAttempts
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 审计日志
|
||||
|
||||
- 记录所有敏感操作
|
||||
- 包含用户信息、时间戳、操作详情
|
||||
- 定期备份和分析日志
|
||||
|
||||
## 应急响应
|
||||
|
||||
### 安全事件处理流程
|
||||
|
||||
1. **发现阶段**: 监控系统检测异常
|
||||
2. **评估阶段**: 确定影响范围和严重程度
|
||||
3. **隔离阶段**: 隔离受影响的系统
|
||||
4. **修复阶段**: 修复漏洞或问题
|
||||
5. **恢复阶段**: 恢复正常服务
|
||||
6. **总结阶段**: 分析原因和改进措施
|
||||
|
||||
### 紧急联系方式
|
||||
|
||||
- **安全团队**: security@nxxmdata.com
|
||||
- **技术支持**: support@nxxmdata.com
|
||||
- **紧急热线**: 400-xxx-xxxx
|
||||
|
||||
## 安全培训
|
||||
|
||||
### 开发人员安全意识
|
||||
|
||||
- 定期进行安全培训
|
||||
- 了解 OWASP Top 10
|
||||
- 掌握安全编码实践
|
||||
- 参与安全代码审查
|
||||
|
||||
### 安全开发生命周期
|
||||
|
||||
1. **需求阶段**: 识别安全需求
|
||||
2. **设计阶段**: 威胁建模分析
|
||||
3. **开发阶段**: 安全编码实践
|
||||
4. **测试阶段**: 安全测试和扫描
|
||||
5. **部署阶段**: 安全配置检查
|
||||
6. **维护阶段**: 持续监控和更新
|
||||
|
||||
## 合规要求
|
||||
|
||||
### 数据保护
|
||||
|
||||
- 遵循数据保护法规
|
||||
- 实施数据分类管理
|
||||
- 提供数据删除机制
|
||||
- 限制数据访问权限
|
||||
|
||||
### 审计要求
|
||||
|
||||
- 保留详细的操作日志
|
||||
- 定期进行安全审计
|
||||
- 配合第三方安全评估
|
||||
- 及时报告安全事件
|
||||
|
||||
## 安全检查清单
|
||||
|
||||
### 开发阶段
|
||||
- [ ] 输入验证和清理
|
||||
- [ ] 参数化查询
|
||||
- [ ] 错误处理不泄露信息
|
||||
- [ ] 使用安全的加密算法
|
||||
- [ ] 实施权限检查
|
||||
|
||||
### 部署阶段
|
||||
- [ ] HTTPS 配置正确
|
||||
- [ ] 安全头配置完整
|
||||
- [ ] 防火墙规则适当
|
||||
- [ ] 服务器已加固
|
||||
- [ ] 监控系统运行
|
||||
|
||||
### 运维阶段
|
||||
- [ ] 定期安全扫描
|
||||
- [ ] 及时更新补丁
|
||||
- [ ] 监控异常活动
|
||||
- [ ] 备份关键数据
|
||||
- [ ] 测试应急预案
|
||||
|
||||
## 联系我们
|
||||
|
||||
如有安全相关问题,请联系:
|
||||
|
||||
- **安全邮箱**: security@nxxmdata.com
|
||||
- **技术支持**: support@nxxmdata.com
|
||||
- **项目地址**: https://github.com/your-org/nxxmdata
|
||||
|
||||
---
|
||||
|
||||
*最后更新: 2025年1月*
|
||||
*请定期查看本文档的更新版本*
|
||||
795
docs/operations/TROUBLESHOOTING.md
Normal file
795
docs/operations/TROUBLESHOOTING.md
Normal file
@@ -0,0 +1,795 @@
|
||||
# 故障排除指南
|
||||
|
||||
## 概述
|
||||
|
||||
本文档提供宁夏智慧养殖监管平台常见问题的诊断和解决方案,帮助开发人员和运维人员快速定位和解决系统故障。
|
||||
|
||||
## 目录
|
||||
|
||||
- [环境相关问题](#环境相关问题)
|
||||
- [数据库问题](#数据库问题)
|
||||
- [API服务问题](#api服务问题)
|
||||
- [前端问题](#前端问题)
|
||||
- [性能问题](#性能问题)
|
||||
- [部署问题](#部署问题)
|
||||
- [日志分析](#日志分析)
|
||||
- [监控和诊断工具](#监控和诊断工具)
|
||||
|
||||
## 环境相关问题
|
||||
|
||||
### Node.js 版本问题
|
||||
|
||||
**问题症状:**
|
||||
```bash
|
||||
Error: The engine "node" is incompatible with this module
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
```bash
|
||||
# 检查当前 Node.js 版本
|
||||
node --version
|
||||
|
||||
# 要求版本: Node.js 18.0+
|
||||
# 升级 Node.js
|
||||
nvm install 18
|
||||
nvm use 18
|
||||
|
||||
# 或者使用官方安装包
|
||||
# https://nodejs.org/
|
||||
```
|
||||
|
||||
### npm 依赖安装失败
|
||||
|
||||
**问题症状:**
|
||||
```bash
|
||||
npm ERR! peer dep missing
|
||||
npm ERR! network timeout
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
```bash
|
||||
# 1. 清理缓存
|
||||
npm cache clean --force
|
||||
|
||||
# 2. 删除 node_modules 和 package-lock.json
|
||||
rm -rf node_modules package-lock.json
|
||||
|
||||
# 3. 重新安装
|
||||
npm install
|
||||
|
||||
# 4. 如果网络问题,使用国内镜像
|
||||
npm config set registry https://registry.npmmirror.com/
|
||||
|
||||
# 5. 使用 yarn 替代
|
||||
yarn install
|
||||
```
|
||||
|
||||
### 环境变量配置问题
|
||||
|
||||
**问题症状:**
|
||||
```bash
|
||||
Error: Missing required environment variable
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
```bash
|
||||
# 1. 检查 .env 文件是否存在
|
||||
ls -la .env
|
||||
|
||||
# 2. 复制示例配置文件
|
||||
cp .env.example .env
|
||||
|
||||
# 3. 编辑配置文件
|
||||
nano .env
|
||||
|
||||
# 4. 验证环境变量
|
||||
node -e "console.log(process.env.DB_HOST)"
|
||||
```
|
||||
|
||||
## 数据库问题
|
||||
|
||||
### 数据库连接失败
|
||||
|
||||
**问题症状:**
|
||||
```
|
||||
Error: connect ECONNREFUSED 127.0.0.1:3306
|
||||
SequelizeConnectionError: Access denied for user
|
||||
```
|
||||
|
||||
**诊断步骤:**
|
||||
```bash
|
||||
# 1. 检查 MySQL 服务状态
|
||||
# macOS
|
||||
brew services list | grep mysql
|
||||
|
||||
# Linux
|
||||
systemctl status mysql
|
||||
|
||||
# Windows
|
||||
net start mysql
|
||||
|
||||
# 2. 测试数据库连接
|
||||
mysql -u root -p -h localhost -P 3306
|
||||
|
||||
# 3. 检查端口占用
|
||||
lsof -i :3306
|
||||
netstat -an | grep 3306
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
```bash
|
||||
# 1. 启动 MySQL 服务
|
||||
# macOS
|
||||
brew services start mysql
|
||||
|
||||
# Linux
|
||||
sudo systemctl start mysql
|
||||
|
||||
# Windows
|
||||
net start mysql
|
||||
|
||||
# 2. 重置 MySQL 密码
|
||||
mysql -u root -p
|
||||
ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';
|
||||
FLUSH PRIVILEGES;
|
||||
|
||||
# 3. 创建数据库用户
|
||||
CREATE USER 'nxxmdata_user'@'localhost' IDENTIFIED BY 'password';
|
||||
GRANT ALL PRIVILEGES ON nxxmdata.* TO 'nxxmdata_user'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
```
|
||||
|
||||
### 数据库迁移失败
|
||||
|
||||
**问题症状:**
|
||||
```
|
||||
Migration failed: Table already exists
|
||||
Sequelize migration error
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
```bash
|
||||
# 1. 检查迁移状态
|
||||
cd backend
|
||||
npm run db:status
|
||||
|
||||
# 2. 回滚迁移
|
||||
npm run db:rollback
|
||||
|
||||
# 3. 强制重置数据库(谨慎使用)
|
||||
mysql -u root -p
|
||||
DROP DATABASE nxxmdata;
|
||||
CREATE DATABASE nxxmdata CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
# 4. 重新运行迁移
|
||||
npm run db:migrate
|
||||
```
|
||||
|
||||
### 数据不一致问题
|
||||
|
||||
**问题症状:**
|
||||
```
|
||||
Foreign key constraint fails
|
||||
Data validation errors
|
||||
```
|
||||
|
||||
**诊断脚本:**
|
||||
```bash
|
||||
cd backend
|
||||
|
||||
# 检查外键约束
|
||||
node check-orphaned-foreign-keys.js
|
||||
|
||||
# 检查数据完整性
|
||||
node verify-data.js
|
||||
|
||||
# 检查表结构
|
||||
node check-table-structure.js
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
```bash
|
||||
# 修复孤立外键
|
||||
node fix-orphaned-foreign-keys.js
|
||||
|
||||
# 重新排序主键
|
||||
node reorder-primary-keys.js
|
||||
|
||||
# 验证修复结果
|
||||
node verify-data.js
|
||||
```
|
||||
|
||||
## API服务问题
|
||||
|
||||
### 服务启动失败
|
||||
|
||||
**问题症状:**
|
||||
```bash
|
||||
Error: listen EADDRINUSE :::5350
|
||||
Cannot find module
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
```bash
|
||||
# 1. 检查端口占用
|
||||
lsof -i :5350
|
||||
netstat -tulpn | grep 5350
|
||||
|
||||
# 2. 杀死占用进程
|
||||
kill -9 <PID>
|
||||
|
||||
# 3. 更换端口
|
||||
export PORT=5351
|
||||
npm run dev
|
||||
|
||||
# 4. 检查模块依赖
|
||||
npm install
|
||||
npm audit fix
|
||||
```
|
||||
|
||||
### JWT Token 问题
|
||||
|
||||
**问题症状:**
|
||||
```
|
||||
401 Unauthorized
|
||||
Token expired
|
||||
Invalid token
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
```bash
|
||||
# 1. 检查 JWT 密钥配置
|
||||
echo $JWT_SECRET
|
||||
|
||||
# 2. 验证 Token 格式
|
||||
node -e "console.log(require('jsonwebtoken').verify('YOUR_TOKEN', 'YOUR_SECRET'))"
|
||||
|
||||
# 3. 重新生成密钥
|
||||
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
|
||||
```
|
||||
|
||||
### API 响应慢
|
||||
|
||||
**问题症状:**
|
||||
```
|
||||
Response time > 5000ms
|
||||
Timeout errors
|
||||
```
|
||||
|
||||
**诊断工具:**
|
||||
```bash
|
||||
# 1. 检查数据库查询性能
|
||||
cd backend
|
||||
node utils/query-optimizer.js
|
||||
|
||||
# 2. 查看性能监控
|
||||
curl http://localhost:5350/api/performance/metrics
|
||||
|
||||
# 3. 分析慢查询日志
|
||||
tail -f logs/performance/database-YYYY-MM-DD.log
|
||||
```
|
||||
|
||||
**优化方案:**
|
||||
```javascript
|
||||
// 1. 添加数据库索引
|
||||
CREATE INDEX idx_farms_status ON farms(status);
|
||||
CREATE INDEX idx_devices_farm_id ON devices(farm_id);
|
||||
|
||||
// 2. 优化查询语句
|
||||
const farms = await Farm.findAll({
|
||||
attributes: ['id', 'name', 'status'], // 只查询需要的字段
|
||||
include: [{
|
||||
model: Device,
|
||||
attributes: ['id', 'status']
|
||||
}],
|
||||
limit: 10,
|
||||
offset: (page - 1) * 10
|
||||
});
|
||||
|
||||
// 3. 使用缓存
|
||||
const Redis = require('redis');
|
||||
const redis = Redis.createClient();
|
||||
```
|
||||
|
||||
## 前端问题
|
||||
|
||||
### 构建失败
|
||||
|
||||
**问题症状:**
|
||||
```bash
|
||||
Build failed with errors
|
||||
Module not found
|
||||
Syntax error in code
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
```bash
|
||||
# 1. 清理构建缓存
|
||||
cd admin-system/frontend
|
||||
rm -rf node_modules/.vite
|
||||
rm -rf dist
|
||||
|
||||
# 2. 检查依赖版本
|
||||
npm ls
|
||||
|
||||
# 3. 更新依赖
|
||||
npm update
|
||||
|
||||
# 4. 重新构建
|
||||
npm run build
|
||||
```
|
||||
|
||||
### 路由问题
|
||||
|
||||
**问题症状:**
|
||||
```
|
||||
404 Page not found
|
||||
Router navigation errors
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
```javascript
|
||||
// 1. 检查路由配置
|
||||
// router/routes.js
|
||||
export const routes = [
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/dashboard'
|
||||
},
|
||||
{
|
||||
path: '/farms',
|
||||
component: () => import('../views/Farms.vue')
|
||||
}
|
||||
];
|
||||
|
||||
// 2. 检查 Nginx 配置
|
||||
// location / {
|
||||
// try_files $uri $uri/ /index.html;
|
||||
// }
|
||||
```
|
||||
|
||||
### API 调用失败
|
||||
|
||||
**问题症状:**
|
||||
```
|
||||
CORS errors
|
||||
Network errors
|
||||
401/403 errors
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
```javascript
|
||||
// 1. 检查 API 基础 URL
|
||||
// config/env.js
|
||||
export const API_BASE_URL = process.env.VITE_API_BASE_URL || 'http://localhost:5350/api';
|
||||
|
||||
// 2. 添加请求拦截器
|
||||
axios.interceptors.request.use(
|
||||
config => {
|
||||
const token = localStorage.getItem('token');
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
error => Promise.reject(error)
|
||||
);
|
||||
|
||||
// 3. 处理响应错误
|
||||
axios.interceptors.response.use(
|
||||
response => response,
|
||||
error => {
|
||||
if (error.response?.status === 401) {
|
||||
// 清除 token,跳转到登录页
|
||||
localStorage.removeItem('token');
|
||||
router.push('/login');
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### 地图显示问题
|
||||
|
||||
**问题症状:**
|
||||
```
|
||||
百度地图加载失败
|
||||
地图空白
|
||||
坐标偏移
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
```javascript
|
||||
// 1. 检查 API 密钥
|
||||
console.log('百度地图 API Key:', process.env.VITE_BAIDU_MAP_API_KEY);
|
||||
|
||||
// 2. 验证域名白名单
|
||||
// 登录百度地图开放平台控制台检查 Referer 设置
|
||||
|
||||
// 3. 检查坐标系统
|
||||
// 确保使用 BD09 坐标系
|
||||
const point = new BMap.Point(106.26667, 38.46667);
|
||||
|
||||
// 4. 处理坐标转换
|
||||
// 如果数据是 WGS84 或 GCJ02,需要转换为 BD09
|
||||
```
|
||||
|
||||
## 性能问题
|
||||
|
||||
### 内存泄漏
|
||||
|
||||
**问题症状:**
|
||||
```
|
||||
Memory usage keeps growing
|
||||
Process killed by system
|
||||
```
|
||||
|
||||
**诊断工具:**
|
||||
```bash
|
||||
# 1. 监控内存使用
|
||||
node --inspect server.js
|
||||
# 打开 Chrome DevTools -> Memory 选项卡
|
||||
|
||||
# 2. 使用 clinic.js
|
||||
npm install -g clinic
|
||||
clinic doctor -- node server.js
|
||||
|
||||
# 3. 使用 PM2 监控
|
||||
pm2 install pm2-server-monit
|
||||
pm2 monit
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
```javascript
|
||||
// 1. 清理事件监听器
|
||||
process.removeAllListeners('exit');
|
||||
|
||||
// 2. 关闭数据库连接
|
||||
await sequelize.close();
|
||||
|
||||
// 3. 限制并发请求
|
||||
const pLimit = require('p-limit');
|
||||
const limit = pLimit(10);
|
||||
|
||||
// 4. 使用对象池
|
||||
const pool = new Pool({
|
||||
create: () => new ExpensiveObject(),
|
||||
destroy: (obj) => obj.cleanup()
|
||||
});
|
||||
```
|
||||
|
||||
### CPU 使用率高
|
||||
|
||||
**问题症状:**
|
||||
```
|
||||
CPU usage > 80%
|
||||
Response time degradation
|
||||
```
|
||||
|
||||
**诊断方法:**
|
||||
```bash
|
||||
# 1. 查看进程状态
|
||||
top -p $(pgrep node)
|
||||
htop
|
||||
|
||||
# 2. 分析性能瓶颈
|
||||
node --prof server.js
|
||||
node --prof-process isolate-*.log > processed.txt
|
||||
|
||||
# 3. 使用火焰图
|
||||
npm install -g 0x
|
||||
0x server.js
|
||||
```
|
||||
|
||||
### 数据库查询慢
|
||||
|
||||
**问题症状:**
|
||||
```
|
||||
Query execution time > 1000ms
|
||||
Database connection pool exhausted
|
||||
```
|
||||
|
||||
**优化策略:**
|
||||
```sql
|
||||
-- 1. 添加索引
|
||||
EXPLAIN SELECT * FROM farms WHERE status = 'active';
|
||||
CREATE INDEX idx_farms_status ON farms(status);
|
||||
|
||||
-- 2. 优化查询
|
||||
-- 避免 SELECT *
|
||||
SELECT id, name, status FROM farms WHERE status = 'active';
|
||||
|
||||
-- 3. 使用查询缓存
|
||||
SET SESSION query_cache_type = ON;
|
||||
```
|
||||
|
||||
## 部署问题
|
||||
|
||||
### Docker 构建失败
|
||||
|
||||
**问题症状:**
|
||||
```
|
||||
Docker build failed
|
||||
Image size too large
|
||||
Container startup errors
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
```dockerfile
|
||||
# 1. 优化 Dockerfile
|
||||
FROM node:18-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
|
||||
# 2. 使用多阶段构建
|
||||
FROM node:18-alpine AS runner
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
EXPOSE 5350
|
||||
CMD ["npm", "start"]
|
||||
|
||||
# 3. 添加 .dockerignore
|
||||
node_modules
|
||||
.git
|
||||
.env
|
||||
logs/*
|
||||
```
|
||||
|
||||
### Nginx 配置问题
|
||||
|
||||
**问题症状:**
|
||||
```
|
||||
502 Bad Gateway
|
||||
404 for static files
|
||||
CORS errors
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
# 解决 CORS 问题
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
|
||||
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
|
||||
|
||||
# 前端路由
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# API 代理
|
||||
location /api {
|
||||
proxy_pass http://backend:5350;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# 超时设置
|
||||
proxy_connect_timeout 30s;
|
||||
proxy_send_timeout 30s;
|
||||
proxy_read_timeout 30s;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### SSL 证书问题
|
||||
|
||||
**问题症状:**
|
||||
```
|
||||
Certificate expired
|
||||
SSL handshake failed
|
||||
Mixed content warnings
|
||||
```
|
||||
|
||||
**解决方案:**
|
||||
```bash
|
||||
# 1. 使用 Let's Encrypt
|
||||
certbot --nginx -d yourdomain.com
|
||||
|
||||
# 2. 检查证书状态
|
||||
openssl x509 -in /path/to/cert.pem -text -noout
|
||||
|
||||
# 3. 自动续期
|
||||
echo "0 12 * * * /usr/bin/certbot renew --quiet" | crontab -
|
||||
|
||||
# 4. 强制 HTTPS
|
||||
return 301 https://$server_name$request_uri;
|
||||
```
|
||||
|
||||
## 日志分析
|
||||
|
||||
### 后端日志
|
||||
|
||||
**日志位置:**
|
||||
```bash
|
||||
backend/logs/
|
||||
├── app.log # 应用日志
|
||||
├── error.log # 错误日志
|
||||
├── access.log # 访问日志
|
||||
└── performance/ # 性能监控日志
|
||||
├── system-YYYY-MM-DD.log
|
||||
└── database-YYYY-MM-DD.log
|
||||
```
|
||||
|
||||
**常用命令:**
|
||||
```bash
|
||||
# 实时查看日志
|
||||
tail -f backend/logs/app.log
|
||||
|
||||
# 搜索错误
|
||||
grep -i error backend/logs/*.log
|
||||
|
||||
# 分析访问模式
|
||||
awk '{print $1}' backend/logs/access.log | sort | uniq -c | sort -nr
|
||||
|
||||
# 查看特定时间段日志
|
||||
sed -n '/2025-01-18 10:00/,/2025-01-18 11:00/p' backend/logs/app.log
|
||||
```
|
||||
|
||||
### 前端日志
|
||||
|
||||
**浏览器控制台:**
|
||||
```javascript
|
||||
// 1. 查看网络请求
|
||||
// Network 标签页 -> 筛选 XHR/Fetch
|
||||
|
||||
// 2. 查看 JavaScript 错误
|
||||
// Console 标签页 -> 筛选 Errors
|
||||
|
||||
// 3. 查看性能
|
||||
// Performance 标签页 -> 录制并分析
|
||||
|
||||
// 4. 查看内存使用
|
||||
// Memory 标签页 -> Heap snapshot
|
||||
```
|
||||
|
||||
## 监控和诊断工具
|
||||
|
||||
### 系统监控
|
||||
|
||||
```bash
|
||||
# 1. 系统资源监控
|
||||
htop
|
||||
iostat -x 1
|
||||
vmstat 1
|
||||
|
||||
# 2. 磁盘使用
|
||||
df -h
|
||||
du -sh /path/to/project
|
||||
|
||||
# 3. 网络连接
|
||||
netstat -tulpn
|
||||
ss -tulpn
|
||||
```
|
||||
|
||||
### 应用监控
|
||||
|
||||
```bash
|
||||
# 1. PM2 监控
|
||||
pm2 monit
|
||||
pm2 logs
|
||||
pm2 show app-name
|
||||
|
||||
# 2. Node.js 性能分析
|
||||
node --inspect server.js
|
||||
# 访问 chrome://inspect
|
||||
|
||||
# 3. 数据库监控
|
||||
SHOW PROCESSLIST;
|
||||
SHOW STATUS LIKE 'Slow_queries';
|
||||
```
|
||||
|
||||
### 自定义监控脚本
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# health-check.sh
|
||||
|
||||
# 检查服务状态
|
||||
curl -f http://localhost:5350/api/health || echo "API 服务异常"
|
||||
|
||||
# 检查数据库连接
|
||||
mysql -u root -p -e "SELECT 1" > /dev/null 2>&1 || echo "数据库连接失败"
|
||||
|
||||
# 检查磁盘空间
|
||||
df -h | awk '$5 > 80 {print "磁盘使用率过高: " $0}'
|
||||
|
||||
# 检查内存使用
|
||||
free | awk 'NR==2{printf "内存使用率: %.2f%%\n", $3*100/$2}'
|
||||
```
|
||||
|
||||
## 紧急响应流程
|
||||
|
||||
### 服务不可用
|
||||
|
||||
**立即响应 (5分钟内):**
|
||||
```bash
|
||||
# 1. 检查服务状态
|
||||
pm2 status
|
||||
systemctl status nginx
|
||||
|
||||
# 2. 重启服务
|
||||
pm2 restart all
|
||||
systemctl restart nginx
|
||||
|
||||
# 3. 检查日志
|
||||
tail -f logs/error.log
|
||||
```
|
||||
|
||||
**深入分析 (30分钟内):**
|
||||
```bash
|
||||
# 1. 检查系统资源
|
||||
top
|
||||
df -h
|
||||
free -h
|
||||
|
||||
# 2. 分析错误日志
|
||||
grep -i error logs/*.log | tail -20
|
||||
|
||||
# 3. 数据库健康检查
|
||||
mysql -e "SHOW PROCESSLIST;"
|
||||
```
|
||||
|
||||
### 数据库异常
|
||||
|
||||
**紧急处理:**
|
||||
```bash
|
||||
# 1. 检查数据库状态
|
||||
systemctl status mysql
|
||||
|
||||
# 2. 查看错误日志
|
||||
tail -f /var/log/mysql/error.log
|
||||
|
||||
# 3. 重启数据库服务
|
||||
systemctl restart mysql
|
||||
|
||||
# 4. 检查数据完整性
|
||||
mysqlcheck -u root -p --all-databases
|
||||
```
|
||||
|
||||
### 安全事件
|
||||
|
||||
**响应步骤:**
|
||||
```bash
|
||||
# 1. 隔离受影响的服务
|
||||
pm2 stop suspicious-process
|
||||
|
||||
# 2. 检查访问日志
|
||||
grep -E "(404|500)" logs/access.log | tail -50
|
||||
|
||||
# 3. 更新密码和密钥
|
||||
# 重新生成 JWT 密钥
|
||||
# 强制所有用户重新登录
|
||||
|
||||
# 4. 通知相关人员
|
||||
echo "安全事件发生,请立即检查系统" | mail -s "紧急: 安全告警" admin@company.com
|
||||
```
|
||||
|
||||
## 联系支持
|
||||
|
||||
### 获取帮助的渠道
|
||||
|
||||
1. **技术支持邮箱**: support@nxxmdata.com
|
||||
2. **紧急联系电话**: 400-xxx-xxxx
|
||||
3. **在线文档**: https://docs.nxxmdata.com
|
||||
4. **GitHub Issues**: https://github.com/your-org/nxxmdata/issues
|
||||
|
||||
### 报告问题时请提供
|
||||
|
||||
1. **错误描述**: 详细的错误信息和复现步骤
|
||||
2. **环境信息**: 操作系统、Node.js版本、浏览器版本
|
||||
3. **日志文件**: 相关的错误日志
|
||||
4. **配置信息**: 去敏感化的配置文件
|
||||
5. **系统状态**: CPU、内存、磁盘使用情况
|
||||
|
||||
---
|
||||
|
||||
*最后更新: 2025年1月*
|
||||
|
||||
**注意**: 本文档会根据系统更新持续完善,请定期查看最新版本。
|
||||
122
docs/operations/data-sync-fix-report.md
Normal file
122
docs/operations/data-sync-fix-report.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# 经纬度数据同步问题修复报告
|
||||
|
||||
## 问题描述
|
||||
|
||||
用户反馈经纬度输入框的值与数据库存储的值不一致,存在数据不同步的问题。
|
||||
|
||||
## 问题分析
|
||||
|
||||
通过深入调查,发现问题的根本原因是:
|
||||
|
||||
### 1. 数据库存储格式问题
|
||||
- **问题**: 数据库中的 `location` 字段被存储为 JSON 字符串而不是 JSON 对象
|
||||
- **表现**: `location` 字段值为 `"{\"lat\":38.47,\"lng\":106.28}"` (字符串格式)
|
||||
- **期望**: `location` 字段值应为 `{"lat":38.47,"lng":106.28}` (对象格式)
|
||||
|
||||
### 2. 前端解析问题
|
||||
- 当 `location` 字段为字符串时,前端无法正确解析 `lng` 和 `lat` 属性
|
||||
- 导致编辑表单中经纬度输入框显示为空
|
||||
|
||||
## 解决方案
|
||||
|
||||
### 1. 数据库格式修复
|
||||
|
||||
创建并运行了 `fix-location-data.js` 脚本:
|
||||
|
||||
```javascript
|
||||
// 将JSON字符串转换为JSON对象
|
||||
if (typeof farm.location === 'string') {
|
||||
newLocation = JSON.parse(farm.location);
|
||||
await farm.update({ location: newLocation });
|
||||
}
|
||||
```
|
||||
|
||||
**修复结果**:
|
||||
- 总记录数: 12
|
||||
- 修复成功: 11
|
||||
- 修复失败: 0
|
||||
- 无需修复: 1
|
||||
|
||||
### 2. 代码验证
|
||||
|
||||
#### 后端代码检查
|
||||
- ✅ `Farm` 模型定义正确 (`DataTypes.JSON`)
|
||||
- ✅ `createFarm` 函数正确处理经纬度数据
|
||||
- ✅ `updateFarm` 函数正确构建 location 对象
|
||||
|
||||
#### 前端代码检查
|
||||
- ✅ `editFarm` 函数正确解析 `record.location?.lng` 和 `record.location?.lat`
|
||||
- ✅ 表单验证规则完整
|
||||
- ✅ `handleSubmit` 函数正确提交数据
|
||||
|
||||
## 测试验证
|
||||
|
||||
### 1. 数据格式验证
|
||||
|
||||
修复前:
|
||||
```
|
||||
Location对象: "{\"lat\":38.4872,\"lng\":106.2309}"
|
||||
❌ Location字段为空或格式错误
|
||||
```
|
||||
|
||||
修复后:
|
||||
```
|
||||
Location对象: {"lat":38.4872,"lng":106.2309}
|
||||
经度 (lng): 106.2309 (类型: number)
|
||||
纬度 (lat): 38.4872 (类型: number)
|
||||
✅ 有经纬度数据
|
||||
```
|
||||
|
||||
### 2. 数据同步测试
|
||||
|
||||
运行 `test-data-sync.js` 验证完整流程:
|
||||
|
||||
```
|
||||
=== 测试结果 ===
|
||||
✅ 创建记录成功
|
||||
✅ 查询验证通过
|
||||
✅ API响应格式正确
|
||||
✅ 前端数据解析正确
|
||||
✅ 更新操作成功
|
||||
✅ 数据一致性检查通过
|
||||
结果: 数据同步正常
|
||||
```
|
||||
|
||||
## 修复效果
|
||||
|
||||
### 修复前
|
||||
- 数据库中 location 字段为 JSON 字符串
|
||||
- 前端无法正确解析经纬度数据
|
||||
- 编辑表单中经纬度输入框显示为空
|
||||
- 用户输入的值与数据库存储值不一致
|
||||
|
||||
### 修复后
|
||||
- 数据库中 location 字段为 JSON 对象
|
||||
- 前端正确解析并显示经纬度数据
|
||||
- 编辑表单正确回显经纬度值
|
||||
- 用户输入值与数据库存储值完全一致
|
||||
|
||||
## 预防措施
|
||||
|
||||
### 1. 数据验证
|
||||
- 在 `createFarm` 和 `updateFarm` 函数中确保 location 对象格式正确
|
||||
- 添加数据类型检查,确保经纬度为数值类型
|
||||
|
||||
### 2. 前端处理
|
||||
- 在 `editFarm` 函数中添加容错处理
|
||||
- 确保 location 对象解析的健壮性
|
||||
|
||||
### 3. 测试覆盖
|
||||
- 定期运行数据一致性检查
|
||||
- 在部署前验证经纬度数据的完整流程
|
||||
|
||||
## 总结
|
||||
|
||||
经纬度数据同步问题已完全解决:
|
||||
|
||||
1. **根本原因**: 数据库中 location 字段存储格式错误(JSON字符串 vs JSON对象)
|
||||
2. **解决方案**: 运行数据修复脚本,将所有记录的 location 字段转换为正确的 JSON 对象格式
|
||||
3. **验证结果**: 所有测试通过,数据同步正常
|
||||
4. **预防措施**: 建立了完整的测试和验证机制
|
||||
|
||||
现在用户在前端编辑养殖场时,经纬度输入框会正确显示数据库中存储的值,实现了完全的数据同步。
|
||||
116
docs/operations/farms-data-import-summary.md
Normal file
116
docs/operations/farms-data-import-summary.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# Farms静态数据导入总结
|
||||
|
||||
## 概述
|
||||
成功将后端API中的farms静态数据导入到数据库的farms表中。
|
||||
|
||||
## 数据来源
|
||||
|
||||
### 1. API静态数据
|
||||
来源:`routes/farms.js` 中的 `/public` 路由
|
||||
- 宁夏农场1 (银川市)
|
||||
- 宁夏农场2 (石嘴山市)
|
||||
- 宁夏农场3 (吴忠市)
|
||||
|
||||
### 2. 种子数据
|
||||
来源:`seeds/20230102000000_farm_data.js` 和 `seeds/20230103000000_extended_data.js`
|
||||
- 阳光农场 (养猪场)
|
||||
- 绿野牧场 (养牛场)
|
||||
- 山谷羊场 (养羊场)
|
||||
- 蓝天养鸡场 (养鸡场)
|
||||
- 金山养鸭场 (养鸭场)
|
||||
- 银河渔场 (渔场)
|
||||
- 星空牧场 (综合养殖场)
|
||||
- 彩虹农庄 (有机农场)
|
||||
|
||||
## 导入过程
|
||||
|
||||
### 1. 创建导入脚本
|
||||
文件:`import-farms-static-data.js`
|
||||
- 合并API静态数据和种子数据
|
||||
- 使用事务确保数据一致性
|
||||
- 清空现有数据并重置自增ID
|
||||
- 批量插入新数据
|
||||
|
||||
### 2. 执行导入
|
||||
```bash
|
||||
node import-farms-static-data.js
|
||||
```
|
||||
|
||||
### 3. 验证导入结果
|
||||
文件:`verify-farms-import.js`
|
||||
- 数据完整性检查
|
||||
- ID序列连续性验证
|
||||
- 地理位置数据验证
|
||||
- 农场类型统计
|
||||
|
||||
## 导入结果
|
||||
|
||||
### 数据统计
|
||||
- **总计**:11个农场
|
||||
- **ID范围**:1-11(连续)
|
||||
- **数据完整性**:✅ 所有字段完整
|
||||
- **地理位置**:✅ 所有位置数据有效
|
||||
|
||||
### 农场类型分布
|
||||
| 类型 | 数量 |
|
||||
|------|------|
|
||||
| 综合农场 | 3个 |
|
||||
| 养猪场 | 1个 |
|
||||
| 养牛场 | 1个 |
|
||||
| 养羊场 | 1个 |
|
||||
| 养鸡场 | 1个 |
|
||||
| 养鸭场 | 1个 |
|
||||
| 渔场 | 1个 |
|
||||
| 综合养殖场 | 1个 |
|
||||
| 有机农场 | 1个 |
|
||||
|
||||
### API验证
|
||||
- `/api/farms/public` ✅ 返回正确的静态数据
|
||||
- `/api/farms` ✅ 返回完整的数据库数据
|
||||
|
||||
## 数据结构
|
||||
|
||||
每个农场记录包含以下字段:
|
||||
- `id`: 主键,自增
|
||||
- `name`: 农场名称
|
||||
- `type`: 农场类型
|
||||
- `location`: 地理位置(JSON格式,包含lat和lng)
|
||||
- `address`: 详细地址
|
||||
- `contact`: 联系人
|
||||
- `phone`: 联系电话
|
||||
- `status`: 状态(active/inactive/maintenance)
|
||||
- `created_at`: 创建时间
|
||||
- `updated_at`: 更新时间
|
||||
|
||||
## 相关文件
|
||||
|
||||
### 创建的文件
|
||||
- `import-farms-static-data.js` - 数据导入脚本
|
||||
- `verify-farms-import.js` - 数据验证脚本
|
||||
- `farms-data-import-summary.md` - 本总结文档
|
||||
|
||||
### 涉及的现有文件
|
||||
- `routes/farms.js` - API路由定义
|
||||
- `models/Farm.js` - 数据模型定义
|
||||
- `controllers/farmController.js` - 控制器逻辑
|
||||
- `seeds/20230102000000_farm_data.js` - 种子数据
|
||||
- `seeds/20230103000000_extended_data.js` - 扩展种子数据
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **数据库连接警告**:执行过程中出现循环依赖警告,但不影响功能
|
||||
2. **事务安全**:使用数据库事务确保数据导入的原子性
|
||||
3. **ID重置**:导入前重置了自增ID,确保从1开始
|
||||
4. **数据覆盖**:导入过程会清空现有farms数据
|
||||
|
||||
## 后续建议
|
||||
|
||||
1. 定期备份farms数据
|
||||
2. 考虑添加数据迁移脚本
|
||||
3. 优化循环依赖问题
|
||||
4. 添加更多数据验证规则
|
||||
|
||||
---
|
||||
|
||||
**导入完成时间**:2025-08-21
|
||||
**状态**:✅ 成功完成
|
||||
256
docs/operations/location-data-validation-report.md
Normal file
256
docs/operations/location-data-validation-report.md
Normal file
@@ -0,0 +1,256 @@
|
||||
# 经纬度数据传递验证报告
|
||||
|
||||
## 概述
|
||||
|
||||
本报告详细验证了经纬度输入值从前端表单到数据库操作层的完整传递流程,确保location字段的更新逻辑被正确执行,并验证查询绑定的值与数据库中的实际值一致。
|
||||
|
||||
## 验证范围
|
||||
|
||||
### 1. 前端数据处理
|
||||
- ✅ 经纬度输入框配置正确
|
||||
- ✅ 表单验证规则完善
|
||||
- ✅ 数据提交格式正确
|
||||
|
||||
### 2. 后端API处理
|
||||
- ✅ 创建养殖场时经纬度处理
|
||||
- ✅ 更新养殖场时经纬度处理(已修复)
|
||||
- ✅ 空值和边界值处理
|
||||
|
||||
### 3. 数据库存储
|
||||
- ✅ JSON字段存储格式正确
|
||||
- ✅ 数据类型保持一致
|
||||
- ✅ 精度保持完整
|
||||
|
||||
## 详细验证结果
|
||||
|
||||
### 前端组件配置
|
||||
|
||||
**经度输入框配置:**
|
||||
```vue
|
||||
<a-input-number
|
||||
v-model:value="formData.longitude"
|
||||
:min="-180"
|
||||
:max="180"
|
||||
:precision="6"
|
||||
:step="0.000001"
|
||||
:string-mode="false"
|
||||
:controls="false"
|
||||
placeholder="请输入经度 (-180 ~ 180)"
|
||||
:parser="(value) => {
|
||||
if (typeof value === 'string') {
|
||||
const num = parseFloat(value.replace(/[^\d.-]/g, ''));
|
||||
return isNaN(num) ? undefined : num;
|
||||
}
|
||||
return value;
|
||||
}"
|
||||
:formatter="(value) => value ? value.toString() : ''"
|
||||
/>
|
||||
```
|
||||
|
||||
**纬度输入框配置:**
|
||||
```vue
|
||||
<a-input-number
|
||||
v-model:value="formData.latitude"
|
||||
:min="-90"
|
||||
:max="90"
|
||||
:precision="6"
|
||||
:step="0.000001"
|
||||
:string-mode="false"
|
||||
:controls="false"
|
||||
placeholder="请输入纬度 (-90 ~ 90)"
|
||||
:parser="(value) => {
|
||||
if (typeof value === 'string') {
|
||||
const num = parseFloat(value.replace(/[^\d.-]/g, ''));
|
||||
return isNaN(num) ? undefined : num;
|
||||
}
|
||||
return value;
|
||||
}"
|
||||
:formatter="(value) => value ? value.toString() : ''"
|
||||
/>
|
||||
```
|
||||
|
||||
### 表单验证规则
|
||||
|
||||
**经度验证:**
|
||||
- ✅ 允许为空值
|
||||
- ✅ 数值有效性检查
|
||||
- ✅ 范围验证(-180 到 180)
|
||||
- ✅ 精度限制(最多6位小数)
|
||||
|
||||
**纬度验证:**
|
||||
- ✅ 允许为空值
|
||||
- ✅ 数值有效性检查
|
||||
- ✅ 范围验证(-90 到 90)
|
||||
- ✅ 精度限制(最多6位小数)
|
||||
|
||||
### 后端API处理
|
||||
|
||||
**创建养殖场(createFarm):**
|
||||
```javascript
|
||||
// 构建location对象
|
||||
const location = {};
|
||||
if (longitude !== undefined && longitude !== null) {
|
||||
location.lng = parseFloat(longitude);
|
||||
}
|
||||
if (latitude !== undefined && latitude !== null) {
|
||||
location.lat = parseFloat(latitude);
|
||||
}
|
||||
|
||||
const farm = await Farm.create({
|
||||
name,
|
||||
type: 'farm',
|
||||
location,
|
||||
address,
|
||||
contact: owner,
|
||||
phone,
|
||||
status: status || 'active'
|
||||
});
|
||||
```
|
||||
|
||||
**更新养殖场(updateFarm):**
|
||||
```javascript
|
||||
// 构建location对象 - 创建新对象以确保Sequelize检测到变化
|
||||
const location = { ...(farm.location || {}) };
|
||||
if (longitude !== undefined && longitude !== null) {
|
||||
location.lng = parseFloat(longitude);
|
||||
}
|
||||
if (latitude !== undefined && latitude !== null) {
|
||||
location.lat = parseFloat(latitude);
|
||||
}
|
||||
|
||||
await farm.update({
|
||||
name,
|
||||
type: farm.type || 'farm',
|
||||
location,
|
||||
address,
|
||||
contact: owner,
|
||||
phone,
|
||||
status: status || 'active'
|
||||
});
|
||||
```
|
||||
|
||||
### 数据库模型定义
|
||||
|
||||
```javascript
|
||||
location: {
|
||||
type: DataTypes.JSON,
|
||||
allowNull: false,
|
||||
defaultValue: {}
|
||||
}
|
||||
```
|
||||
|
||||
## 测试结果
|
||||
|
||||
### 基础功能测试
|
||||
|
||||
| 测试项目 | 输入值 | 期望结果 | 实际结果 | 状态 |
|
||||
|---------|--------|----------|----------|------|
|
||||
| 创建记录 | lng: 106.123456, lat: 38.654321 | 正确存储 | ✅ 正确存储 | 通过 |
|
||||
| 更新记录 | lng: 107.987654, lat: 39.123456 | 正确更新 | ✅ 正确更新 | 通过 |
|
||||
| 部分更新 | 仅更新经度 | 经度更新,纬度保持 | ✅ 符合期望 | 通过 |
|
||||
| 清空坐标 | 空对象 | location为空对象 | ✅ 符合期望 | 通过 |
|
||||
|
||||
### 边界值测试
|
||||
|
||||
| 测试项目 | 输入值 | 存储值 | 精度保持 | 状态 |
|
||||
|---------|--------|--------|----------|------|
|
||||
| 最小边界值 | lng: -180, lat: -90 | lng: -180, lat: -90 | ✅ | 通过 |
|
||||
| 最大边界值 | lng: 180, lat: 90 | lng: 180, lat: 90 | ✅ | 通过 |
|
||||
| 零值 | lng: 0, lat: 0 | lng: 0, lat: 0 | ✅ | 通过 |
|
||||
| 高精度值 | lng: 106.123456789, lat: 38.987654321 | lng: 106.123456789, lat: 38.987654321 | ✅ | 通过 |
|
||||
|
||||
### 空值处理测试
|
||||
|
||||
| 测试项目 | 输入值 | 处理结果 | 状态 |
|
||||
|---------|--------|----------|------|
|
||||
| undefined值 | longitude: undefined, latitude: undefined | location: {} | ✅ 通过 |
|
||||
| null值 | longitude: null, latitude: null | location: {} | ✅ 通过 |
|
||||
| 空字符串 | longitude: '', latitude: '' | location: {} | ✅ 通过 |
|
||||
| 仅经度有值 | longitude: 106.123, latitude: undefined | location: {lng: 106.123} | ✅ 通过 |
|
||||
| 仅纬度有值 | longitude: undefined, latitude: 38.456 | location: {lat: 38.456} | ✅ 通过 |
|
||||
|
||||
### API流程测试
|
||||
|
||||
| 操作 | 输入经纬度 | 存储结果 | 状态 |
|
||||
|------|------------|----------|------|
|
||||
| 创建 | lng: 106.789123, lat: 38.456789 | ✅ 正确存储 | 通过 |
|
||||
| 更新 | lng: 107.111222, lat: 39.333444 | ✅ 正确更新 | 通过 |
|
||||
|
||||
## 发现的问题及修复
|
||||
|
||||
### 问题1:更新操作中经纬度值未正确保存
|
||||
|
||||
**问题描述:**
|
||||
在更新养殖场时,新的经纬度值没有被正确保存到数据库中。
|
||||
|
||||
**原因分析:**
|
||||
原代码直接修改了原有的location对象引用:
|
||||
```javascript
|
||||
const location = farm.location || {};
|
||||
```
|
||||
Sequelize可能没有检测到这个对象的变化,因为它是同一个引用。
|
||||
|
||||
**修复方案:**
|
||||
创建一个新的location对象来确保Sequelize检测到变化:
|
||||
```javascript
|
||||
const location = { ...(farm.location || {}) };
|
||||
```
|
||||
|
||||
**修复验证:**
|
||||
- ✅ 更新操作现在能正确保存新的经纬度值
|
||||
- ✅ 部分更新功能正常工作
|
||||
- ✅ 不影响其他字段的更新
|
||||
|
||||
## 数据流验证
|
||||
|
||||
### 完整数据流路径
|
||||
|
||||
1. **前端输入** → 用户在经纬度输入框中输入数值
|
||||
2. **前端验证** → 表单验证规则检查数值有效性和范围
|
||||
3. **前端提交** → 通过API发送JSON数据到后端
|
||||
4. **后端接收** → 控制器从req.body中提取longitude和latitude
|
||||
5. **后端处理** → 使用parseFloat转换并构建location对象
|
||||
6. **数据库存储** → Sequelize将location对象存储为JSON格式
|
||||
7. **数据库查询** → 查询时返回完整的location对象
|
||||
8. **前端显示** → 编辑时正确解析location.lng和location.lat
|
||||
|
||||
### 数据类型转换验证
|
||||
|
||||
| 阶段 | 数据类型 | 示例值 |
|
||||
|------|----------|--------|
|
||||
| 前端输入 | number | 106.123456 |
|
||||
| API传输 | number | 106.123456 |
|
||||
| 后端处理 | number (parseFloat) | 106.123456 |
|
||||
| 数据库存储 | JSON | {"lng":106.123456,"lat":38.654321} |
|
||||
| 数据库查询 | number | 106.123456 |
|
||||
| 前端显示 | number | 106.123456 |
|
||||
|
||||
## 结论
|
||||
|
||||
### 验证结果总结
|
||||
|
||||
✅ **经纬度数据传递流程完全正确**
|
||||
- 前端输入框配置合理,支持高精度数值输入
|
||||
- 表单验证规则完善,确保数据有效性
|
||||
- 后端API正确处理经纬度数据的创建和更新
|
||||
- 数据库存储格式正确,支持JSON格式的location字段
|
||||
- 数据类型在整个流程中保持一致
|
||||
|
||||
✅ **修复的问题**
|
||||
- 更新操作中的对象引用问题已解决
|
||||
- 经纬度值现在能正确保存和更新
|
||||
|
||||
✅ **边界情况处理**
|
||||
- 空值处理正确
|
||||
- 边界值验证通过
|
||||
- 高精度数值保持完整
|
||||
|
||||
### 建议
|
||||
|
||||
1. **监控建议**:建议在生产环境中添加日志记录,监控经纬度数据的更新操作
|
||||
2. **性能建议**:对于大量的位置更新操作,可以考虑批量更新优化
|
||||
3. **扩展建议**:未来可以考虑添加地理位置验证(如检查坐标是否在合理的地理范围内)
|
||||
|
||||
### 最终确认
|
||||
|
||||
经过全面测试验证,经纬度输入值能够正确传递到数据库操作层,location字段的更新逻辑被正确执行,查询绑定的值与数据库中的实际值完全一致。系统现在能够可靠地处理经纬度数据的存储和更新操作。
|
||||
305
docs/operations/performance-monitoring.md
Normal file
305
docs/operations/performance-monitoring.md
Normal file
@@ -0,0 +1,305 @@
|
||||
# 性能监控系统文档
|
||||
|
||||
## 概述
|
||||
|
||||
性能监控系统是一个全面的监控工具,用于实时跟踪和分析应用程序的性能指标。它包括以下主要功能:
|
||||
|
||||
- **系统资源监控**:CPU、内存和磁盘使用情况
|
||||
- **数据库性能监控**:连接池状态、慢查询识别和查询模式分析
|
||||
- **API性能监控**:请求响应时间、错误率和请求频率
|
||||
- **警报系统**:基于可配置阈值的性能警报
|
||||
- **历史数据**:性能指标的历史记录和趋势分析
|
||||
- **可视化界面**:直观的性能指标展示
|
||||
|
||||
## 系统架构
|
||||
|
||||
性能监控系统由以下组件组成:
|
||||
|
||||
1. **核心监控引擎**:`performance-monitor.js`
|
||||
2. **API中间件**:`performance-middleware.js`
|
||||
3. **配置模块**:`performance-config.js`
|
||||
4. **API路由**:`performance-routes.js`
|
||||
5. **前端组件**:`PerformanceMonitor.vue`
|
||||
|
||||
## 安装和配置
|
||||
|
||||
### 后端集成
|
||||
|
||||
1. 在Express应用中引入性能监控系统:
|
||||
|
||||
```javascript
|
||||
const { initPerformanceMonitoring, getPerformanceRoutes } = require('./backend/config/performance-config');
|
||||
|
||||
// 初始化性能监控系统
|
||||
const performanceMonitor = initPerformanceMonitoring(app, {
|
||||
autoStart: true,
|
||||
interval: 60000, // 监控间隔(毫秒)
|
||||
logToConsole: false,
|
||||
thresholds: {
|
||||
system: {
|
||||
cpuUsage: 80, // CPU使用率阈值(百分比)
|
||||
memoryUsage: 80, // 内存使用率阈值(百分比)
|
||||
diskUsage: 80 // 磁盘使用率阈值(百分比)
|
||||
},
|
||||
database: {
|
||||
connectionPoolUtilization: 80, // 连接池利用率阈值(百分比)
|
||||
slowQueryCount: 5, // 慢查询数量阈值
|
||||
errorRate: 5 // 错误率阈值(百分比)
|
||||
},
|
||||
api: {
|
||||
responseTime: 500, // API响应时间阈值(毫秒)
|
||||
errorRate: 5, // API错误率阈值(百分比)
|
||||
requestRate: 1000 // 每分钟请求数阈值
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 注册性能监控路由
|
||||
app.use('/api/performance', getPerformanceRoutes());
|
||||
```
|
||||
|
||||
### 前端集成
|
||||
|
||||
1. 在Vue应用中引入性能监控组件:
|
||||
|
||||
```javascript
|
||||
import PerformanceMonitor from './components/PerformanceMonitor.vue';
|
||||
|
||||
// 在Vue组件中使用
|
||||
export default {
|
||||
components: {
|
||||
PerformanceMonitor
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. 在模板中使用组件:
|
||||
|
||||
```html
|
||||
<template>
|
||||
<div>
|
||||
<performance-monitor />
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
## API参考
|
||||
|
||||
### 后端API
|
||||
|
||||
#### 性能监控核心API
|
||||
|
||||
```javascript
|
||||
const { performanceMonitor } = require('./backend/utils/performance-monitor');
|
||||
|
||||
// 启动监控
|
||||
performanceMonitor.startMonitoring(60000); // 参数:监控间隔(毫秒)
|
||||
|
||||
// 停止监控
|
||||
performanceMonitor.stopMonitoring();
|
||||
|
||||
// 获取所有性能指标
|
||||
const metrics = await performanceMonitor.getAllMetrics();
|
||||
|
||||
// 获取系统资源指标
|
||||
const systemMetrics = performanceMonitor.getSystemMetrics();
|
||||
|
||||
// 获取数据库性能指标
|
||||
const dbMetrics = await performanceMonitor.getDatabaseMetrics();
|
||||
|
||||
// 获取API性能指标
|
||||
const apiStats = performanceMonitor.getApiStats();
|
||||
|
||||
// 设置警报阈值
|
||||
performanceMonitor.setAlertThresholds({
|
||||
system: { cpuUsage: 75 },
|
||||
api: { responseTime: 300 }
|
||||
});
|
||||
|
||||
// 获取警报阈值
|
||||
const thresholds = performanceMonitor.getAlertThresholds();
|
||||
|
||||
// 重置API统计
|
||||
performanceMonitor.resetApiStats();
|
||||
```
|
||||
|
||||
#### HTTP API端点
|
||||
|
||||
| 端点 | 方法 | 描述 |
|
||||
|------|------|------|
|
||||
| `/api/performance/metrics` | GET | 获取所有性能指标 |
|
||||
| `/api/performance/system` | GET | 获取系统资源指标 |
|
||||
| `/api/performance/database` | GET | 获取数据库性能指标 |
|
||||
| `/api/performance/api` | GET | 获取API性能指标 |
|
||||
| `/api/performance/start` | POST | 启动性能监控 |
|
||||
| `/api/performance/stop` | POST | 停止性能监控 |
|
||||
| `/api/performance/status` | GET | 获取监控状态 |
|
||||
| `/api/performance/thresholds` | GET | 获取警报阈值 |
|
||||
| `/api/performance/thresholds` | POST | 设置警报阈值 |
|
||||
| `/api/performance/api/reset` | POST | 重置API统计 |
|
||||
|
||||
### 事件系统
|
||||
|
||||
性能监控系统提供了一个事件系统,可以监听各种性能相关的事件:
|
||||
|
||||
```javascript
|
||||
const { perfEvents } = require('./backend/utils/performance-monitor');
|
||||
|
||||
// 监控启动事件
|
||||
perfEvents.on('monitoringStarted', (data) => {
|
||||
console.log(`性能监控已启动,间隔: ${data.interval}ms`);
|
||||
});
|
||||
|
||||
// 监控停止事件
|
||||
perfEvents.on('monitoringStopped', () => {
|
||||
console.log('性能监控已停止');
|
||||
});
|
||||
|
||||
// 数据库状态变化事件
|
||||
perfEvents.on('databaseStatus', (status) => {
|
||||
console.log('数据库状态更新:', status);
|
||||
});
|
||||
|
||||
// 数据库错误事件
|
||||
perfEvents.on('databaseError', (error) => {
|
||||
console.error('数据库错误:', error);
|
||||
});
|
||||
|
||||
// 慢查询事件
|
||||
perfEvents.on('slowQuery', (query) => {
|
||||
console.warn(`检测到慢查询: ${query.duration}ms - ${query.query}`);
|
||||
});
|
||||
|
||||
// API错误事件
|
||||
perfEvents.on('apiError', (data) => {
|
||||
console.error(`API错误: ${data.method} ${data.path} - ${data.error}`);
|
||||
});
|
||||
|
||||
// 慢API请求事件
|
||||
perfEvents.on('slowApiRequest', (data) => {
|
||||
console.warn(`慢API请求: ${data.endpoint} - ${data.duration}ms`);
|
||||
});
|
||||
|
||||
// 高CPU使用率事件
|
||||
perfEvents.on('highCpuUsage', (data) => {
|
||||
console.warn(`高CPU使用率: ${data.usage}% (阈值: ${data.threshold}%)`);
|
||||
});
|
||||
|
||||
// 高内存使用率事件
|
||||
perfEvents.on('highMemoryUsage', (data) => {
|
||||
console.warn(`高内存使用率: ${data.usage}% (阈值: ${data.threshold}%)`);
|
||||
});
|
||||
|
||||
// 高磁盘使用率事件
|
||||
perfEvents.on('highDiskUsage', (data) => {
|
||||
console.warn(`高磁盘使用率: ${data.usage}% (阈值: ${data.threshold}%)`);
|
||||
});
|
||||
```
|
||||
|
||||
## 前端组件
|
||||
|
||||
`PerformanceMonitor.vue` 组件提供了一个直观的界面,用于展示性能指标和配置警报阈值。它包括以下功能:
|
||||
|
||||
- 系统资源监控面板(CPU、内存、磁盘)
|
||||
- 数据库性能监控面板(连接池、慢查询、查询模式)
|
||||
- API性能监控面板(请求统计、响应时间、错误率)
|
||||
- 警报配置面板(设置各项指标的警报阈值)
|
||||
- 实时图表展示历史趋势
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 性能监控
|
||||
|
||||
1. **设置合适的监控间隔**:根据应用负载和服务器资源选择合适的监控间隔。高负载系统可能需要更长的间隔(如5分钟),而关键系统可能需要更短的间隔(如30秒)。
|
||||
|
||||
2. **配置合理的警报阈值**:根据系统特性和业务需求设置合理的警报阈值。过低的阈值可能导致过多的警报,过高的阈值可能导致问题被忽略。
|
||||
|
||||
3. **定期分析性能数据**:定期查看性能监控数据,识别潜在问题和优化机会。
|
||||
|
||||
### 数据库优化
|
||||
|
||||
1. **关注慢查询**:定期检查慢查询列表,优化频繁出现的慢查询。
|
||||
|
||||
2. **监控连接池**:保持合理的连接池大小,避免连接池耗尽或过度分配。
|
||||
|
||||
3. **分析查询模式**:利用查询模式统计,识别频繁执行的查询,考虑添加索引或优化查询结构。
|
||||
|
||||
### API优化
|
||||
|
||||
1. **关注慢响应API**:优化响应时间超过阈值的API端点。
|
||||
|
||||
2. **监控错误率**:保持低错误率,及时修复错误率高的API端点。
|
||||
|
||||
3. **平衡请求负载**:避免单个端点过度负载,考虑负载均衡或缓存策略。
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **监控系统占用过多资源**:
|
||||
- 增加监控间隔
|
||||
- 减少收集的指标
|
||||
- 限制历史数据存储量
|
||||
|
||||
2. **警报过多**:
|
||||
- 调整警报阈值
|
||||
- 合并相似警报
|
||||
- 实现警报抑制机制
|
||||
|
||||
3. **数据不准确**:
|
||||
- 检查监控代码是否正确集成
|
||||
- 验证数据源是否可靠
|
||||
- 确保时间同步
|
||||
|
||||
### 日志文件
|
||||
|
||||
性能监控系统会在 `logs/performance` 目录下生成以下日志文件:
|
||||
|
||||
- `system-YYYY-MM-DD.log`:系统资源监控日志
|
||||
- `database-YYYY-MM-DD.log`:数据库性能监控日志
|
||||
- `system-error-YYYY-MM-DD.log`:系统监控错误日志
|
||||
- `database-error-YYYY-MM-DD.log`:数据库监控错误日志
|
||||
|
||||
## 扩展和定制
|
||||
|
||||
### 添加新的监控指标
|
||||
|
||||
要添加新的监控指标,需要修改以下文件:
|
||||
|
||||
1. `performance-monitor.js`:添加新的指标收集和处理逻辑
|
||||
2. `performance-routes.js`:添加新的API端点
|
||||
3. `PerformanceMonitor.vue`:添加新的UI组件展示指标
|
||||
|
||||
### 集成外部监控系统
|
||||
|
||||
性能监控系统可以与外部监控系统集成,如Prometheus、Grafana或ELK堆栈:
|
||||
|
||||
```javascript
|
||||
// 示例:将性能指标导出到Prometheus
|
||||
const client = require('prom-client');
|
||||
const register = new client.Registry();
|
||||
|
||||
// 创建指标
|
||||
const cpuGauge = new client.Gauge({
|
||||
name: 'cpu_usage_percent',
|
||||
help: 'CPU使用率百分比',
|
||||
registers: [register]
|
||||
});
|
||||
|
||||
// 更新指标
|
||||
perfEvents.on('systemMetrics', (metrics) => {
|
||||
cpuGauge.set(metrics.cpuUsage.usage);
|
||||
});
|
||||
|
||||
// 暴露指标端点
|
||||
app.get('/metrics', (req, res) => {
|
||||
res.set('Content-Type', register.contentType);
|
||||
res.end(register.metrics());
|
||||
});
|
||||
```
|
||||
|
||||
## 结论
|
||||
|
||||
性能监控系统提供了全面的工具,用于监控和优化应用程序的性能。通过实时跟踪系统资源、数据库性能和API响应时间,可以及早发现潜在问题,提高应用程序的可靠性和用户体验。
|
||||
|
||||
定期查看性能指标,设置合理的警报阈值,并根据性能数据进行优化,可以显著提高应用程序的性能和稳定性。
|
||||
597
docs/operations/监控运维文档.md
Normal file
597
docs/operations/监控运维文档.md
Normal file
@@ -0,0 +1,597 @@
|
||||
# 宁夏智慧养殖监管平台监控运维文档
|
||||
|
||||
## 版本历史
|
||||
|
||||
| 版本 | 日期 | 修改内容 | 修改人 |
|
||||
|------|------|----------|--------|
|
||||
| v1.0 | 2025-01-19 | 初始版本 | 运维团队 |
|
||||
|
||||
## 1. 监控概述
|
||||
|
||||
### 1.1 监控目标
|
||||
- 确保系统7x24小时稳定运行
|
||||
- 及时发现和处理系统异常
|
||||
- 提供性能数据支持系统优化
|
||||
- 保障用户体验和业务连续性
|
||||
|
||||
### 1.2 监控范围
|
||||
- **基础设施监控**: 服务器、网络、存储
|
||||
- **应用监控**: 后端服务、前端应用、数据库
|
||||
- **业务监控**: 关键业务指标、用户行为
|
||||
- **安全监控**: 安全事件、异常访问
|
||||
|
||||
## 2. 监控架构
|
||||
|
||||
### 2.1 监控组件
|
||||
```mermaid
|
||||
graph TB
|
||||
A[应用服务] --> B[日志收集]
|
||||
A --> C[指标收集]
|
||||
B --> D[日志分析]
|
||||
C --> E[监控平台]
|
||||
D --> F[告警系统]
|
||||
E --> F
|
||||
F --> G[运维人员]
|
||||
```
|
||||
|
||||
### 2.2 技术栈
|
||||
- **监控平台**: Prometheus + Grafana
|
||||
- **日志收集**: ELK Stack (Elasticsearch + Logstash + Kibana)
|
||||
- **告警系统**: AlertManager + 钉钉/邮件
|
||||
- **APM**: Node.js 应用性能监控
|
||||
- **健康检查**: 自定义健康检查接口
|
||||
|
||||
## 3. 基础设施监控
|
||||
|
||||
### 3.1 服务器监控
|
||||
|
||||
#### 3.1.1 监控指标
|
||||
- **CPU使用率**: 平均负载、使用率分布
|
||||
- **内存使用**: 内存使用率、可用内存
|
||||
- **磁盘空间**: 磁盘使用率、I/O性能
|
||||
- **网络流量**: 入站/出站流量、连接数
|
||||
|
||||
#### 3.1.2 告警阈值
|
||||
| 指标 | 警告阈值 | 严重阈值 | 处理方式 |
|
||||
|------|----------|----------|----------|
|
||||
| CPU使用率 | 70% | 85% | 自动扩容/人工介入 |
|
||||
| 内存使用率 | 75% | 90% | 重启服务/扩容 |
|
||||
| 磁盘使用率 | 80% | 95% | 清理日志/扩容 |
|
||||
| 网络延迟 | 100ms | 500ms | 检查网络/切换节点 |
|
||||
|
||||
### 3.2 数据库监控
|
||||
|
||||
#### 3.2.1 MySQL监控指标
|
||||
- **连接数**: 当前连接数、最大连接数
|
||||
- **查询性能**: 慢查询、QPS、TPS
|
||||
- **锁状态**: 死锁、锁等待时间
|
||||
- **复制状态**: 主从延迟、复制错误
|
||||
|
||||
#### 3.2.2 监控配置
|
||||
```sql
|
||||
-- 开启慢查询日志
|
||||
SET GLOBAL slow_query_log = 'ON';
|
||||
SET GLOBAL long_query_time = 2;
|
||||
|
||||
-- 监控连接数
|
||||
SHOW STATUS LIKE 'Threads_connected';
|
||||
SHOW STATUS LIKE 'Max_used_connections';
|
||||
|
||||
-- 监控查询性能
|
||||
SHOW STATUS LIKE 'Questions';
|
||||
SHOW STATUS LIKE 'Uptime';
|
||||
```
|
||||
|
||||
## 4. 应用监控
|
||||
|
||||
### 4.1 后端服务监控
|
||||
|
||||
#### 4.1.1 Node.js应用监控
|
||||
```javascript
|
||||
// 健康检查接口
|
||||
app.get('/health', (req, res) => {
|
||||
const healthCheck = {
|
||||
uptime: process.uptime(),
|
||||
message: 'OK',
|
||||
timestamp: Date.now(),
|
||||
memory: process.memoryUsage(),
|
||||
cpu: process.cpuUsage()
|
||||
};
|
||||
|
||||
res.status(200).json(healthCheck);
|
||||
});
|
||||
|
||||
// 性能监控中间件
|
||||
const performanceMonitor = (req, res, next) => {
|
||||
const start = Date.now();
|
||||
|
||||
res.on('finish', () => {
|
||||
const duration = Date.now() - start;
|
||||
console.log(`${req.method} ${req.path} - ${res.statusCode} - ${duration}ms`);
|
||||
});
|
||||
|
||||
next();
|
||||
};
|
||||
```
|
||||
|
||||
#### 4.1.2 关键指标
|
||||
- **响应时间**: API接口响应时间分布
|
||||
- **错误率**: HTTP错误状态码统计
|
||||
- **吞吐量**: 每秒请求数(RPS)
|
||||
- **内存使用**: 堆内存、非堆内存使用情况
|
||||
|
||||
### 4.2 前端应用监控
|
||||
|
||||
#### 4.2.1 性能监控
|
||||
```javascript
|
||||
// 页面加载性能监控
|
||||
window.addEventListener('load', () => {
|
||||
const perfData = performance.getEntriesByType('navigation')[0];
|
||||
const loadTime = perfData.loadEventEnd - perfData.fetchStart;
|
||||
|
||||
// 发送性能数据到监控系统
|
||||
sendMetrics({
|
||||
type: 'page_load',
|
||||
duration: loadTime,
|
||||
url: window.location.href
|
||||
});
|
||||
});
|
||||
|
||||
// 错误监控
|
||||
window.addEventListener('error', (event) => {
|
||||
sendError({
|
||||
message: event.error.message,
|
||||
stack: event.error.stack,
|
||||
url: window.location.href,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
#### 4.2.2 用户体验监控
|
||||
- **页面加载时间**: 首屏加载、完全加载时间
|
||||
- **JavaScript错误**: 运行时错误、资源加载错误
|
||||
- **用户行为**: 页面访问量、用户停留时间
|
||||
- **浏览器兼容性**: 不同浏览器的使用情况
|
||||
|
||||
## 5. 业务监控
|
||||
|
||||
### 5.1 关键业务指标
|
||||
|
||||
#### 5.1.1 用户相关指标
|
||||
- **注册用户数**: 日新增、月活跃用户
|
||||
- **登录成功率**: 登录成功/失败比例
|
||||
- **用户留存率**: 日留存、周留存、月留存
|
||||
|
||||
#### 5.1.2 业务功能指标
|
||||
- **养殖场管理**: 新增养殖场数量、更新频率
|
||||
- **监控数据**: 数据上报成功率、数据完整性
|
||||
- **报表生成**: 报表生成成功率、生成时间
|
||||
|
||||
### 5.2 业务告警规则
|
||||
```yaml
|
||||
# 业务告警配置示例
|
||||
alerts:
|
||||
- name: 登录失败率过高
|
||||
condition: login_failure_rate > 0.1
|
||||
duration: 5m
|
||||
severity: warning
|
||||
|
||||
- name: 数据上报中断
|
||||
condition: data_upload_count == 0
|
||||
duration: 10m
|
||||
severity: critical
|
||||
|
||||
- name: 报表生成失败
|
||||
condition: report_generation_failure_rate > 0.05
|
||||
duration: 3m
|
||||
severity: warning
|
||||
```
|
||||
|
||||
## 6. 日志管理
|
||||
|
||||
### 6.1 日志分类
|
||||
|
||||
#### 6.1.1 应用日志
|
||||
- **访问日志**: HTTP请求记录
|
||||
- **错误日志**: 应用异常和错误
|
||||
- **业务日志**: 关键业务操作记录
|
||||
- **性能日志**: 性能相关数据
|
||||
|
||||
#### 6.1.2 系统日志
|
||||
- **系统日志**: 操作系统级别日志
|
||||
- **数据库日志**: 数据库操作和错误日志
|
||||
- **安全日志**: 安全相关事件记录
|
||||
|
||||
### 6.2 日志格式规范
|
||||
```javascript
|
||||
// 统一日志格式
|
||||
const logFormat = {
|
||||
timestamp: '2025-01-19T10:30:00.000Z',
|
||||
level: 'INFO',
|
||||
service: 'backend-api',
|
||||
module: 'user-management',
|
||||
message: 'User login successful',
|
||||
userId: '12345',
|
||||
ip: '192.168.1.100',
|
||||
userAgent: 'Mozilla/5.0...',
|
||||
requestId: 'req-uuid-12345',
|
||||
duration: 150
|
||||
};
|
||||
```
|
||||
|
||||
### 6.3 日志收集配置
|
||||
```yaml
|
||||
# Logstash配置示例
|
||||
input {
|
||||
file {
|
||||
path => "/var/log/nxxmdata/*.log"
|
||||
start_position => "beginning"
|
||||
codec => json
|
||||
}
|
||||
}
|
||||
|
||||
filter {
|
||||
if [level] == "ERROR" {
|
||||
mutate {
|
||||
add_tag => ["error"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output {
|
||||
elasticsearch {
|
||||
hosts => ["localhost:9200"]
|
||||
index => "nxxmdata-logs-%{+YYYY.MM.dd}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 告警系统
|
||||
|
||||
### 7.1 告警级别
|
||||
|
||||
#### 7.1.1 告警分级
|
||||
- **P0 - 紧急**: 系统完全不可用,需要立即处理
|
||||
- **P1 - 严重**: 核心功能异常,影响用户使用
|
||||
- **P2 - 警告**: 性能下降或非核心功能异常
|
||||
- **P3 - 信息**: 需要关注但不影响正常使用
|
||||
|
||||
#### 7.1.2 告警通知方式
|
||||
| 级别 | 通知方式 | 响应时间 |
|
||||
|------|----------|----------|
|
||||
| P0 | 电话 + 短信 + 钉钉 | 5分钟内 |
|
||||
| P1 | 短信 + 钉钉 + 邮件 | 15分钟内 |
|
||||
| P2 | 钉钉 + 邮件 | 30分钟内 |
|
||||
| P3 | 邮件 | 2小时内 |
|
||||
|
||||
### 7.2 告警规则配置
|
||||
```yaml
|
||||
# Prometheus告警规则
|
||||
groups:
|
||||
- name: system.rules
|
||||
rules:
|
||||
- alert: HighCPUUsage
|
||||
expr: cpu_usage_percent > 85
|
||||
for: 5m
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "CPU使用率过高"
|
||||
description: "服务器CPU使用率超过85%,持续5分钟"
|
||||
|
||||
- alert: DatabaseConnectionHigh
|
||||
expr: mysql_connections_current / mysql_connections_max > 0.8
|
||||
for: 2m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "数据库连接数过高"
|
||||
description: "数据库连接数超过最大连接数的80%"
|
||||
```
|
||||
|
||||
## 8. 性能优化
|
||||
|
||||
### 8.1 性能监控指标
|
||||
|
||||
#### 8.1.1 响应时间优化
|
||||
- **API响应时间**: 目标 < 200ms
|
||||
- **数据库查询时间**: 目标 < 100ms
|
||||
- **页面加载时间**: 目标 < 3s
|
||||
|
||||
#### 8.1.2 并发性能
|
||||
- **最大并发用户数**: 1000+
|
||||
- **数据库连接池**: 合理配置连接数
|
||||
- **缓存命中率**: 目标 > 90%
|
||||
|
||||
### 8.2 优化策略
|
||||
```javascript
|
||||
// Redis缓存配置
|
||||
const redis = require('redis');
|
||||
const client = redis.createClient({
|
||||
host: 'localhost',
|
||||
port: 6379,
|
||||
retry_strategy: (options) => {
|
||||
if (options.error && options.error.code === 'ECONNREFUSED') {
|
||||
return new Error('Redis服务器拒绝连接');
|
||||
}
|
||||
if (options.total_retry_time > 1000 * 60 * 60) {
|
||||
return new Error('重试时间超时');
|
||||
}
|
||||
return Math.min(options.attempt * 100, 3000);
|
||||
}
|
||||
});
|
||||
|
||||
// 数据库连接池配置
|
||||
const pool = mysql.createPool({
|
||||
connectionLimit: 10,
|
||||
host: 'localhost',
|
||||
user: 'root',
|
||||
password: 'password',
|
||||
database: 'nxxmdata',
|
||||
acquireTimeout: 60000,
|
||||
timeout: 60000
|
||||
});
|
||||
```
|
||||
|
||||
## 9. 故障处理
|
||||
|
||||
### 9.1 故障分类
|
||||
|
||||
#### 9.1.1 常见故障类型
|
||||
- **服务不可用**: 应用崩溃、服务器宕机
|
||||
- **性能问题**: 响应慢、超时
|
||||
- **数据问题**: 数据丢失、数据不一致
|
||||
- **安全问题**: 攻击、数据泄露
|
||||
|
||||
#### 9.1.2 故障处理流程
|
||||
1. **故障发现**: 监控告警、用户反馈
|
||||
2. **故障确认**: 验证故障范围和影响
|
||||
3. **应急处理**: 快速恢复服务
|
||||
4. **根因分析**: 分析故障原因
|
||||
5. **永久修复**: 实施根本性解决方案
|
||||
6. **总结改进**: 更新监控和预防措施
|
||||
|
||||
### 9.2 应急预案
|
||||
|
||||
#### 9.2.1 服务不可用处理
|
||||
```bash
|
||||
# 检查服务状态
|
||||
systemctl status nxxmdata-backend
|
||||
systemctl status nginx
|
||||
systemctl status mysql
|
||||
|
||||
# 重启服务
|
||||
systemctl restart nxxmdata-backend
|
||||
systemctl restart nginx
|
||||
|
||||
# 检查日志
|
||||
tail -f /var/log/nxxmdata/error.log
|
||||
tail -f /var/log/nginx/error.log
|
||||
```
|
||||
|
||||
#### 9.2.2 数据库故障处理
|
||||
```bash
|
||||
# 检查数据库状态
|
||||
mysql -u root -p -e "SHOW PROCESSLIST;"
|
||||
mysql -u root -p -e "SHOW ENGINE INNODB STATUS;"
|
||||
|
||||
# 检查磁盘空间
|
||||
df -h
|
||||
du -sh /var/lib/mysql/
|
||||
|
||||
# 数据库备份恢复
|
||||
mysqldump -u root -p nxxmdata > backup.sql
|
||||
mysql -u root -p nxxmdata < backup.sql
|
||||
```
|
||||
|
||||
## 10. 运维自动化
|
||||
|
||||
### 10.1 自动化部署
|
||||
|
||||
#### 10.1.1 CI/CD流程
|
||||
```yaml
|
||||
# GitHub Actions配置
|
||||
name: Deploy to Production
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '18'
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
- name: Run tests
|
||||
run: npm test
|
||||
- name: Build application
|
||||
run: npm run build
|
||||
- name: Deploy to server
|
||||
run: |
|
||||
ssh user@server 'cd /app && git pull && npm install && pm2 restart all'
|
||||
```
|
||||
|
||||
#### 10.1.2 自动化脚本
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# 自动化部署脚本
|
||||
|
||||
set -e
|
||||
|
||||
echo "开始部署..."
|
||||
|
||||
# 备份当前版本
|
||||
cp -r /app/current /app/backup/$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
# 更新代码
|
||||
cd /app/current
|
||||
git pull origin main
|
||||
|
||||
# 安装依赖
|
||||
npm install --production
|
||||
|
||||
# 构建应用
|
||||
npm run build
|
||||
|
||||
# 重启服务
|
||||
pm2 restart all
|
||||
|
||||
# 健康检查
|
||||
sleep 10
|
||||
curl -f http://localhost:3000/health || exit 1
|
||||
|
||||
echo "部署完成!"
|
||||
```
|
||||
|
||||
### 10.2 自动化监控
|
||||
|
||||
#### 10.2.1 健康检查脚本
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# 系统健康检查脚本
|
||||
|
||||
# 检查服务状态
|
||||
services=("nxxmdata-backend" "nginx" "mysql")
|
||||
for service in "${services[@]}"; do
|
||||
if ! systemctl is-active --quiet $service; then
|
||||
echo "警告: $service 服务未运行"
|
||||
systemctl restart $service
|
||||
fi
|
||||
done
|
||||
|
||||
# 检查磁盘空间
|
||||
disk_usage=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
|
||||
if [ $disk_usage -gt 80 ]; then
|
||||
echo "警告: 磁盘使用率超过80%"
|
||||
# 清理日志文件
|
||||
find /var/log -name "*.log" -mtime +7 -delete
|
||||
fi
|
||||
|
||||
# 检查内存使用
|
||||
memory_usage=$(free | awk 'NR==2{printf "%.0f", $3*100/$2}')
|
||||
if [ $memory_usage -gt 85 ]; then
|
||||
echo "警告: 内存使用率超过85%"
|
||||
fi
|
||||
```
|
||||
|
||||
## 11. 备份与恢复
|
||||
|
||||
### 11.1 备份策略
|
||||
|
||||
#### 11.1.1 数据备份
|
||||
- **全量备份**: 每日凌晨2点执行
|
||||
- **增量备份**: 每4小时执行一次
|
||||
- **备份保留**: 本地保留7天,远程保留30天
|
||||
|
||||
#### 11.1.2 备份脚本
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# 数据库备份脚本
|
||||
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_DIR="/backup/mysql"
|
||||
DB_NAME="nxxmdata"
|
||||
|
||||
# 创建备份目录
|
||||
mkdir -p $BACKUP_DIR
|
||||
|
||||
# 执行备份
|
||||
mysqldump -u root -p$MYSQL_PASSWORD \
|
||||
--single-transaction \
|
||||
--routines \
|
||||
--triggers \
|
||||
$DB_NAME > $BACKUP_DIR/nxxmdata_$DATE.sql
|
||||
|
||||
# 压缩备份文件
|
||||
gzip $BACKUP_DIR/nxxmdata_$DATE.sql
|
||||
|
||||
# 上传到云存储
|
||||
aws s3 cp $BACKUP_DIR/nxxmdata_$DATE.sql.gz s3://nxxmdata-backup/
|
||||
|
||||
# 清理本地旧备份
|
||||
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete
|
||||
|
||||
echo "备份完成: nxxmdata_$DATE.sql.gz"
|
||||
```
|
||||
|
||||
### 11.2 恢复流程
|
||||
|
||||
#### 11.2.1 数据库恢复
|
||||
```bash
|
||||
# 停止应用服务
|
||||
systemctl stop nxxmdata-backend
|
||||
|
||||
# 恢复数据库
|
||||
gunzip -c backup_file.sql.gz | mysql -u root -p nxxmdata
|
||||
|
||||
# 验证数据完整性
|
||||
mysql -u root -p -e "SELECT COUNT(*) FROM nxxmdata.users;"
|
||||
|
||||
# 重启服务
|
||||
systemctl start nxxmdata-backend
|
||||
```
|
||||
|
||||
## 12. 安全运维
|
||||
|
||||
### 12.1 安全监控
|
||||
|
||||
#### 12.1.1 安全事件监控
|
||||
- **异常登录**: 异地登录、暴力破解
|
||||
- **SQL注入**: 恶意SQL查询检测
|
||||
- **XSS攻击**: 跨站脚本攻击检测
|
||||
- **文件上传**: 恶意文件上传检测
|
||||
|
||||
#### 12.1.2 安全日志分析
|
||||
```bash
|
||||
# 分析访问日志中的异常请求
|
||||
awk '$9 >= 400 {print $1, $7, $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr
|
||||
|
||||
# 检查失败的登录尝试
|
||||
grep "authentication failure" /var/log/auth.log
|
||||
|
||||
# 监控文件系统变化
|
||||
find /app -type f -mtime -1 -ls
|
||||
```
|
||||
|
||||
### 12.2 安全加固
|
||||
|
||||
#### 12.2.1 系统安全配置
|
||||
```bash
|
||||
# 防火墙配置
|
||||
ufw enable
|
||||
ufw allow 22/tcp
|
||||
ufw allow 80/tcp
|
||||
ufw allow 443/tcp
|
||||
|
||||
# SSH安全配置
|
||||
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
|
||||
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
|
||||
systemctl restart sshd
|
||||
|
||||
# 自动安全更新
|
||||
apt install unattended-upgrades
|
||||
dpkg-reconfigure -plow unattended-upgrades
|
||||
```
|
||||
|
||||
## 13. 联系方式
|
||||
|
||||
### 13.1 运维团队
|
||||
- **运维负责人**: 张三 (zhangsan@nxxmdata.com)
|
||||
- **系统管理员**: 李四 (lisi@nxxmdata.com)
|
||||
- **安全专员**: 王五 (wangwu@nxxmdata.com)
|
||||
|
||||
### 13.2 紧急联系
|
||||
- **24小时值班电话**: 400-xxx-xxxx
|
||||
- **紧急邮箱**: emergency@nxxmdata.com
|
||||
- **钉钉群**: 宁夏智慧养殖运维群
|
||||
|
||||
---
|
||||
|
||||
**文档维护**: 本文档将根据系统运维情况定期更新
|
||||
**最后更新**: 2025-01-19
|
||||
841
docs/operations/部署文档.md
Normal file
841
docs/operations/部署文档.md
Normal file
@@ -0,0 +1,841 @@
|
||||
# 宁夏智慧养殖监管平台部署文档
|
||||
|
||||
## 版本历史
|
||||
|
||||
| 版本 | 日期 | 修改内容 | 修改人 |
|
||||
|------|------|----------|--------|
|
||||
| v1.0 | 2024-01-15 | 初始版本,基础部署流程 | 开发团队 |
|
||||
| v2.0 | 2024-01-20 | 全面重构,增加多端部署和容器化支持 | 开发团队 |
|
||||
|
||||
## 1. 部署概述
|
||||
|
||||
### 1.1 部署架构
|
||||
本平台采用前后端分离架构,支持多端部署:
|
||||
- **后端服务**: Node.js + Express + MySQL
|
||||
- **管理后台**: Vue.js 3 + Ant Design Vue
|
||||
- **官网大屏**: Vue.js 3 + ECharts
|
||||
- **微信小程序**: 原生小程序开发
|
||||
- **移动端应用**: 基于 Vue.js 的响应式设计
|
||||
|
||||
### 1.2 部署环境
|
||||
- **开发环境**: 本地开发调试
|
||||
- **测试环境**: 功能测试和集成测试
|
||||
- **预生产环境**: 性能测试和用户验收
|
||||
- **生产环境**: 正式运行环境
|
||||
|
||||
## 2. 系统要求
|
||||
|
||||
### 2.1 基础要求
|
||||
- **操作系统**: Linux (推荐 Ubuntu 20.04+), CentOS 8+, macOS 11+, Windows 10+
|
||||
- **Node.js**: 18.0+ (推荐 18.17.0)
|
||||
- **MySQL**: 8.0+ (推荐 8.0.33)
|
||||
- **Redis**: 6.0+ (推荐 7.0.11)
|
||||
- **Nginx**: 1.18+ (生产环境)
|
||||
|
||||
### 2.2 硬件要求
|
||||
|
||||
#### 开发环境
|
||||
- **CPU**: 2核心
|
||||
- **内存**: 8GB RAM
|
||||
- **存储**: 50GB 可用空间
|
||||
- **网络**: 10Mbps
|
||||
|
||||
#### 生产环境
|
||||
- **CPU**: 8核心或更高
|
||||
- **内存**: 32GB RAM
|
||||
- **存储**: 500GB SSD
|
||||
- **网络**: 100Mbps 专线
|
||||
- **负载均衡**: 支持高可用部署
|
||||
|
||||
### 2.3 软件依赖
|
||||
```bash
|
||||
# 必需软件
|
||||
- Node.js 18.17.0+
|
||||
- MySQL 8.0.33+
|
||||
- Redis 7.0.11+
|
||||
- PM2 (生产环境进程管理)
|
||||
- Nginx (反向代理和静态文件服务)
|
||||
|
||||
# 可选软件
|
||||
- Docker & Docker Compose (容器化部署)
|
||||
- Git (版本控制)
|
||||
- SSL证书 (HTTPS支持)
|
||||
```
|
||||
|
||||
## 3. 环境准备
|
||||
|
||||
### 3.1 系统环境检查
|
||||
```bash
|
||||
# 检查 Node.js 版本
|
||||
node --version # 应显示 v18.17.0 或更高
|
||||
|
||||
# 检查 npm 版本
|
||||
npm --version # 应显示 9.0.0 或更高
|
||||
|
||||
# 检查 MySQL 版本
|
||||
mysql --version # 应显示 8.0.33 或更高
|
||||
|
||||
# 检查 Redis 版本
|
||||
redis-server --version # 应显示 7.0.11 或更高
|
||||
```
|
||||
|
||||
### 3.2 数据库初始化
|
||||
```sql
|
||||
-- 创建主数据库
|
||||
CREATE DATABASE nxxmdata CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- 创建测试数据库
|
||||
CREATE DATABASE nxxmdata_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- 创建专用用户
|
||||
CREATE USER 'nxxmdata_user'@'%' IDENTIFIED BY 'NxxmData2024!@#';
|
||||
GRANT ALL PRIVILEGES ON nxxmdata.* TO 'nxxmdata_user'@'%';
|
||||
GRANT ALL PRIVILEGES ON nxxmdata_test.* TO 'nxxmdata_user'@'%';
|
||||
FLUSH PRIVILEGES;
|
||||
|
||||
-- 优化配置
|
||||
SET GLOBAL innodb_buffer_pool_size = 2147483648; -- 2GB
|
||||
SET GLOBAL max_connections = 1000;
|
||||
SET GLOBAL query_cache_size = 268435456; -- 256MB
|
||||
```
|
||||
|
||||
### 3.3 Redis 配置
|
||||
```bash
|
||||
# Redis 配置文件 /etc/redis/redis.conf
|
||||
bind 127.0.0.1
|
||||
port 6379
|
||||
timeout 300
|
||||
tcp-keepalive 60
|
||||
maxmemory 1gb
|
||||
maxmemory-policy allkeys-lru
|
||||
save 900 1
|
||||
save 300 10
|
||||
save 60 10000
|
||||
```
|
||||
|
||||
## 4. 源码部署
|
||||
|
||||
### 4.1 获取源码
|
||||
```bash
|
||||
# 方式1: Git克隆
|
||||
git clone https://github.com/your-org/nxxmdata.git
|
||||
cd nxxmdata
|
||||
|
||||
# 方式2: 下载压缩包
|
||||
wget https://github.com/your-org/nxxmdata/archive/main.zip
|
||||
unzip main.zip
|
||||
cd nxxmdata-main
|
||||
|
||||
# 检查项目结构
|
||||
ls -la
|
||||
# 应该看到: backend/, admin-system/, website/, mini-app/, docs/
|
||||
```
|
||||
|
||||
### 4.2 后端服务部署
|
||||
|
||||
#### 4.2.1 安装依赖
|
||||
```bash
|
||||
cd backend
|
||||
npm install --production
|
||||
|
||||
# 安装全局依赖
|
||||
npm install -g pm2 nodemon
|
||||
```
|
||||
|
||||
#### 4.2.2 环境配置
|
||||
创建 `backend/.env` 文件:
|
||||
```bash
|
||||
# 应用配置
|
||||
NODE_ENV=production
|
||||
PORT=5350
|
||||
APP_NAME=宁夏智慧养殖监管平台
|
||||
|
||||
# 数据库配置
|
||||
DB_HOST=localhost
|
||||
DB_PORT=3306
|
||||
DB_NAME=nxxmdata
|
||||
DB_USER=nxxmdata_user
|
||||
DB_PASSWORD=NxxmData2024!@#
|
||||
DB_POOL_MIN=5
|
||||
DB_POOL_MAX=20
|
||||
|
||||
# Redis配置
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
REDIS_PASSWORD=
|
||||
REDIS_DB=0
|
||||
|
||||
# JWT配置
|
||||
JWT_SECRET=nxxmdata_jwt_secret_2024_very_secure_key
|
||||
JWT_EXPIRES_IN=24h
|
||||
JWT_REFRESH_EXPIRES_IN=7d
|
||||
|
||||
# 文件上传配置
|
||||
UPLOAD_PATH=/var/www/nxxmdata/uploads
|
||||
MAX_FILE_SIZE=10485760
|
||||
ALLOWED_FILE_TYPES=jpg,jpeg,png,gif,pdf,doc,docx,xls,xlsx
|
||||
|
||||
# 第三方服务配置
|
||||
BAIDU_MAP_AK=your_baidu_map_api_key
|
||||
WECHAT_APPID=your_wechat_appid
|
||||
WECHAT_SECRET=your_wechat_secret
|
||||
|
||||
# 邮件配置
|
||||
SMTP_HOST=smtp.qq.com
|
||||
SMTP_PORT=587
|
||||
SMTP_USER=your_email@qq.com
|
||||
SMTP_PASS=your_email_password
|
||||
|
||||
# 日志配置
|
||||
LOG_LEVEL=info
|
||||
LOG_PATH=/var/log/nxxmdata
|
||||
```
|
||||
|
||||
#### 4.2.3 数据库迁移
|
||||
```bash
|
||||
# 运行数据库迁移
|
||||
npm run migrate
|
||||
|
||||
# 初始化基础数据
|
||||
npm run seed
|
||||
|
||||
# 验证数据库连接
|
||||
npm run db:check
|
||||
```
|
||||
|
||||
#### 4.2.4 启动后端服务
|
||||
```bash
|
||||
# 开发环境
|
||||
npm run dev
|
||||
|
||||
# 生产环境
|
||||
npm run start
|
||||
|
||||
# 使用PM2管理进程
|
||||
pm2 start ecosystem.config.js
|
||||
pm2 save
|
||||
pm2 startup
|
||||
```
|
||||
|
||||
### 4.3 管理后台部署
|
||||
|
||||
#### 4.3.1 安装依赖
|
||||
```bash
|
||||
cd admin-system
|
||||
npm install
|
||||
```
|
||||
|
||||
#### 4.3.2 环境配置
|
||||
创建 `admin-system/.env.production` 文件:
|
||||
```bash
|
||||
# API配置
|
||||
VITE_API_BASE_URL=https://api.nxxmdata.com
|
||||
VITE_API_TIMEOUT=30000
|
||||
|
||||
# 应用配置
|
||||
VITE_APP_TITLE=宁夏智慧养殖监管平台
|
||||
VITE_APP_VERSION=2.0.0
|
||||
VITE_APP_ENV=production
|
||||
|
||||
# 地图配置
|
||||
VITE_BAIDU_MAP_AK=your_baidu_map_api_key
|
||||
|
||||
# 文件上传配置
|
||||
VITE_UPLOAD_URL=https://api.nxxmdata.com/api/upload
|
||||
VITE_MAX_FILE_SIZE=10485760
|
||||
|
||||
# 功能开关
|
||||
VITE_ENABLE_MOCK=false
|
||||
VITE_ENABLE_DEBUG=false
|
||||
```
|
||||
|
||||
#### 4.3.3 构建和部署
|
||||
```bash
|
||||
# 构建生产版本
|
||||
npm run build
|
||||
|
||||
# 检查构建结果
|
||||
ls -la dist/
|
||||
|
||||
# 部署到Web服务器
|
||||
sudo cp -r dist/* /var/www/nxxmdata/admin/
|
||||
sudo chown -R www-data:www-data /var/www/nxxmdata/admin/
|
||||
```
|
||||
|
||||
### 4.4 官网大屏部署
|
||||
|
||||
#### 4.4.1 安装依赖
|
||||
```bash
|
||||
cd website
|
||||
npm install
|
||||
```
|
||||
|
||||
#### 4.4.2 环境配置
|
||||
创建 `website/.env.production` 文件:
|
||||
```bash
|
||||
# API配置
|
||||
VITE_API_BASE_URL=https://api.nxxmdata.com
|
||||
VITE_WS_URL=wss://api.nxxmdata.com/ws
|
||||
|
||||
# 大屏配置
|
||||
VITE_SCREEN_WIDTH=1920
|
||||
VITE_SCREEN_HEIGHT=1080
|
||||
VITE_AUTO_REFRESH_INTERVAL=30000
|
||||
|
||||
# 地图配置
|
||||
VITE_BAIDU_MAP_AK=your_baidu_map_api_key
|
||||
VITE_MAP_CENTER_LNG=106.2309
|
||||
VITE_MAP_CENTER_LAT=38.4872
|
||||
```
|
||||
|
||||
#### 4.4.3 构建和部署
|
||||
```bash
|
||||
# 构建生产版本
|
||||
npm run build
|
||||
|
||||
# 部署到Web服务器
|
||||
sudo cp -r dist/* /var/www/nxxmdata/screen/
|
||||
sudo chown -R www-data:www-data /var/www/nxxmdata/screen/
|
||||
```
|
||||
|
||||
### 4.5 微信小程序部署
|
||||
|
||||
#### 4.5.1 配置小程序
|
||||
编辑 `mini-app/project.config.json`:
|
||||
```json
|
||||
{
|
||||
"appid": "your_wechat_miniprogram_appid",
|
||||
"projectname": "宁夏智慧养殖监管平台",
|
||||
"setting": {
|
||||
"urlCheck": true,
|
||||
"es6": true,
|
||||
"enhance": true,
|
||||
"postcss": true,
|
||||
"minified": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.5.2 配置API地址
|
||||
编辑 `mini-app/config/index.js`:
|
||||
```javascript
|
||||
const config = {
|
||||
development: {
|
||||
baseURL: 'https://dev-api.nxxmdata.com'
|
||||
},
|
||||
production: {
|
||||
baseURL: 'https://api.nxxmdata.com'
|
||||
}
|
||||
}
|
||||
|
||||
export default config[process.env.NODE_ENV || 'production']
|
||||
```
|
||||
|
||||
#### 4.5.3 上传发布
|
||||
```bash
|
||||
# 使用微信开发者工具上传代码
|
||||
# 或使用命令行工具
|
||||
npm install -g miniprogram-ci
|
||||
npm run upload
|
||||
```
|
||||
|
||||
## 5. Nginx 配置
|
||||
|
||||
### 5.1 安装 Nginx
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt update
|
||||
sudo apt install nginx
|
||||
|
||||
# CentOS/RHEL
|
||||
sudo yum install nginx
|
||||
```
|
||||
|
||||
### 5.2 配置文件
|
||||
创建 `/etc/nginx/sites-available/nxxmdata` 文件:
|
||||
```nginx
|
||||
# 管理后台配置
|
||||
server {
|
||||
listen 80;
|
||||
server_name admin.nxxmdata.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name admin.nxxmdata.com;
|
||||
|
||||
ssl_certificate /etc/ssl/certs/nxxmdata.crt;
|
||||
ssl_certificate_key /etc/ssl/private/nxxmdata.key;
|
||||
|
||||
root /var/www/nxxmdata/admin;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api {
|
||||
proxy_pass http://localhost:5350;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /uploads {
|
||||
alias /var/www/nxxmdata/uploads;
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
|
||||
# 大屏展示配置
|
||||
server {
|
||||
listen 80;
|
||||
server_name screen.nxxmdata.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name screen.nxxmdata.com;
|
||||
|
||||
ssl_certificate /etc/ssl/certs/nxxmdata.crt;
|
||||
ssl_certificate_key /etc/ssl/private/nxxmdata.key;
|
||||
|
||||
root /var/www/nxxmdata/screen;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api {
|
||||
proxy_pass http://localhost:5350;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /ws {
|
||||
proxy_pass http://localhost:5350;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
|
||||
# API服务配置
|
||||
server {
|
||||
listen 80;
|
||||
server_name api.nxxmdata.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name api.nxxmdata.com;
|
||||
|
||||
ssl_certificate /etc/ssl/certs/nxxmdata.crt;
|
||||
ssl_certificate_key /etc/ssl/private/nxxmdata.key;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:5350;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# CORS配置
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
|
||||
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||
|
||||
if ($request_method = 'OPTIONS') {
|
||||
return 204;
|
||||
}
|
||||
}
|
||||
|
||||
location /uploads {
|
||||
alias /var/www/nxxmdata/uploads;
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 启用配置
|
||||
```bash
|
||||
# 创建软链接
|
||||
sudo ln -s /etc/nginx/sites-available/nxxmdata /etc/nginx/sites-enabled/
|
||||
|
||||
# 测试配置
|
||||
sudo nginx -t
|
||||
|
||||
# 重启Nginx
|
||||
sudo systemctl restart nginx
|
||||
sudo systemctl enable nginx
|
||||
```
|
||||
|
||||
## 6. 容器化部署
|
||||
|
||||
### 6.1 Docker 配置
|
||||
|
||||
#### 6.1.1 后端 Dockerfile
|
||||
创建 `backend/Dockerfile`:
|
||||
```dockerfile
|
||||
FROM node:18-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
|
||||
COPY . .
|
||||
|
||||
EXPOSE 5350
|
||||
|
||||
CMD ["npm", "start"]
|
||||
```
|
||||
|
||||
#### 6.1.2 前端 Dockerfile
|
||||
创建 `admin-system/Dockerfile`:
|
||||
```dockerfile
|
||||
FROM node:18-alpine as builder
|
||||
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx:alpine
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
COPY nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
EXPOSE 80
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
```
|
||||
|
||||
### 6.2 Docker Compose 配置
|
||||
创建 `docker-compose.yml`:
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
container_name: nxxmdata-mysql
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: root_password
|
||||
MYSQL_DATABASE: nxxmdata
|
||||
MYSQL_USER: nxxmdata_user
|
||||
MYSQL_PASSWORD: NxxmData2024!@#
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
- ./backend/database/init.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
ports:
|
||||
- "3306:3306"
|
||||
restart: unless-stopped
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: nxxmdata-redis
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
restart: unless-stopped
|
||||
|
||||
backend:
|
||||
build: ./backend
|
||||
container_name: nxxmdata-backend
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
DB_HOST: mysql
|
||||
REDIS_HOST: redis
|
||||
ports:
|
||||
- "5350:5350"
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
volumes:
|
||||
- uploads_data:/app/uploads
|
||||
restart: unless-stopped
|
||||
|
||||
admin:
|
||||
build: ./admin-system
|
||||
container_name: nxxmdata-admin
|
||||
ports:
|
||||
- "8080:80"
|
||||
restart: unless-stopped
|
||||
|
||||
screen:
|
||||
build: ./website
|
||||
container_name: nxxmdata-screen
|
||||
ports:
|
||||
- "8081:80"
|
||||
restart: unless-stopped
|
||||
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: nxxmdata-nginx
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./nginx/ssl:/etc/ssl
|
||||
- uploads_data:/var/www/uploads
|
||||
depends_on:
|
||||
- backend
|
||||
- admin
|
||||
- screen
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
||||
redis_data:
|
||||
uploads_data:
|
||||
```
|
||||
|
||||
### 6.3 容器部署命令
|
||||
```bash
|
||||
# 构建和启动所有服务
|
||||
docker-compose up -d
|
||||
|
||||
# 查看服务状态
|
||||
docker-compose ps
|
||||
|
||||
# 查看日志
|
||||
docker-compose logs -f backend
|
||||
|
||||
# 停止服务
|
||||
docker-compose down
|
||||
|
||||
# 更新服务
|
||||
docker-compose pull
|
||||
docker-compose up -d --force-recreate
|
||||
```
|
||||
|
||||
## 7. 生产环境优化
|
||||
|
||||
### 7.1 性能优化
|
||||
```bash
|
||||
# PM2 集群模式
|
||||
pm2 start ecosystem.config.js --env production
|
||||
|
||||
# Nginx 缓存配置
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# 数据库连接池优化
|
||||
DB_POOL_MIN=10
|
||||
DB_POOL_MAX=50
|
||||
DB_POOL_IDLE=10000
|
||||
DB_POOL_ACQUIRE=60000
|
||||
```
|
||||
|
||||
### 7.2 安全配置
|
||||
```bash
|
||||
# 防火墙配置
|
||||
sudo ufw allow 22/tcp
|
||||
sudo ufw allow 80/tcp
|
||||
sudo ufw allow 443/tcp
|
||||
sudo ufw enable
|
||||
|
||||
# SSL证书配置
|
||||
sudo certbot --nginx -d admin.nxxmdata.com -d api.nxxmdata.com -d screen.nxxmdata.com
|
||||
|
||||
# 定期更新证书
|
||||
sudo crontab -e
|
||||
0 12 * * * /usr/bin/certbot renew --quiet
|
||||
```
|
||||
|
||||
### 7.3 监控配置
|
||||
```bash
|
||||
# 安装监控工具
|
||||
npm install -g pm2-logrotate
|
||||
pm2 install pm2-server-monit
|
||||
|
||||
# 日志轮转
|
||||
pm2 set pm2-logrotate:max_size 10M
|
||||
pm2 set pm2-logrotate:retain 30
|
||||
pm2 set pm2-logrotate:compress true
|
||||
```
|
||||
|
||||
## 8. 备份与恢复
|
||||
|
||||
### 8.1 数据库备份
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# 创建备份脚本 /opt/nxxmdata/backup.sh
|
||||
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_DIR="/opt/nxxmdata/backups"
|
||||
DB_NAME="nxxmdata"
|
||||
DB_USER="nxxmdata_user"
|
||||
DB_PASS="NxxmData2024!@#"
|
||||
|
||||
# 创建备份目录
|
||||
mkdir -p $BACKUP_DIR
|
||||
|
||||
# 数据库备份
|
||||
mysqldump -u$DB_USER -p$DB_PASS $DB_NAME > $BACKUP_DIR/db_backup_$DATE.sql
|
||||
|
||||
# 文件备份
|
||||
tar -czf $BACKUP_DIR/files_backup_$DATE.tar.gz /var/www/nxxmdata/uploads
|
||||
|
||||
# 清理7天前的备份
|
||||
find $BACKUP_DIR -name "*.sql" -mtime +7 -delete
|
||||
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete
|
||||
|
||||
echo "Backup completed: $DATE"
|
||||
```
|
||||
|
||||
### 8.2 自动备份
|
||||
```bash
|
||||
# 添加到crontab
|
||||
sudo crontab -e
|
||||
0 2 * * * /opt/nxxmdata/backup.sh >> /var/log/nxxmdata-backup.log 2>&1
|
||||
```
|
||||
|
||||
### 8.3 数据恢复
|
||||
```bash
|
||||
# 恢复数据库
|
||||
mysql -u nxxmdata_user -p nxxmdata < /opt/nxxmdata/backups/db_backup_20240120_020000.sql
|
||||
|
||||
# 恢复文件
|
||||
tar -xzf /opt/nxxmdata/backups/files_backup_20240120_020000.tar.gz -C /
|
||||
```
|
||||
|
||||
## 9. 故障排除
|
||||
|
||||
### 9.1 常见问题
|
||||
|
||||
#### 9.1.1 数据库连接失败
|
||||
```bash
|
||||
# 检查MySQL服务状态
|
||||
sudo systemctl status mysql
|
||||
|
||||
# 检查端口占用
|
||||
netstat -tlnp | grep 3306
|
||||
|
||||
# 检查防火墙
|
||||
sudo ufw status
|
||||
|
||||
# 测试连接
|
||||
mysql -h localhost -u nxxmdata_user -p nxxmdata
|
||||
```
|
||||
|
||||
#### 9.1.2 Node.js 服务异常
|
||||
```bash
|
||||
# 查看PM2进程状态
|
||||
pm2 status
|
||||
|
||||
# 查看应用日志
|
||||
pm2 logs backend
|
||||
|
||||
# 重启应用
|
||||
pm2 restart backend
|
||||
|
||||
# 查看系统资源
|
||||
htop
|
||||
df -h
|
||||
```
|
||||
|
||||
#### 9.1.3 Nginx 配置错误
|
||||
```bash
|
||||
# 测试配置文件
|
||||
sudo nginx -t
|
||||
|
||||
# 查看错误日志
|
||||
sudo tail -f /var/log/nginx/error.log
|
||||
|
||||
# 重新加载配置
|
||||
sudo nginx -s reload
|
||||
```
|
||||
|
||||
### 9.2 性能监控
|
||||
```bash
|
||||
# 系统监控
|
||||
htop
|
||||
iotop
|
||||
nethogs
|
||||
|
||||
# 应用监控
|
||||
pm2 monit
|
||||
|
||||
# 数据库监控
|
||||
SHOW PROCESSLIST;
|
||||
SHOW STATUS LIKE 'Threads_connected';
|
||||
```
|
||||
|
||||
## 10. 维护计划
|
||||
|
||||
### 10.1 日常维护
|
||||
- **每日**: 检查系统日志和应用状态
|
||||
- **每周**: 检查磁盘空间和数据库性能
|
||||
- **每月**: 更新系统补丁和依赖包
|
||||
- **每季度**: 性能评估和容量规划
|
||||
|
||||
### 10.2 更新流程
|
||||
```bash
|
||||
# 1. 备份当前版本
|
||||
./backup.sh
|
||||
|
||||
# 2. 下载新版本
|
||||
git pull origin main
|
||||
|
||||
# 3. 更新依赖
|
||||
cd backend && npm install
|
||||
cd ../admin-system && npm install && npm run build
|
||||
|
||||
# 4. 数据库迁移
|
||||
npm run migrate
|
||||
|
||||
# 5. 重启服务
|
||||
pm2 restart all
|
||||
|
||||
# 6. 验证功能
|
||||
curl -f http://localhost:5350/api/health
|
||||
```
|
||||
|
||||
### 10.3 回滚计划
|
||||
```bash
|
||||
# 1. 停止服务
|
||||
pm2 stop all
|
||||
|
||||
# 2. 恢复代码
|
||||
git checkout previous-stable-tag
|
||||
|
||||
# 3. 恢复数据库
|
||||
mysql -u nxxmdata_user -p nxxmdata < backup.sql
|
||||
|
||||
# 4. 重启服务
|
||||
pm2 start all
|
||||
```
|
||||
|
||||
## 11. 联系支持
|
||||
|
||||
### 11.1 技术支持
|
||||
- **邮箱**: support@nxxmdata.com
|
||||
- **电话**: 400-xxx-xxxx
|
||||
- **工作时间**: 周一至周五 9:00-18:00
|
||||
|
||||
### 11.2 紧急联系
|
||||
- **24小时热线**: 138-xxxx-xxxx
|
||||
- **微信群**: 宁夏智慧养殖技术支持群
|
||||
|
||||
---
|
||||
|
||||
**注意**: 本文档会根据系统更新持续维护,请定期查看最新版本。
|
||||
Reference in New Issue
Block a user