1. 项目概述与部署准备
"录用通知-自助系统"是一款基于Node.js和PostgreSQL开发的企业级应用,主要用于自动化生成和管理员工录用通知书。系统采用前后端分离架构,前端使用现代JavaScript框架(如React或Vue),后端基于Express.js构建,数据库采用PostgreSQL。这套系统特别适合HR部门使用,可以大幅提升录用流程的效率和规范性。
1.1 系统架构解析
整个系统采用典型的三层架构设计:
- 前端层:静态文件服务,运行在3000端口
- 应用层:Node.js后端服务,运行在4000端口
- 数据层:PostgreSQL数据库,运行在5432端口
Nginx作为反向代理和负载均衡器,对外暴露80/443端口,同时处理HTTPS加密和静态文件缓存。这种架构设计有以下几个优势:
- 前后端完全解耦,可以独立开发和部署
- Nginx提供高效的文件服务和负载均衡
- PM2保障Node.js进程的稳定运行
- 数据库与应用分离,便于扩展和维护
1.2 服务器选型建议
根据实际使用场景,我们推荐以下服务器配置方案:
小型企业(日访问量<1000)
- 云服务器:2核CPU/4GB内存/50GB SSD
- 带宽:5Mbps
- 操作系统:Ubuntu 22.04 LTS
中型企业(日访问量1000-5000)
- 云服务器:4核CPU/8GB内存/100GB SSD
- 带宽:10Mbps
- 操作系统:Ubuntu 22.04 LTS + 数据库独立实例
大型企业(日访问量>5000)
- 建议采用Kubernetes集群部署
- 前端、后端、数据库分别独立部署
- 考虑使用RDS替代自建PostgreSQL
提示:如果预算允许,建议将数据库部署在独立的服务器上,这样可以获得更好的性能和稳定性。
2. 服务器基础环境配置
2.1 系统初始化设置
首次登录服务器后,建议按以下顺序进行基础配置:
# 更新系统软件包(Ubuntu/Debian) sudo apt update && sudo apt upgrade -y # 安装常用工具 sudo apt install -y curl wget git unzip htop # 创建专用部署用户(非root操作更安全) sudo adduser deploy sudo usermod -aG sudo deploy # 配置SSH密钥登录(更安全) mkdir -p ~/.ssh chmod 700 ~/.ssh vim ~/.ssh/authorized_keys # 粘贴你的公钥 chmod 600 ~/.ssh/authorized_keys # 禁用密码登录(提升安全性) sudo vim /etc/ssh/sshd_config # 修改以下参数: PasswordAuthentication no PermitRootLogin no sudo systemctl restart sshd2.2 Node.js环境配置
我们推荐使用Node.js 18.x LTS版本,它提供了更好的性能和稳定性:
# 安装NodeSource仓库 curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - # 安装Node.js和npm sudo apt install -y nodejs # 验证安装 node -v # 应显示v18.x.x npm -v # 应显示8.x.x # 配置npm全局安装路径(避免使用sudo) mkdir ~/.npm-global npm config set prefix '~/.npm-global' echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc source ~/.bashrc # 安装PM2进程管理器 npm install -g pm2 pm2 install pm2-logrotate # 日志轮转插件 pm2 set pm2-logrotate:max_size 10M # 单个日志文件最大10MB pm2 set pm2-logrotate:retain 30 # 保留30个日志文件2.3 系统优化设置
为了获得更好的性能,建议进行以下系统调优:
# 增加文件描述符限制(Node.js需要) echo "* soft nofile 65535" | sudo tee -a /etc/security/limits.conf echo "* hard nofile 65535" | sudo tee -a /etc/security/limits.conf # 调整内核参数 echo "fs.file-max = 65535" | sudo tee -a /etc/sysctl.conf echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf sudo sysctl -p # 禁用交换分区(对数据库性能很重要) sudo swapoff -a sudo sed -i '/swap/d' /etc/fstab # 配置时区(确保时间准确) sudo timedatectl set-timezone Asia/Shanghai sudo apt install -y ntp sudo systemctl enable ntp3. PostgreSQL数据库部署
3.1 数据库安装与配置
PostgreSQL 12+版本提供了更好的JSON支持和性能优化:
# Ubuntu/Debian安装 sudo apt install -y postgresql postgresql-contrib # 启动服务并设置开机自启 sudo systemctl start postgresql sudo systemctl enable postgresql # 修改默认配置 sudo vim /etc/postgresql/14/main/postgresql.conf # 调整以下参数: listen_addresses = 'localhost' max_connections = 100 shared_buffers = 1GB # 建议为内存的25% effective_cache_size = 3GB # 建议为内存的50-75% work_mem = 16MB # 每个查询可用的内存 maintenance_work_mem = 256MB3.2 数据库用户与权限
为应用创建专用数据库用户和数据库:
# 切换到postgres用户 sudo -u postgres psql -- 创建数据库 CREATE DATABASE acceptance_notices WITH ENCODING 'UTF8' LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8'; -- 创建应用用户 CREATE USER notice_user WITH PASSWORD 'your_secure_password'; -- 设置权限 GRANT ALL PRIVILEGES ON DATABASE acceptance_notices TO notice_user; ALTER DATABASE acceptance_notices OWNER TO notice_user; -- 创建扩展(如需要) CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE EXTENSION IF NOT EXISTS "pgcrypto"; -- 退出 \q3.3 数据库性能优化
对于生产环境,还需要进行以下优化:
# 配置pg_hba.conf sudo vim /etc/postgresql/14/main/pg_hba.conf # 添加以下行(仅允许本地连接) host acceptance_notices notice_user 127.0.0.1/32 md5 # 配置连接池(提高性能) sudo apt install -y pgpool2 # 定期维护任务(添加到crontab) 0 3 * * * /usr/bin/vacuumdb -U postgres -d acceptance_notices -z -v 0 4 * * * /usr/bin/reindexdb -U postgres -d acceptance_notices -v4. 后端服务部署
4.1 代码结构与部署
后端代码应该部署在/var/www目录下,保持规范的目录结构:
# 创建项目目录 sudo mkdir -p /var/www/acceptance-notice/backend sudo chown -R deploy:deploy /var/www/acceptance-notice # 克隆代码(或上传) git clone https://your-repo-url.git /var/www/acceptance-notice/backend # 安装依赖 cd /var/www/acceptance-notice/backend npm install --production # 设置环境变量 cp .env.example .env vim .env # 根据实际情况修改4.2 环境变量配置
.env文件需要包含以下关键配置:
# 应用配置 NODE_ENV=production PORT=4000 # 数据库配置 DATABASE_URL=postgresql://notice_user:your_password@localhost:5432/acceptance_notices DATABASE_POOL_MIN=2 DATABASE_POOL_MAX=10 # JWT配置 JWT_SECRET=your_very_secure_random_string JWT_EXPIRES_IN=30d # 文件存储 STORAGE_ROOT=/var/www/acceptance-notice/storage UPLOAD_LIMIT=50mb # 邮件服务(如需要) SMTP_HOST=smtp.yourdomain.com SMTP_PORT=587 SMTP_USER=your_email@domain.com SMTP_PASS=your_email_password4.3 PM2进程管理
使用PM2管理Node.js进程可以提供更好的稳定性和监控:
# 启动服务 pm2 start src/server.js --name "acceptance-backend" \ -i max \ --log-date-format "YYYY-MM-DD HH:mm:ss" \ --output "/var/log/acceptance-backend.out.log" \ --error "/var/log/acceptance-backend.err.log" \ --time # 设置开机自启 pm2 startup # 执行输出的命令 pm2 save # 监控日志 pm2 logs acceptance-backend --lines 100 # 性能监控 pm2 monit5. 前端服务部署
5.1 构建生产版本
前端项目需要构建为静态文件:
cd /var/www/acceptance-notice/frontend # 安装依赖 npm install # 配置环境变量 cp .env.production .env vim .env # 修改API地址等配置 # 构建生产版本 npm run build # 检查构建结果 ls -lh dist/5.2 Nginx配置优化
Nginx配置需要考虑以下优化点:
# /etc/nginx/sites-available/acceptance-notice server { listen 80; server_name yourdomain.com www.yourdomain.com; root /var/www/acceptance-notice/frontend/dist; index index.html; # 性能优化 sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; # Gzip压缩 gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml; # 静态资源缓存 location ~* \.(?:ico|css|js|gif|jpe?g|png|svg|woff2?|eot|ttf|otf)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; } # 前端路由处理 location / { try_files $uri $uri/ /index.html; } # 禁止访问.git等隐藏文件 location ~ /\. { deny all; access_log off; log_not_found off; } }5.3 HTTPS安全配置
使用Let's Encrypt免费SSL证书:
# 安装Certbot sudo apt install -y certbot python3-certbot-nginx # 获取证书(需要域名已解析) sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com # 自动续期测试 sudo certbot renew --dry-run # 配置自动续期(添加到crontab) 0 12 * * * /usr/bin/certbot renew --quiet6. 系统监控与维护
6.1 基础监控设置
# 安装基础监控工具 sudo apt install -y htop iotop iftop nmon # 日志轮转配置 sudo vim /etc/logrotate.d/acceptance-notice /var/log/acceptance-*.log { daily missingok rotate 30 compress delaycompress notifempty create 640 deploy deploy sharedscripts postrotate pm2 reloadLogs > /dev/null endscript }6.2 备份策略
# 数据库备份脚本 #!/bin/bash DATE=$(date +%Y%m%d) BACKUP_DIR="/backups/db" mkdir -p $BACKUP_DIR pg_dump -U notice_user -d acceptance_notices -F c -f $BACKUP_DIR/acceptance_db_$DATE.dump # 文件备份 tar -czf /backups/files/acceptance_files_$DATE.tar.gz /var/www/acceptance-notice/storage # 添加到crontab(每天凌晨2点执行) 0 2 * * * /path/to/backup_script.sh6.3 性能调优检查清单
数据库检查
- 定期执行VACUUM和ANALYZE
- 监控慢查询日志
- 检查索引使用情况
Node.js检查
- 监控内存泄漏
- 检查事件循环延迟
- 优化CPU密集型任务
系统层面
- 监控磁盘I/O
- 检查网络吞吐量
- 观察内存使用情况
7. 常见问题排查指南
7.1 数据库连接问题
症状:应用启动时报数据库连接错误
排查步骤:
- 检查PostgreSQL服务状态:
sudo systemctl status postgresql - 测试本地连接:
psql -h localhost -U notice_user -d acceptance_notices - 检查连接数限制:
show max_connections; - 查看当前连接:
SELECT * FROM pg_stat_activity;
解决方案:
- 增加连接池大小
- 优化查询减少长连接
- 调整PostgreSQL配置
7.2 文件上传失败
症状:上传大文件时报413错误或超时
排查步骤:
- 检查Nginx配置:
client_max_body_size 50M; - 检查Node.js body-parser限制
- 检查磁盘空间:
df -h - 检查目录权限:
ls -la /var/www/acceptance-notice/storage
解决方案:
- 调整Nginx和Node.js的上传限制
- 确保存储目录有足够空间和正确权限
- 考虑分片上传大文件
7.3 性能瓶颈分析
症状:系统响应变慢,CPU或内存使用率高
排查工具:
# 系统级别 top htop vmstat 1 iostat -x 1 # Node.js级别 pm2 monit node --inspect-brk server.js # Chrome DevTools调试 # 数据库级别 pg_stat_statements EXPLAIN ANALYZE [你的慢查询]优化建议:
- 添加数据库索引
- 优化复杂查询
- 实现缓存层(Redis)
- 考虑水平扩展
8. 安全加固措施
8.1 基础安全配置
# 防火墙设置(UFW) sudo ufw allow 22/tcp # SSH sudo ufw allow 80/tcp # HTTP sudo ufw allow 443/tcp # HTTPS sudo ufw enable # SSH加固 sudo vim /etc/ssh/sshd_config # 修改以下参数: PermitRootLogin no PasswordAuthentication no AllowUsers deploy LoginGraceTime 1m MaxAuthTries 3 MaxSessions 2 # 定期安全更新 sudo apt install -y unattended-upgrades sudo dpkg-reconfigure -plow unattended-upgrades8.2 应用安全建议
API安全
- 实现速率限制
- 添加请求验证
- 使用Helmet中间件
数据安全
- 敏感字段加密存储
- 实现数据访问控制
- 定期备份验证
依赖安全
- 使用
npm audit检查漏洞 - 定期更新依赖
- 锁定版本号
- 使用
8.3 监控与告警
# 安装基础监控工具 sudo apt install -y fail2ban logwatch # 配置关键指标监控 # 使用Prometheus + Grafana监控: # - 系统资源使用率 # - 应用响应时间 # - 数据库性能指标 # - 错误率监控 # 设置告警规则 # - CPU持续>80%超过5分钟 # - 内存使用>90% # - 磁盘空间<20% # - HTTP 5xx错误增加9. 升级与维护流程
9.1 代码更新流程
# 标准更新流程 cd /var/www/acceptance-notice # 拉取最新代码 git pull origin main # 后端更新 cd backend npm install --production npm run migrate # 如有数据库变更 pm2 restart acceptance-backend # 前端更新 cd ../frontend npm install npm run build pm2 restart acceptance-frontend # 验证更新 curl -I https://yourdomain.com9.2 数据库迁移策略
小版本升级(如12.1→12.2)
- 直接使用pg_dump/pg_restore
- 停机时间短
大版本升级(如12→13)
- 使用逻辑复制
- 设置只读窗口期
- 考虑使用pg_upgrade
零停机方案
- 设置副本服务器
- 使用逻辑复制同步数据
- 切换DNS指向新服务器
9.3 灾难恢复计划
恢复优先级
- 数据库 → 应用代码 → 上传文件
恢复步骤
# 恢复数据库 pg_restore -U notice_user -d acceptance_notices -F c /backups/db/latest.dump # 恢复代码 git clone https://your-repo-url.git /var/www/acceptance-notice # 恢复文件 tar -xzf /backups/files/latest.tar.gz -C /定期演练
- 每季度执行一次恢复测试
- 记录恢复时间和问题
- 持续改进恢复流程
10. 高级部署方案
10.1 Docker化部署
# backend/Dockerfile FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm install --production COPY . . EXPOSE 4000 CMD ["npm", "start"]# docker-compose.yml示例 version: '3.8' services: db: image: postgres:14 environment: POSTGRES_USER: notice_user POSTGRES_PASSWORD: your_password POSTGRES_DB: acceptance_notices volumes: - pg_data:/var/lib/postgresql/data ports: - "5432:5432" backend: build: ./backend environment: DATABASE_URL: postgresql://notice_user:your_password@db:5432/acceptance_notices ports: - "4000:4000" depends_on: - db frontend: build: ./frontend ports: - "3000:3000" nginx: image: nginx:alpine volumes: - ./nginx.conf:/etc/nginx/nginx.conf ports: - "80:80" - "443:443" depends_on: - backend - frontend volumes: pg_data:10.2 Kubernetes部署
# deployment.yaml示例 apiVersion: apps/v1 kind: Deployment metadata: name: acceptance-backend spec: replicas: 3 selector: matchLabels: app: acceptance-backend template: metadata: labels: app: acceptance-backend spec: containers: - name: backend image: your-registry/acceptance-backend:latest ports: - containerPort: 4000 envFrom: - configMapRef: name: backend-config --- apiVersion: v1 kind: Service metadata: name: acceptance-backend spec: selector: app: acceptance-backend ports: - protocol: TCP port: 4000 targetPort: 400010.3 高可用架构设计
推荐架构:
[负载均衡器] | ------------------------------- | | | [前端集群] [后端集群] [数据库集群] (3节点) (3节点) (主从复制)关键组件:
- 前端层:多实例+CDN
- 应用层:无状态服务,自动扩展
- 数据层:PostgreSQL主从+读写分离
- 缓存层:Redis集群
- 监控层:Prometheus+Alertmanager+Grafana
实现要点:
- 使用Terraform管理基础设施
- 通过CI/CD实现自动化部署
- 配置自动扩展策略
- 实现多区域部署
11. 性能优化进阶
11.1 数据库查询优化
-- 常用优化技巧 -- 1. 添加适当索引 CREATE INDEX idx_employee_name ON employees(name); -- 2. 避免SELECT * SELECT id, name, position FROM employees; -- 3. 使用EXPLAIN分析 EXPLAIN ANALYZE SELECT * FROM notices WHERE status = 'pending'; -- 4. 批量操作替代循环 -- 不好 UPDATE employees SET updated_at = NOW() WHERE id = 1; UPDATE employees SET updated_at = NOW() WHERE id = 2; -- 好 UPDATE employees SET updated_at = NOW() WHERE id IN (1, 2); -- 5. 使用连接替代子查询 -- 不好 SELECT name FROM employees WHERE department_id IN (SELECT id FROM departments WHERE active = true); -- 好 SELECT e.name FROM employees e JOIN departments d ON e.department_id = d.id WHERE d.active = true;11.2 Node.js性能调优
// 1. 使用Cluster模式 const cluster = require('cluster'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { for (let i = 0; i < numCPUs; i++) { cluster.fork(); } } else { require('./server'); } // 2. 优化中间件顺序 app.use(compression()); // 最先压缩 app.use(helmet()); // 安全头 app.use(cors()); // CORS app.use(express.json()); // 解析JSON // 3. 实现缓存 const cache = require('express-redis-cache')(); app.get('/api/notices', cache.route(), (req, res) => { // 你的逻辑 }); // 4. 使用Stream处理大文件 app.get('/download', (req, res) => { const fileStream = fs.createReadStream('/path/to/large/file'); fileStream.pipe(res); });11.3 前端性能优化
// 1. 代码分割 const Home = React.lazy(() => import('./Home')); // 2. 图片优化 // 使用WebP格式 // 实现懒加载 <img loading="lazy" src="image.webp" alt="..."> // 3. API请求优化 // 使用GraphQL减少请求字段 // 实现请求去重 // 添加客户端缓存 // 4. 预加载关键资源 <link rel="preload" href="critical.css" as="style"> <link rel="preload" href="app.js" as="script"> // 5. 使用Service Worker缓存 if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/sw.js'); }); }12. 监控与日志管理
12.1 应用日志配置
// 使用Winston日志库 const winston = require('winston'); const { combine, timestamp, printf } = winston.format; const logFormat = printf(({ level, message, timestamp }) => { return `${timestamp} [${level}]: ${message}`; }); const logger = winston.createLogger({ level: 'info', format: combine( timestamp(), logFormat ), transports: [ new winston.transports.File({ filename: '/var/log/acceptance-app.log', maxsize: 10 * 1024 * 1024, // 10MB maxFiles: 5 }) ] }); // 生产环境添加Sentry if (process.env.NODE_ENV === 'production') { const Sentry = require('@sentry/node'); Sentry.init({ dsn: 'your_sentry_dsn' }); logger.add(new winston.transports.Console({ format: winston.format.simple(), level: 'error' })); }12.2 性能监控指标
关键指标:
系统层面
- CPU使用率
- 内存使用量
- 磁盘I/O
- 网络吞吐量
应用层面
- 请求响应时间
- 错误率
- 请求吞吐量
- 事件循环延迟
数据库层面
- 查询执行时间
- 连接池使用率
- 缓存命中率
- 锁等待时间
监控工具栈:
- Prometheus + Grafana(指标)
- ELK Stack(日志)
- Sentry(错误跟踪)
- Blackbox(外部监控)
12.3 告警规则示例
# Prometheus告警规则示例 groups: - name: node.rules rules: - alert: HighCPUUsage expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80 for: 10m labels: severity: warning annotations: summary: "High CPU usage on {{ $labels.instance }}" description: "CPU usage is {{ $value }}%" - alert: HighMemoryUsage expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100 > 90 for: 10m labels: severity: critical annotations: summary: "High memory usage on {{ $labels.instance }}" description: "Memory usage is {{ $value }}%"13. 安全审计与合规
13.1 定期安全检查清单
系统层面
- 检查未授权用户
- 验证防火墙规则
- 审核sudo权限
- 检查未安装的安全更新
应用层面
- 扫描依赖漏洞
- 检查敏感数据暴露
- 验证输入过滤
- 审计API权限
数据层面
- 检查备份完整性
- 验证加密措施
- 审核访问日志
- 检查数据库权限
13.2 自动化安全扫描
# 使用工具进行安全扫描 # 1. 依赖漏洞检查 npm audit snyk test # 2. 容器安全扫描 docker scan your-image # 3. 系统漏洞扫描 sudo apt install lynis sudo lynis audit system # 4. Web应用扫描 docker run -it --rm owasp/zap2docker-stable zap-baseline.py \ -t https://yourdomain.com13.3 合规性要求
数据保护
- 实现GDPR合规
- 用户数据加密
- 访问日志记录
审计要求
- 保留6个月以上的日志
- 实现操作审计跟踪
- 定期安全评估报告
行业标准
- 遵循OWASP Top 10
- 实现CIS基准
- 考虑ISO 27001认证
14. 成本优化策略
14.1 云资源优化
# AWS成本优化示例 # 1. 识别未使用的资源 aws ec2 describe-instances --query 'Reservations[].Instances[?State.Name==`stopped`].[InstanceId]' # 2. 调整实例大小 aws ec2 modify-instance-attribute --instance-id i-1234567890abcdef0 --instance-type t3.medium # 3. 使用Spot实例 aws ec2 request-spot-instances --spot-price "0.05" --instance-count 1 \ --type "one-time" --launch-specification file://specification.json # 4. 设置自动缩放 aws autoscaling put-scaling-policy --policy-name scale-down \ --auto-scaling-group-name my-asg --scaling-adjustment -1 \ --adjustment-type ChangeInCapacity14.2 数据库成本控制
存储优化
- 归档旧数据
- 压缩大字段
- 分区大表
查询优化
- 添加适当索引
- 避免全表扫描
- 使用物化视图
架构优化
- 读写分离
- 使用只读副本
- 考虑分片
14.3 监控与预算告警
# AWS预算告警设置 aws budgets create-budget \ --account-id 123456789012 \ --budget file://budget.json \ --notifications-with-subscribers file://notifications.json # budget.json示例 { "BudgetLimit": { "Amount": "100", "Unit": "USD" }, "TimeUnit": "MONTHLY", "BudgetType": "COST", "BudgetName": "Monthly Budget" }15. 扩展与演进
15.1 微服务化改造
演进路径:
- 单体架构→ 2.模块化单体→ 3.微服务架构
拆分策略:
- 按业务能力拆分
- 按数据边界拆分
- 按变更频率拆分
技术栈选择:
- 服务网格:Istio/Linkerd
- API网关:Kong/Apigee
- 消息队列:Kafka/RabbitMQ
- 分布式追踪:Jaeger/Zipkin
15.2 无服务器架构
# serverless.yml示例 service: acceptance-notice provider: name: aws runtime: nodejs14.x region: us-east-1 functions: generateNotice: handler: handler.generate events: - http: path: notices/generate method: post cors: true listNotices: handler: handler.list events: - http: path: notices method: get cors: true15.3 未来技术规划
AI集成
- 智能模板推荐
- 自动字段提取
- 智能纠错
区块链应用
- 录用通知存证
- 数字签名验证
- 不可篡改记录
移动优化
- PWA应用
- 原生APP
- 小程序集成
国际化支持
- 多语言界面
- 本地化模板
- 区域合规检查
在实际部署过程中,每个企业的环境和需求都会有所不同。我在多个生产环境部署这套系统时发现,最关键的三个点是:数据库性能调优、文件存储方案选择和监控告警设置。特别是当系统用户量增长后,这三个方面最容易成为瓶颈。建议在部署初期就规划好扩展方案,避免后期大规模重构。