核心概念 #

Dyno #

什么是 Dyno? #

Dyno 是 Heroku 中运行应用的轻量级容器。每个 Dyno 都是一个独立的 Linux 容器,拥有自己的文件系统、内存和 CPU 资源。

text
┌─────────────────────────────────────────┐
│              Heroku 应用                 │
├─────────────────────────────────────────┤
│  ┌─────────┐ ┌─────────┐ ┌─────────┐   │
│  │ Web.1   │ │ Web.2   │ │ Worker.1│   │
│  │ Dyno    │ │ Dyno    │ │ Dyno    │   │
│  │         │ │         │ │         │   │
│  │ 512MB   │ │ 512MB   │ │ 512MB   │   │
│  │ RAM     │ │ RAM     │ │ RAM     │   │
│  └─────────┘ └─────────┘ └─────────┘   │
└─────────────────────────────────────────┘

Dyno 类型 #

类型 说明 特点
Web Dyno 处理 HTTP 请求 接收路由流量
Worker Dyno 后台任务处理 不接收 HTTP 流量
One-off Dyno 临时执行命令 用于 heroku run

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/月

Dyno 生命周期 #

text
┌──────────┐
│  创建    │  heroku ps:scale web=1
└────┬─────┘
     │
     ▼
┌──────────┐
│  启动    │  执行 Procfile 中的命令
└────┬─────┘
     │
     ▼
┌──────────┐
│  运行    │  处理请求/任务
└────┬─────┘
     │
     ├──────────────────────┐
     │                      │
     ▼                      ▼
┌──────────┐          ┌──────────┐
│  重启    │          │  停止    │
│ (24小时) │          │  heroku  │
└────┬─────┘          │  restart │
     │                └──────────┘
     │
     └──────────────────┐
                        │
                        ▼
                  ┌──────────┐
                  │  休眠    │
                  │ (免费/Eco)│
                  └──────────┘

Dyno 文件系统 #

bash
# Dyno 文件系统是临时的
/app/           # 应用代码(只读)
/tmp/           # 临时文件(可写,重启丢失)
~/.heroku/      # Heroku 工具文件

# 写入示例
heroku run bash
~$ echo "test" > /tmp/test.txt
~$ cat /tmp/test.txt
test

# 重启后文件丢失
~$ exit
heroku restart
heroku run cat /tmp/test.txt
# 文件不存在

Dyno 管理 #

bash
# 查看 Dyno 状态
heroku ps

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

# 扩展 Dyno
heroku ps:scale web=3      # 扩展到 3 个 Web Dyno
heroku ps:scale worker=2   # 添加 2 个 Worker Dyno

# 调整 Dyno 大小
heroku ps:resize web=standard-2x

# 重启 Dyno
heroku restart
heroku restart web.1       # 重启特定 Dyno

# 停止 Dyno
heroku ps:stop web.1

Buildpack #

什么是 Buildpack? #

Buildpack 是一组脚本,负责检测应用语言、安装运行时、下载依赖,并将应用打包成 Slug。

text
┌─────────────────────────────────────────┐
│            Buildpack 工作流程            │
├─────────────────────────────────────────┤
│                                         │
│  ┌─────────┐                            │
│  │  检测   │  detect: 检测应用类型       │
│  │ Detect  │  查找 package.json 等      │
│  └────┬────┘                            │
│       │                                 │
│       ▼                                 │
│  ┌─────────┐                            │
│  │  编译   │  compile: 构建应用          │
│  │Compile  │  安装 Node.js, npm install │
│  └────┬────┘                            │
│       │                                 │
│       ▼                                 │
│  ┌─────────┐                            │
│  │  发布   │  release: 生成启动脚本      │
│  │ Release │  创建 Procfile 入口        │
│  └─────────┘                            │
│                                         │
└─────────────────────────────────────────┘

官方 Buildpack #

语言 Buildpack 检测文件
Node.js heroku/nodejs package.json
Ruby heroku/ruby Gemfile
Python heroku/python requirements.txt
Java heroku/java pom.xml, build.gradle
PHP heroku/php composer.json
Go heroku/go go.mod
Scala heroku/scala build.sbt

