一、前言
Tengine 是阿里巴巴基于 Nginx 开发的增强版 Web 服务器,在 Nginx 的基础上增加了大量生产环境需要的功能。本文重点介绍两个最实用的功能------check 模块(主动健康检查) 和 dyups 模块(动态 upstream)。
二、为什么选择 Tengine?
Nginx 的不足
| 功能 | Nginx 原生 | Tengine |
|---|---|---|
| 主动健康检查 | ❌ 需要 Nginx Plus 或第三方模块 | ✅ 内置 check_module |
| 动态 upstream | ❌ 需要 reload 才能更新后端 | ✅ 内置 dyups_module |
| 一致性哈希 | ❌ 需要第三方模块 | ✅ 内置 consistent_hash |
| 日志增强 | 基础变量 | 更多内置变量 |
编译安装 Tengine 2.3.2
bash
# 下载
wget https://tengine.taobao.org/download/tengine-2.3.2.tar.gz
tar -xzf tengine-2.3.2.tar.gz
cd tengine-2.3.2
# 编译(启用关键模块)
./configure \
--prefix=/etc/tengine \
--with-http_ssl_module \
--with-http_v2_module \
--add-module=./modules/ngx_http_upstream_check_module \
--add-module=./modules/ngx_http_upstream_consistent_hash_module \
--add-module=./modules/ngx_http_upstream_dynamic_module \
--add-module=./modules/ngx_http_upstream_dyups_module
make && make install
三、check 模块:主动健康检查
配置示例
nginx
upstream backend_tengine {
server 127.0.0.1:9001;
server 127.0.0.1:9002;
server 127.0.0.1:9003;
# 主动健康检查配置
check interval=3000 fall=3 rise=2 timeout=3000 default_down=false type=tcp;
keepalive 20;
}
# 健康检查状态页面
server {
listen 8080;
location /status {
check_status;
}
}
参数详解
| 参数 | 示例值 | 说明 |
|---|---|---|
interval |
3000 | 检查间隔(毫秒),最小有效值 1000ms |
fall |
3 | 连续失败 3 次标记为宕机 |
rise |
2 | 连续成功 2 次标记为恢复 |
timeout |
3000 | 单次探测超时(毫秒) |
default_down |
false | 启动时是否默认标记为宕机 |
type |
tcp/http/ssl_hello | 检查类型 |
检查类型
| 类型 | 说明 | 适用场景 |
|---|---|---|
tcp |
TCP 端口探测 | 通用,所有 TCP 服务 |
http |
HTTP 请求检查 | 需要检查 HTTP 响应码 |
ssl_hello |
SSL 握手检测 | HTTPS 服务 |
验证过程
场景:后端 9002 宕机
bash
# 1. 模拟宕机
pkill -9 -f "http.server 9002"
# 2. 观察健康检查状态页面
curl http://localhost:8080/status
# 输出:
# Index Name Status Rise Fall
# 0 127.0.0.1:9001 up 271 0
# 1 127.0.0.1:9002 down 0 3 ← 自动检测到宕机
# 2 127.0.0.1:9003 up 64 0
# 3. 验证请求转发(只转发到 9001 和 9003)
curl http://localhost:8080/
# 输出:Backend-1 (port 9001) ← 没有 9002
curl http://localhost:8080/
# 输出:Backend-3 (port 9003) ← 没有 9002
场景:后端 9002 恢复
bash
# 1. 重启 9002
cd /var/www/nginx-review/backend2 && python3 -m http.server 9002 --bind 127.0.0.1 &
# 2. 等待 rise=2 次探测成功
curl http://localhost:8080/status
# 输出:
# Index Name Status Rise Fall
# 0 127.0.0.1:9001 up 345 0
# 1 127.0.0.1:9002 up 10 0 ← 自动恢复
# 2 127.0.0.1:9003 up 17 0
健康检查参数配置建议
| 场景 | interval | fall | rise | 效果 |
|---|---|---|---|---|
| 支付接口 | 1s | 5 | 5 | 宁可多等 5 秒,不能因网络抖动摘掉节点 |
| 静态资源 | 10s | 2 | 3 | 缓存兜底,慢一点无所谓 |
| 实时推送 | 2s | 2 | 3 | 用户在线体验敏感,故障要快切 |
| 测试环境 | 3s | 3 | 2 | 快速验证,够用就行 |
四、dyups 模块:动态 Upstream
核心原理
dyups 模块允许通过 HTTP API 动态增删 upstream 的后端服务器,无需 reload,即时生效。
关键要求
dyups 要求 proxy_pass 必须使用变量,不能使用静态 upstream 名称:
nginx
# ❌ 错误:静态 upstream 名称,dyups 不生效
proxy_pass http://backend_tengine;
# ✅ 正确:使用变量,dyups 生效
set $ups "backend_tengine";
proxy_pass http://$ups;
配置
nginx
# 主入口
server {
listen 8080;
set $ups "backend_tengine";
location / {
proxy_pass http://$ups;
proxy_http_version 1.1;
proxy_set_header Connection "";
add_header X-Upstream $upstream_addr;
}
location /status {
check_status;
}
}
# dyups 管理接口
server {
listen 8089;
location / {
dyups_interface;
}
}
API 操作
bash
# 查看当前 upstream 列表
curl -s http://localhost:8089/list
# 输出:backend_tengine
# 查看 upstream 详情
curl -s http://localhost:8089/upstream/backend_tengine
# 输出:server 127.0.0.1:9001;server 127.0.0.1:9002;server 127.0.0.1:9003;
# 添加新后端
curl -s -d "server 127.0.0.1:9003;" http://localhost:8089/upstream/backend_tengine
# 替换整个 backend 列表
curl -s -d "server 127.0.0.1:9001;server 127.0.0.1:9002;" http://localhost:8089/upstream/backend_tengine
# 删除单个后端
# 注意:dyups 没有直接删除单个 server 的 API,需要先 get 全部列表
# 去掉要删除的后端,再用 set 替换
五、update-upstream.sh 脚本
功能
支持 list、detail、status、set、add、rm 六个命令,同时更新运行时(dyups API)和配置文件(持久化)。
核心逻辑
bash
#!/bin/bash
# update-upstream.sh --- Tengine 动态 upstream 管理器
UPSTREAM_NAME="backend_tengine"
DYUPS_API="http://localhost:8089"
CONF_FILE="/etc/tengine/rs-ports/01-tengine-demo.conf"
TENGINE_BIN="/usr/sbin/tengine"
case "$1" in
list) curl -s "$DYUPS_API/list" ;;
detail) curl -s "$DYUPS_API/upstream/$UPSTREAM_NAME" ;;
status) # 解析 check 模块的 status 页面,显示 up/down 状态 ;;
set) # 替换整个 upstream 列表(API + 写文件) ;;
add) # 追加一个后端(API + 写文件) ;;
rm) # 移除一个后端(API + 写文件) ;;
esac
使用示例
bash
# 查看健康检查状态
./update-upstream.sh status
# 输出:显示每个后端的 up/down、rise 次数、fall 次数
# 添加后端(即时生效 + 写入配置文件)
./update-upstream.sh add "server 127.0.0.1:9003;"
# 移除后端(即时生效 + 写入配置文件)
./update-upstream.sh rm "127.0.0.1:9002"
# 查看详情
./update-upstream.sh detail
六、重要发现:check 模块和 dyups 的独立性
问题
当通过 dyups 修改 upstream 后,check 模块的 status 页面会变成空白,健康检查状态丢失。
原因
┌─────────────────────────────────────┐
│ Tengine 共享内存 │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ dyups 模块 │ │ check 模块 │ │
│ │ (运行时) │ │ (健康检查) │ │
│ │ │ │ │ │
│ │ 增删 server │ │ 跟踪状态 │ │
│ │ 即时生效 │ │ up/down │ │
│ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │
│ │ ❌ 不共享 │ │
│ └────────┬────────┘ │
│ │ │
│ reload 后重新同步 │
└─────────────────────────────────────┘
dyups 和 check 模块是独立的数据结构 ,dyups 修改 upstream 后,check 模块不会自动同步。需要执行 tengine -s reload 让 check 模块重新读取配置。
解决方案
| 方案 | 说明 | 适用场景 |
|---|---|---|
| 每次 dyups 操作后 reload | 简单,但需要 reload | 低频率变更 |
| 不用 check 模块,改用外部监控 | 独立脚本探测 | 需要灵活定制 |
| 升级到 APISIX | check 和 upstream 是同一套数据 | 全新架构 |
七、F5 工程师看 Tengine
F5 概念 Tengine 对应
────────────────────────────────────
Monitor check 模块(主动健康检查)
Pool Member 动态增删 dyups 模块(动态 upstream)
tmsh modify dyups API(HTTP 接口)
tmsh save sys config 配置文件写入(持久化)
GUI 状态页面 /status 页面
关键区别: F5 的 Monitor 和 Pool 是同一套数据,Tengine 的 check 和 dyups 是两套独立数据,需要 reload 同步。
八、生产建议
- check 模块的 interval 不要设得太短,建议 3000ms 以上,避免对后端造成压力
- dyups 操作后记得写配置文件,否则 Tengine 重启后会丢失运行时变更
- 每次 dyups 操作后建议 reload,让 check 模块重新同步
- 生产环境使用 update-upstream.sh 脚本,确保 API 和配置文件同时更新
- Tengine 适合中小规模集群,大规模建议使用 APISIX
下一篇: 负载均衡架构设计:F5 ↔ Nginx/HAProxy ↔ Keepalived 全链路映射