Dyno 管理 #

Dyno 概述 #

Dyno 是 Heroku 应用的运行容器,理解 Dyno 的管理对于构建高性能、可扩展的应用至关重要。

Dyno 架构 #

text
┌─────────────────────────────────────────────────────┐
│                   Heroku 应用                        │
├─────────────────────────────────────────────────────┤
│                                                     │
│  ┌─────────────────────────────────────────────┐   │
│  │              Web Dynos                       │   │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐       │   │
│  │  │ web.1   │ │ web.2   │ │ web.3   │       │   │
│  │  │ 512MB   │ │ 512MB   │ │ 512MB   │       │   │
│  │  └─────────┘ └─────────┘ └─────────┘       │   │
│  └─────────────────────────────────────────────┘   │
│                                                     │
│  ┌─────────────────────────────────────────────┐   │
│  │            Worker Dynos                      │   │
│  │  ┌─────────┐ ┌─────────┐                    │   │
│  │  │worker.1 │ │worker.2 │                    │   │
│  │  │ 512MB   │ │ 512MB   │                    │   │
│  │  └─────────┘ └─────────┘                    │   │
│  └─────────────────────────────────────────────┘   │
│                                                     │
└─────────────────────────────────────────────────────┘

Dyno 类型 #

按用途分类 #

类型 说明 用途
Web Dyno 处理 HTTP 请求 Web 应用、API 服务
Worker Dyno 后台任务处理 队列处理、定时任务
One-off Dyno 临时命令执行 数据迁移、调试

按规格分类 #

规格 内存 CPU 价格/月 适用场景
Eco 512MB 共享 $5 个人项目、测试
Basic 512MB 共享 $7 小型应用
Standard-1X 512MB 共享 $25 生产环境
Standard-2X 1GB 共享 $50 中型应用
Performance-M 2.5GB 专用 $250 高性能需求
Performance-L 14GB 专用 $500 大型应用
Performance-L-RAM 30GB 专用 $900 内存密集型
Performance-XL 64GB 专用 $1,800 超大应用

共享 vs 专用 Dyno #

text
┌─────────────────────────────────────────────────────┐
│              共享 Dyno (Eco/Basic/Standard)          │
├─────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────────┐   │
│  │              共享 CPU 核心                   │   │
│  │  ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐           │   │
│  │  │App A│ │App B│ │App C│ │App D│           │   │
│  │  └─────┘ └─────┘ └─────┘ └─────┘           │   │
│  └─────────────────────────────────────────────┘   │
│  特点:成本较低,性能可能受其他应用影响              │
└─────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────┐
│              专用 Dyno (Performance)                 │
├─────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────────┐   │
│  │              专用 CPU 核心                   │   │
│  │  ┌─────────────────────────────────────┐   │   │
│  │  │              Your App               │   │   │
│  │  └─────────────────────────────────────┘   │   │
│  └─────────────────────────────────────────────┘   │
│  特点:性能稳定,资源独占,成本较高                  │
└─────────────────────────────────────────────────────┘

Dyno 管理 #

查看 Dyno 状态 #

bash
# 查看所有 Dyno
heroku ps

# 输出示例
# === web (Eco): node index.js (1)
# web.1: up 2024/01/15 10:30:00 (~ 2h ago)
#
# === worker (Eco): node worker.js (2)
# worker.1: up 2024/01/15 10:30:00 (~ 2h ago)
# worker.2: up 2024/01/15 11:00:00 (~ 1h ago)

# 查看 Dyno 数量
heroku ps:scale

# 查看特定进程类型
heroku ps --type web

扩展 Dyno #

bash
# 垂直扩展(调整大小)
heroku ps:resize web=standard-2x

# 水平扩展(增加数量)
heroku ps:scale web=3

# 同时扩展多个进程
heroku ps:scale web=3 worker=2

# 缩减 Dyno
heroku ps:scale web=1
heroku ps:scale worker=0

