深色模式
轮值排班设计
摘要:排班的难点不是"排出来",而是让覆盖无空档、负载够公平、长期可持续。本文给出轮值周期的选择依据、交接窗口的安排原则,以及用脚本生成并校验排班表的方法。
适用环境
bash
date +%G-W%V # 查看当前 ISO 周,排班常以周为单位
nproc; whoami # 排班脚本对资源无要求,本地或 CI 均可
python3 --version || echo "可用 awk/shell 替代"1
2
3
2
3
操作步骤
第 1 步:确定轮值周期
| 周期 | 适用人数 | 优点 | 缺点 |
|---|---|---|---|
| 12 小时轮 | ≥ 8 人 | 疲劳低 | 交接次数多 |
| 24 小时轮 | ≥ 6 人 | 交接少 | 夜间压力大 |
| 一周轮 | ≥ 4 人 | 上下文连贯 | 疲劳集中 |
经验值:每人每周被叫醒次数 > 3 次,就该考虑缩短周期或增加人数。
第 2 步:固定交接时刻
交接时刻必须落在双方都清醒的时间,且避开发布窗口:
bash
# 推荐交接时间:工作日 10:00(本地时区)
TZ=Asia/Shanghai date -d 'today 10:00' '+%F %T %Z'
# 避免放在以下时段
echo "避免: 00:00-06:00(双方疲惫)、周五 18:00 后(周末失联)"1
2
3
4
2
3
4
第 3 步:生成排班表
bash
# 从人员列表生成 N 周轮值:rotate.sh
cat > rotate.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
people=(alice bob carol dave erin) # 替换为实际成员
weeks=${1:-8}
start=${2:-2026-10-12} # 起始周一
for ((w=0; w<weeks; w++)); do
mon=$(date -d "$start +$((w*7)) day" '+%F')
sun=$(date -d "$start +$((w*7+6)) day" '+%F')
p=${people[$((w % ${#people[@]}))]}
s=${people[$(((w+1) % ${#people[@]}))]}
printf '| %s ~ %s | %s | %s |\n' "$mon" "$sun" "$p" "$s"
done
EOF
chmod +x rotate.sh && ./rotate.sh 8 2026-10-121
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
第 4 步:校验覆盖与公平性
bash
# 统计每人值班次数,确认无空档、无偏重
./rotate.sh 26 2026-10-12 | awk -F'|' '{gsub(/ /,"",$3); c[$3]++; s[$4]++} END{for(k in c) printf "%s primary=%d secondary=%d\n",k,c[k],s[k]}' | sort
# 检查是否有周次缺失
./rotate.sh 26 2026-10-12 | wc -l1
2
3
4
5
2
3
4
5
第 5 步:发布与锁定
bash
# 排班一经发布即锁定,变动走换班流程
cat > rotation.lock <<EOF
generated: $(date -u '+%F %T')
weeks: 26
owner: ops-team
rule: 换班需双方确认并在群内同步
EOF
gpg --clearsign rotation.lock 2>/dev/null || echo "无 gpg 时用 Git 提交记录即可"
git add rotation.lock 2>/dev/null && git commit -m "lock rotation" 2>/dev/null || true1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
验证
bash
# 1. 排班覆盖 26 周、无缺行
test "$(./rotate.sh 26 2026-10-12 | wc -l)" -eq 26 && echo "覆盖 OK"
# 2. 任意相邻两周的 Primary 不同人
./rotate.sh 26 2026-10-12 | awk -F'|' '{gsub(/ /,"",$3); print $3}' | uniq -d | wc -l
# 3. 交接时刻在白天
date -d 'next monday 10:00' '+%H:%M'1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
常见坑
人数刚好等于周期数
6 人做 6 周轮值,一旦有人休假就全线崩塌。至少预留 1 名机动人员(Shadow)。
只看"天"不看"夜"
同样 7 天,包含夜班的疲劳远高于白天。统计时要按被打扰的告警次数而非天数衡量。
换班不记录
口头换班后告警仍打给原值班人,导致无人接管。换班必须同步修改排班来源(配置 / 平台),不能只靠口头约定。