生产环境最佳实践 #

性能优化 #

Dyno 配置优化 #

bash
# 选择合适的 Dyno 大小
# 小型应用: Standard-1X 或 Standard-2X
# 中型应用: Standard-2X 或 Performance-M
# 大型应用: Performance-M 或 Performance-L

# 扩展策略
heroku ps:scale web=3        # 水平扩展
heroku ps:resize web=standard-2x  # 垂直扩展

应用性能优化 #

javascript
// 1. 使用连接池
const { Pool } = require('pg');
const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  max: 10,
  idleTimeoutMillis: 30000,
  connectionTimeoutMillis: 2000
});

// 2. 启用压缩
const compression = require('compression');
app.use(compression());

// 3. 启用缓存
app.use(express.static('public', {
  maxAge: '1d',
  etag: true
}));

// 4. 使用 Redis 缓存
const redis = new Redis(process.env.REDIS_URL);

async function getCached(key, fn, ttl = 3600) {
  const cached = await redis.get(key);
  if (cached) return JSON.parse(cached);
  
  const data = await fn();
  await redis.setex(key, ttl, JSON.stringify(data));
  return data;
}

数据库优化 #

sql
-- 创建索引
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_posts_user_id ON posts(user_id);
CREATE INDEX idx_posts_created_at ON posts(created_at DESC);

-- 分析查询
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';

-- 连接池配置
-- 根据应用需求调整连接数

安全加固 #

安全配置 #

javascript
// 1. 使用 Helmet
const helmet = require('helmet');
app.use(helmet());

// 2. CORS 配置
const cors = require('cors');
app.use(cors({
  origin: process.env.ALLOWED_ORIGINS.split(','),
  credentials: true
}));

// 3. 速率限制
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 100
});
app.use('/api/', limiter);

// 4. 安全 Headers
app.use((req, res, next) => {
  res.setHeader('X-Content-Type-Options', 'nosniff');
  res.setHeader('X-Frame-Options', 'DENY');
  res.setHeader('X-XSS-Protection', '1; mode=block');
  next();
});

环境变量安全 #

bash
# 使用强密钥
heroku config:set JWT_SECRET=$(openssl rand -hex 32)
heroku config:set SESSION_SECRET=$(openssl rand -hex 32)

# 定期轮换密钥
heroku config:set NEW_SECRET=$(openssl rand -hex 32)
# 更新应用使用新密钥
heroku config:unset OLD_SECRET

# 不要在代码中硬编码敏感信息

数据库安全 #

bash
# 使用 SSL 连接
heroku pg:info

# 限制连接数
# 在应用中使用连接池

# 定期备份
heroku pg:backups:schedule DATABASE_URL --at '02:00 UTC'

成本控制 #

成本分析 #

bash
# 查看当前配置
heroku apps:info
heroku addons

# 分析使用情况
heroku ps
heroku pg:info
heroku redis:info

成本优化策略 #

优化项 建议
Dyno 数量 根据流量调整,非高峰期缩减
Dyno 大小 选择合适规格,避免过度配置
数据库计划 根据数据量选择合适计划
Add-ons 定期审查,删除不使用的服务
Review Apps 设置自动销毁时间

自动扩展 #

bash
# 启用自动扩展(Performance Dyno)
heroku autoscale:set web --min=2 --max=10

# 基于响应时间扩展
heroku autoscale:set web --target-response-time=500ms

定时缩减 #

yaml
# .github/workflows/scale.yml
name: Scale Dynos

on:
  schedule:
    - cron: '0 9 * * 1-5'  # 工作日 9:00 扩展
    - cron: '0 18 * * 1-5' # 工作日 18:00 缩减

jobs:
  scale-up:
    runs-on: ubuntu-latest
    if: github.event.schedule == '0 9 * * 1-5'
    steps:
      - name: Scale up
        run: |
          curl -X PATCH https://api.heroku.com/apps/myapp/formation/web \
            -H "Authorization: Bearer ${{ secrets.HEROKU_API_KEY }}" \
            -H "Content-Type: application/json" \
            -d '{"quantity": 3}'

  scale-down:
    runs-on: ubuntu-latest
    if: github.event.schedule == '0 18 * * 1-5'
    steps:
      - name: Scale down
        run: |
          curl -X PATCH https://api.heroku.com/apps/myapp/formation/web \
            -H "Authorization: Bearer ${{ secrets.HEROKU_API_KEY }}" \
            -H "Content-Type: application/json" \
            -d '{"quantity": 1}'

监控与告警 #

监控配置 #

bash
# APM
heroku addons:create newrelic:wayne

# 日志
heroku addons:create papertrail:choklad

# 错误追踪
heroku addons:create sentry:developer

# 指标
heroku addons:create librato:meter

告警规则 #

markdown
## 告警规则配置

### 紧急告警
- 应用完全不可用
- 数据库连接失败
- 错误率 > 50%

