Module Federation 的部署策略对于生产环境的稳定性和性能至关重要。以下是详细的部署方案:
1. 部署架构设计
独立部署模式:
shell┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Host App │ │ Remote App 1│ │ Remote App 2│ │ :3000 │ │ :3001 │ │ :3002 │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ └───────────────────┼───────────────────┘ │ ┌──────▼──────┐ │ Load Balancer│ └──────┬──────┘ │ ┌──────▼──────┐ │ CDN / Nginx│ └─────────────┘
2. 环境配置管理
开发环境配置:
javascript// webpack.config.js const isDevelopment = process.env.NODE_ENV === 'development' module.exports = { plugins: [ new ModuleFederationPlugin({ name: 'app1', filename: 'remoteEntry.js', remotes: { app2: isDevelopment ? 'app2@http://localhost:3002/remoteEntry.js' : 'app2@https://app2.example.com/remoteEntry.js' }, shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true } } }) ] }
生产环境配置:
javascript// .env.production REMOTE_APP_URL=https://cdn.example.com REMOTE_APP_VERSION=1.2.3 // webpack.config.js const remoteUrl = process.env.REMOTE_APP_URL const remoteVersion = process.env.REMOTE_APP_VERSION module.exports = { plugins: [ new ModuleFederationPlugin({ name: 'app1', remotes: { app2: `app2@${remoteUrl}/app2/${remoteVersion}/remoteEntry.js` } }) ] }
3. CDN 部署策略
静态资源上传:
bash# 使用 AWS S3 + CloudFront aws s3 sync ./dist s3://my-bucket/app1/1.0.0/ --delete aws cloudfront create-invalidation --distribution-id E1234567890 --paths "/*" # 使用阿里云 OSS ossutil cp -rf ./dist oss://my-bucket/app1/1.0.0/ # 使用腾讯云 COS coscli cp -r ./dist cos://my-bucket/app1/1.0.0/
Nginx 配置:
nginxserver { listen 80; server_name app1.example.com; # 主应用 location / { root /var/www/app1; try_files $uri $uri/ /index.html; } # 远程模块入口 location /remoteEntry.js { root /var/www/app1; add_header Cache-Control "public, max-age=31536000, immutable"; } # 模块文件 location /assets/ { root /var/www/app1; add_header Cache-Control "public, max-age=31536000, immutable"; } # 启用 gzip 压缩 gzip on; gzip_types text/javascript application/javascript; }
4. 版本管理策略
语义化版本控制:
json{ "version": "1.2.3", "scripts": { "version:patch": "npm version patch && npm run deploy", "version:minor": "npm version minor && npm run deploy", "version:major": "npm version major && npm run deploy" } }
版本回滚机制:
bash# 部署脚本 deploy.sh #!/bin/bash VERSION=$1 BACKUP_DIR="/var/backups/app1" CURRENT_DIR="/var/www/app1" # 备份当前版本 if [ -d "$CURRENT_DIR" ]; then cp -r "$CURRENT_DIR" "$BACKUP_DIR/$(date +%Y%m%d_%H%M%S)" fi # 部署新版本 cp -r "./dist" "$CURRENT_DIR" # 健康检查 if ! curl -f http://localhost:3000/health; then echo "Health check failed, rolling back..." cp -r "$BACKUP_DIR/latest" "$CURRENT_DIR" exit 1 fi echo "Deployment successful"
5. CI/CD 集成
GitHub Actions 配置:
yamlname: Deploy Module Federation on: push: branches: [main] jobs: build-and-deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup Node.js uses: actions/setup-node@v2 with: node-version: '16' - name: Install dependencies run: npm ci - name: Build run: npm run build - name: Run tests run: npm test - name: Deploy to S3 uses: jakejarvis/s3-sync-action@master with: args: --delete env: AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_REGION: 'us-east-1' SOURCE_DIR: 'dist' - name: Invalidate CloudFront uses: chetan/invalidate-cloudfront-action@master env: DISTRIBUTION: ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} PATHS: '/*' AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_REGION: 'us-east-1'
6. 监控和告警
健康检查端点:
javascript// health.js app.get('/health', (req, res) => { const health = { status: 'ok', timestamp: new Date().toISOString(), uptime: process.uptime(), memory: process.memoryUsage(), remoteModules: { app2: { loaded: true, version: '1.2.3', lastUpdated: new Date().toISOString() } } } res.json(health) })
监控指标:
javascript// metrics.js const Prometheus = require('prom-client') const httpRequestDuration = new Prometheus.Histogram({ name: 'http_request_duration_seconds', help: 'Duration of HTTP requests in seconds', labelNames: ['method', 'route', 'code'] }) const moduleLoadDuration = new Prometheus.Histogram({ name: 'module_load_duration_seconds', help: 'Duration of module loading in seconds', labelNames: ['module', 'status'] }) // 使用示例 const start = Date.now() await import('remoteApp/Module') moduleLoadDuration.observe( { module: 'remoteApp/Module', status: 'success' }, (Date.now() - start) / 1000 )
7. 灾难恢复
备份策略:
bash# 定期备份脚本 #!/bin/bash BACKUP_DIR="/backups/$(date +%Y%m%d)" mkdir -p "$BACKUP_DIR" # 备份所有应用 for app in app1 app2 app3; do cp -r "/var/www/$app" "$BACKUP_DIR/" done # 上传到 S3 aws s3 sync "$BACKUP_DIR" s3://my-backups/
故障转移配置:
nginxupstream app1_cluster { server app1-primary.example.com weight=3; server app1-backup.example.com weight=1; server app1-dr.example.com backup; } server { location / { proxy_pass http://app1_cluster; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; proxy_next_upstream_tries 2; } }
最佳实践总结:
- 环境隔离:开发、测试、生产环境完全隔离
- 版本管理:使用语义化版本,支持快速回滚
- CDN 加速:使用 CDN 分发静态资源,提升加载速度
- 自动化部署:集成 CI/CD,实现自动化部署流程
- 监控告警:实时监控应用状态,及时发现和解决问题
- 备份恢复:定期备份,制定灾难恢复计划
- 灰度发布:支持灰度发布,降低风险
- 文档完善:维护详细的部署文档和操作手册
通过以上部署策略,可以确保 Module Federation 应用在生产环境中的稳定性和可靠性。