重启 Dyno #

bash
# 重启所有 Dyno
heroku restart

# 重启特定进程类型
heroku restart web

# 重启特定 Dyno
heroku restart web.1

# 重启所有 Worker
heroku restart worker

停止 Dyno #

bash
# 停止特定 Dyno
heroku ps:stop web.1

# 停止所有 Worker
heroku ps:stop worker

Dyno 休眠 #

休眠机制 #

Eco 和 Basic Dyno 在一段时间无活动后会进入休眠状态。

text
┌─────────────────────────────────────────────────────┐
│              Dyno 休眠周期                           │
├─────────────────────────────────────────────────────┤
│                                                     │
│  活动状态                                           │
│  ┌─────────────────────────────────────┐           │
│  │  接收请求 → 处理请求 → 等待新请求    │           │
│  └─────────────────────────────────────┘           │
│       │                                             │
│       │ 30 分钟无活动                               │
│       ▼                                             │
│  休眠状态                                           │
│  ┌─────────────────────────────────────┐           │
│  │  Dyno 休眠,释放资源                │           │
│  └─────────────────────────────────────┘           │
│       │                                             │
│       │ 收到新请求                                  │
│       ▼                                             │
│  唤醒过程                                           │
│  ┌─────────────────────────────────────┐           │
│  │  启动 Dyno → 加载应用 → 响应请求    │           │
│  │  (通常需要几秒到十几秒)              │           │
│  └─────────────────────────────────────┘           │
│                                                     │
└─────────────────────────────────────────────────────┘

避免休眠 #

bash
# 方式一:升级到 Standard 或更高级别
heroku ps:resize web=standard-1x

# 方式二:使用多个 Eco Dyno
heroku ps:scale web=2  # 至少一个保持活动

# 方式三:使用外部监控服务定时 ping
# 如 Pingdom, UptimeRobot

休眠对应用的影响 #

影响 说明
首次请求延迟 唤醒需要几秒到十几秒
定时任务 休眠期间不会执行
WebSocket 连接会断开

资源限制 #

内存限制 #

bash
# 不同 Dyno 类型的内存限制
# Eco/Basic/Standard-1X: 512MB
# Standard-2X: 1GB
# Performance-M: 2.5GB
# Performance-L: 14GB

# 监控内存使用
heroku logs --tail | grep -i memory

# 内存超限警告
# heroku[web.1]: Process running mem=600M(120.0%)
# heroku[web.1]: Error R14 (Memory quota exceeded)

内存超限错误 #

错误代码 说明 解决方案
R14 内存超限(警告) 优化代码或升级 Dyno
R15 内存超限(严重) 立即升级或优化
R16 内存超限(终止) 进程被终止

CPU 限制 #

bash
# 共享 Dyno 的 CPU 是共享的
# Performance Dyno 有专用 CPU

# CPU 密集型任务建议使用 Performance Dyno
heroku ps:resize worker=performance-m

网络限制 #

限制
最大连接数 每个 Dyno 限制
请求超时 30 秒
响应超时 55 秒(长轮询)
文件上传 最大 500MB

Dyno 生命周期 #

启动流程 #

text
┌─────────────────────────────────────────────────────┐
│              Dyno 启动流程                           │
├─────────────────────────────────────────────────────┤
│                                                     │
│  1. 分配资源                                        │
│     └── 创建容器,分配内存和 CPU                    │
│                                                     │
│  2. 加载 Slug                                       │
│     └── 解压应用代码和依赖                          │
│                                                     │
│  3. 设置环境变量                                    │
│     └── 注入 Config Vars                            │
│                                                     │
│  4. 执行启动命令                                    │
│     └── 运行 Procfile 中定义的命令                  │
│                                                     │
│  5. 绑定端口(Web Dyno)                            │
│     └── 监听 $PORT                                  │
│                                                     │
│  6. 健康检查                                        │
│     └── 确认进程正常运行                            │
│                                                     │
└─────────────────────────────────────────────────────┘