### 重要告警
- 响应时间 > 2s
- 内存使用 > 90%
- 错误率 > 10%

### 警告告警
- 响应时间 > 500ms
- 内存使用 > 80%
- 错误率 > 5%

健康检查 #

javascript
// 健康检查端点
app.get('/health', async (req, res) => {
  const health = {
    status: 'ok',
    timestamp: new Date().toISOString(),
    checks: {}
  };
  
  // 检查数据库
  try {
    await pool.query('SELECT 1');
    health.checks.database = 'ok';
  } catch (error) {
    health.checks.database = 'error';
    health.status = 'degraded';
  }
  
  // 检查 Redis
  try {
    await redis.ping();
    health.checks.redis = 'ok';
  } catch (error) {
    health.checks.redis = 'error';
    health.status = 'degraded';
  }
  
  const statusCode = health.status === 'ok' ? 200 : 503;
  res.status(statusCode).json(health);
});

部署流程 #

生产部署检查清单 #

markdown
## 部署前检查
- [ ] 所有测试通过
- [ ] 代码已审查
- [ ] 环境变量已配置
- [ ] 数据库迁移已准备
- [ ] 回滚计划已制定
- [ ] 监控已配置
- [ ] 告警已设置

## 部署中监控
- [ ] 监控部署日志
- [ ] 检查应用启动
- [ ] 验证健康检查

## 部署后验证
- [ ] 验证关键功能
- [ ] 检查错误日志
- [ ] 验证性能指标

蓝绿部署 #

bash
# 使用 Pipeline 实现
heroku pipelines:create myapp-pipeline -a myapp-staging -s staging
heroku pipelines:add myapp-pipeline -a myapp-production -s production

# 部署到 Staging
git push heroku-staging main

# 验证 Staging
heroku open --app myapp-staging

# 推广到 Production
heroku pipelines:promote -a myapp-staging

回滚策略 #

bash
# 查看发布历史
heroku releases

# 回滚到上一版本
heroku rollback

# 回滚到指定版本
heroku rollback v10

# 数据库回滚(需要提前备份)
heroku pg:backups:restore b001 --confirm myapp

灾难恢复 #

备份策略 #

bash
# 数据库自动备份
heroku pg:backups:schedule DATABASE_URL --at '02:00 UTC'

# 手动备份
heroku pg:backups:capture

# 下载备份
heroku pg:backups:download

# 验证备份
heroku pg:backups

恢复流程 #

markdown
## 灾难恢复流程

1. 评估影响
   - 确定问题范围
   - 通知相关团队

2. 恢复服务
   - 回滚代码(如需要)
   - 恢复数据库(如需要)
   - 重启应用

3. 验证恢复
   - 检查应用状态
   - 验证关键功能
   - 监控错误日志

4. 事后分析
   - 记录事件详情
   - 分析根本原因
   - 制定改进措施

文档与知识库 #

运维文档 #

markdown
## 应用信息
- 应用名称: myapp-production
- 技术栈: Node.js, Express, PostgreSQL, Redis
- 部署平台: Heroku

## 关键配置
- Dyno: Standard-2X x 3
- 数据库: Standard-0
- Redis: Premium-0

## 监控
- APM: New Relic
- 日志: Papertrail
- 错误: Sentry

## 联系人
- 开发团队: dev@example.com
- 运维团队: ops@example.com

运行手册 #

markdown
## 常见问题处理

### 应用无响应
1. 检查 Dyno 状态: heroku ps
2. 查看日志: heroku logs --tail
3. 重启应用: heroku restart

### 数据库连接失败
1. 检查数据库状态: heroku pg:info
2. 检查连接数: heroku pg:connections
3. 重启数据库: heroku pg:restart

### 内存不足
1. 检查内存使用: heroku logs --tail | grep memory
2. 升级 Dyno: heroku ps:resize web=standard-2x
3. 优化应用内存使用

持续改进 #

性能基准 #

javascript
// 定期运行性能测试
const autocannon = require('autocannon');

async function runBenchmark() {
  const result = await autocannon({
    url: 'https://myapp.herokuapp.com',
    connections: 100,
    duration: 30
  });
  
  console.log('Requests/sec:', result.requests.mean);
  console.log('Latency:', result.latency.mean);
}

runBenchmark();

定期审查 #

markdown
## 月度审查清单
- [ ] 检查应用性能指标
- [ ] 审查错误日志
- [ ] 检查安全更新
- [ ] 审查成本报告
- [ ] 更新文档
- [ ] 检查备份完整性

恭喜! #

你已经完成了 Heroku 云应用平台的完整学习之旅!从基础概念到高级特性,从开发部署到生产运维,你现在已经具备了在 Heroku 上构建、部署和管理生产级应用的能力。

继续实践,不断优化,构建更优秀的应用!

最后更新:2026-03-28