管理 Buildpack #

bash
# 查看当前 Buildpack
heroku buildpacks

# 设置 Buildpack
heroku buildpacks:set heroku/nodejs

# 添加多个 Buildpack
heroku buildpacks:add --index 1 heroku/nodejs
heroku buildpacks:add --index 2 heroku/ruby

# 清除所有 Buildpack
heroku buildpacks:clear

# 使用自定义 Buildpack
heroku buildpacks:set https://github.com/example/custom-buildpack

Buildpack 缓存 #

bash
# Buildpack 会缓存依赖,加速后续构建
# 清除缓存
heroku builds:cache:purge

Slug #

什么是 Slug? #

Slug 是构建后的可部署包,包含应用代码、依赖和运行时环境。

text
┌─────────────────────────────────────────┐
│              Slug 组成                   │
├─────────────────────────────────────────┤
│  /app/                                  │
│  ├── node_modules/    # 依赖            │
│  ├── index.js         # 应用代码        │
│  ├── package.json                       │
│  └── Procfile                           │
│                                         │
│  环境变量                                │
│  ├── PATH                               │
│  ├── NODE_ENV                           │
│  └── ...                                │
│                                         │
│  元数据                                  │
│  ├── 构建时间                           │
│  ├── Git SHA                            │
│  └── 构建日志                           │
└─────────────────────────────────────────┘

Slug 大小限制 #

bash
# Slug 最大 500MB(压缩后)
# 查看 Slug 大小
heroku run "du -sh /app"

# 优化 Slug 大小
# 1. 使用 .slugignore 排除文件
# 2. 清理开发依赖
# 3. 使用多阶段构建

.slugignore #

text
# .slugignore - 类似 .gitignore
# 排除不需要的文件

test/
spec/
docs/
*.md
.git/
node_modules/.cache/

Release #

什么是 Release? #

Release 是 Slug 和 Config Vars 的组合,代表应用的一个可部署版本。

text
┌─────────────────────────────────────────┐
│              Release 组成                │
├─────────────────────────────────────────┤
│                                         │
│  Release v5                             │
│  ├── Slug (应用代码 + 依赖)             │
│  ├── Config Vars (环境变量)             │
│  ├── Add-ons (附加服务)                 │
│  └── Metadata (版本信息)                │
│                                         │
└─────────────────────────────────────────┘

Release 历史 #

bash
# 查看 Release 历史
heroku releases

# 输出示例
# === myapp Releases
# v5  Deploy 2a3b4c5d  me@example.com  2024/01/15 10:30:00
# v4  Config set FOO   me@example.com  2024/01/15 09:00:00
# v3  Deploy 1a2b3c4d  me@example.com  2024/01/14 15:00:00

# 查看特定 Release 详情
heroku releases:info v5

# 回滚到上一个版本
heroku rollback

# 回滚到指定版本
heroku rollback v3

Release 流程 #

text
代码变更 ────┬─── Git Push ──── Buildpack ──── Slug
             │
             ├─── Config 变更
             │
             └─── Add-ons 变更
                      │
                      ▼
              ┌──────────────┐
              │  创建 Release │
              │    (v + 1)   │
              └──────┬───────┘
                     │
                     ▼
              ┌──────────────┐
              │  部署到 Dyno  │
              │  重启应用     │
              └──────────────┘

Logplex #

什么是 Logplex? #

Logplex 是 Heroku 的日志聚合和路由系统,负责收集、聚合和分发应用日志。

text
┌─────────────────────────────────────────┐
│            Logplex 架构                  │
├─────────────────────────────────────────┤
│                                         │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐   │
│  │ Dyno 1  │ │ Dyno 2  │ │ Dyno 3  │   │
│  │ stdout  │ │ stdout  │ │ stdout  │   │
│  └────┬────┘ └────┬────┘ └────┬────┘   │
│       │           │           │         │
│       └───────────┼───────────┘         │
│                   │                     │
│                   ▼                     │
│           ┌──────────────┐              │
│           │   Logplex    │              │
│           │  日志聚合     │              │
│           └──────┬───────┘              │
│                  │                      │
│       ┌──────────┼──────────┐           │
│       │          │          │           │
│       ▼          ▼          ▼           │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐   │
│  │ CLI     │ │ Add-on  │ │ Syslog  │   │
│  │ heroku  │ │Papertrail│ │ Drain   │   │
│  │ logs    │ │         │ │         │   │
│  └─────────┘ └─────────┘ └─────────┘   │
│                                         │
└─────────────────────────────────────────┘