自动重启 #

bash
# Dyno 每 24 小时自动重启
# 日志示例
# heroku[web.1]: Cycling
# heroku[web.1]: State changed from up to starting

优雅关闭 #

javascript
// Node.js 优雅关闭示例
const server = app.listen(port, () => {
  console.log(`Server listening on port ${port}`);
});

process.on('SIGTERM', () => {
  console.log('SIGTERM received, shutting down gracefully');
  
  server.close(() => {
    console.log('HTTP server closed');
    process.exit(0);
  });
  
  // 强制关闭超时
  setTimeout(() => {
    console.error('Forced shutdown');
    process.exit(1);
  }, 10000);
});

性能优化 #

选择合适的 Dyno 大小 #

text
┌─────────────────────────────────────────────────────┐
│              Dyno 选择指南                           │
├─────────────────────────────────────────────────────┤
│                                                     │
│  流量评估                                           │
│  ├── 低流量(< 100 req/s)                          │
│  │   └── Standard-1X 或 Standard-2X                │
│  │                                                  │
│  ├── 中等流量(100-1000 req/s)                     │
│  │   └── Standard-2X 多个实例                       │
│  │                                                  │
│  └── 高流量(> 1000 req/s)                         │
│      └── Performance-M 或 Performance-L            │
│                                                     │
│  内存需求                                           │
│  ├── < 512MB → Standard-1X                         │
│  ├── 512MB - 1GB → Standard-2X                     │
│  ├── 1GB - 2.5GB → Performance-M                   │
│  └── > 2.5GB → Performance-L                       │
│                                                     │
└─────────────────────────────────────────────────────┘

扩展策略 #

bash
# 垂直扩展 vs 水平扩展

# 垂直扩展:增加单个 Dyno 的资源
heroku ps:resize web=performance-m

# 水平扩展:增加 Dyno 数量
heroku ps:scale web=5

# 推荐策略
# 1. 先水平扩展到 3-4 个 Dyno
# 2. 如果单个 Dyno 内存不足,再垂直扩展
# 3. 结合自动扩展功能

自动扩展 #

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

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

# 查看自动扩展配置
heroku autoscale

# 禁用自动扩展
heroku autoscale:unset web

监控与诊断 #

查看 Dyno 指标 #

bash
# 使用 Heroku Dashboard
heroku open

# 使用 CLI 查看日志
heroku logs --tail

# 使用 Add-ons 监控
# New Relic, Librato, Papertrail

内存泄漏排查 #

bash
# 生成堆快照
heroku run node --expose-gc -e "require('./dump-heap')"

# 使用 Node.js 内存分析
node --inspect index.js

# 常见内存泄漏原因
# 1. 未关闭的数据库连接
# 2. 未清理的定时器
# 3. 缓存无限增长
# 4. 事件监听器未移除

性能分析 #

javascript
// 添加性能监控
const startTime = Date.now();

app.use((req, res, next) => {
  const start = Date.now();
  res.on('finish', () => {
    const duration = Date.now() - start;
    console.log(`${req.method} ${req.path} - ${duration}ms`);
  });
  next();
});

成本优化 #

成本计算 #

bash
# 示例:中型应用配置
# 3 x Standard-2X Web Dyno: $150/月
# 2 x Standard-1X Worker Dyno: $50/月
# PostgreSQL Mini: $5/月
# Redis Mini: $15/月
# 总计: $220/月

节省成本的建议 #

建议 说明
使用 Eco Dyno 开发和测试环境
合理扩展 根据实际需求扩展
使用 Review Apps 仅在需要时运行
监控资源使用 避免过度配置
选择合适的数据库 Mini 计划适合小型应用

下一步 #

Dyno 管理掌握后,接下来学习 日志管理 了解如何监控和调试应用!

最后更新:2026-03-28