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