日志格式 #

text
# 日志格式
timestamp source[dyno]: message

# 示例
2024-01-15T10:30:00.000000+00:00 app[web.1]: Server started on port 3000
2024-01-15T10:30:01.000000+00:00 heroku[router]: at=info method=GET path="/" host=myapp.herokuapp.com request_id=abc123 fwd="1.2.3.4" dyno=web.1 connect=0ms service=10ms status=200 bytes=1234

日志源 #

说明
app 应用输出 (stdout/stderr)
heroku 系统消息
router HTTP 请求日志

查看日志 #

bash
# 查看实时日志
heroku logs --tail

# 查看最近 N 行
heroku logs -n 200

# 过滤特定源
heroku logs --source app
heroku logs --source router

# 过滤特定 Dyno
heroku logs --dyno web.1

# 组合过滤
heroku logs --source app --dyno web.1 -n 100

日志 Drain #

bash
# 添加日志 drain(发送到外部服务)
heroku drains:add syslog://logs.example.com:514

# 查看所有 drain
heroku drains

# 删除 drain
heroku drains:remove syslog://logs.example.com:514

Router #

什么是 Router? #

Heroku Router 是 HTTP 请求路由器,负责将请求分发到正确的 Web Dyno。

text
┌─────────────────────────────────────────┐
│            Router 工作流程               │
├─────────────────────────────────────────┤
│                                         │
│  HTTP Request                           │
│       │                                 │
│       ▼                                 │
│  ┌─────────┐                            │
│  │ Router  │                            │
│  │         │                            │
│  │ 负载均衡│                            │
│  │ SSL 终止│                            │
│  │ 路由分发│                            │
│  └────┬────┘                            │
│       │                                 │
│       ├──────────┬──────────┐           │
│       │          │          │           │
│       ▼          ▼          ▼           │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐   │
│  │ Web.1   │ │ Web.2   │ │ Web.3   │   │
│  └─────────┘ └─────────┘ └─────────┘   │
│                                         │
└─────────────────────────────────────────┘

Router 特性 #

特性 说明
负载均衡 自动分发请求到多个 Dyno
SSL 终止 自动处理 HTTPS
超时处理 请求超时 30 秒
会话亲和 支持 Cookie 会话绑定

Router 超时 #

bash
# 默认超时设置
# - 连接超时: 5 秒
# - 请求超时: 30 秒
# - 长轮询超时: 55 秒

# 长时间任务处理
# 1. 使用 Worker Dyno
# 2. 使用后台任务队列
# 3. 返回立即响应,异步处理

Config Vars #

什么是 Config Vars? #

Config Vars 是 Heroku 的环境变量系统,用于存储配置信息和敏感数据。

bash
# 设置环境变量
heroku config:set DATABASE_URL=postgres://user:pass@host:5432/db
heroku config:set SECRET_KEY=your-secret-key
heroku config:set NODE_ENV=production

# 查看所有环境变量
heroku config

# 查看单个变量
heroku config:get DATABASE_URL

# 删除环境变量
heroku config:unset SECRET_KEY

环境变量最佳实践 #

javascript
// 应用中使用环境变量
const config = {
  port: process.env.PORT || 3000,
  database: process.env.DATABASE_URL,
  secret: process.env.SECRET_KEY,
  nodeEnv: process.env.NODE_ENV || 'development'
};

// 验证必需变量
const requiredVars = ['DATABASE_URL', 'SECRET_KEY'];
requiredVars.forEach(varName => {
  if (!process.env[varName]) {
    throw new Error(`Missing required env var: ${varName}`);
  }
});

下一步 #

现在你已经理解了 Heroku 的核心概念,接下来学习 应用配置管理 深入了解应用配置!

最后更新:2026-03-28