3. 门禁系统设计:门禁触发条件、门禁检查项与CI/CD集成
蓝绿发布门禁是SLO驱动部署的核心执行层。门禁系统在CI/CD流水线的关键卡点处拦截流量切换决策,依据实时采集的SLO指标数据,判断目标环境(Green)是否达到准入标准。本章详细阐述门禁的触发条件、检查项设计以及与流水线的集成方式。
3.1 门禁触发条件
门禁并非在流水线每个阶段都执行,而是在特定事件或时间点触发。合理的触发条件能避免无效检查,降低系统开销。
| 触发类型 | 触发时机 | 典型场景 |
|---|---|---|
| 时间窗口触发 | Green环境部署完成并预热后,等待固定时长(如5分钟) | 确保指标采集器完成首次数据聚合,避免冷启动噪声 |
| 事件驱动触发 | CI/CD流水线执行到“门禁检查”阶段时,由流水线引擎发起HTTP回调 | 与Jenkins/GitLab CI/GitHub Actions集成,作为Stage Gate |
| 指标阈值触发 | 当错误率或延迟指标连续N个评估窗口超出基线时,自动触发门禁拒绝 | 用于自动化回滚或阻断流量切换 |
| 手动审批触发 | SRE或发布经理在Dashboard上点击“执行门禁检查” | 灰度发布或紧急修复场景,需要人工确认 |
最佳实践:推荐采用“时间窗口 + 事件驱动”组合触发。部署完成后等待60秒(时间窗口),再由流水线调用门禁API(事件驱动),确保指标数据已稳定写入时序数据库。
3.2 门禁检查项:错误率、延迟、饱和度
门禁检查项直接映射到SLO的三大黄金指标。每个检查项都包含指标定义、阈值、评估窗口和容忍度四个要素。
3.2.1 错误率检查
- 指标定义: (HTTP 5xx + 业务自定义错误码) / 总请求数 × 100%
- 阈值: 错误率 ≤ 0.1%(对应SLO 99.9%)
- 评估窗口: 最近5分钟滑动窗口
- 容忍度: 允许连续2个窗口超出阈值,但第3个窗口必须恢复
3.2.2 延迟检查
- 指标定义: p99 响应时间(毫秒)
- 阈值: p99 ≤ 500ms(对应SLO目标)
- 评估窗口: 最近10分钟滑动窗口
- 容忍度: 不允许任何窗口超出阈值(零容忍)
3.2.3 饱和度检查
- 指标定义: CPU使用率、内存使用率、数据库连接池使用率
- 阈值: 所有资源使用率 ≤ 80%
- 评估窗口: 最近5分钟滑动窗口
- 容忍度: 允许单次突发,但均值必须低于阈值
关键设计原则:门禁阈值应比SLO目标更严格(例如SLO为99.9%,门禁阈值设为99.95%),预留安全缓冲,避免因指标抖动导致频繁阻断。
3.3 门禁与CI/CD流水线集成
门禁系统以微服务形式部署,对外暴露RESTful API。CI/CD流水线在“切换流量”步骤之前插入门禁检查阶段,通过HTTP请求调用门禁服务,并根据返回结果决定继续或中止。
3.3.1 集成架构
3.3.2 集成流程步骤
- 部署完成:流水线将新版本部署到Green环境,并执行健康检查。
- 预热等待:等待60秒,让指标采集器开始上报数据。
- 发起门禁检查:流水线调用门禁API(POST /api/v1/gate/check),携带环境标识和部署ID。
- 指标查询:门禁服务从Prometheus/Thanos查询最近N分钟的SLO指标。
- 规则评估:依次执行错误率、延迟、饱和度检查,生成通过/拒绝结果。
- 结果回传:门禁服务返回JSON响应,包含检查项明细和最终决策。
- 流水线决策:若通过,继续执行流量切换;若拒绝,中止流水线并触发告警。
3.3.3 门禁API设计示例
# 门禁检查请求示例
POST /api/v1/gate/check
Content-Type: application/json
{
"deployment_id": "deploy-20250321-001",
"environment": "green",
"service": "user-service",
"check_items": ["error_rate", "latency_p99", "saturation"]
}
# 门禁检查响应示例(通过)
HTTP/1.1 200 OK
Content-Type: application/json
{
"decision": "pass",
"summary": "所有检查项通过",
"details": [
{
"item": "error_rate",
"status": "pass",
"value": 0.02,
"threshold": 0.1,
"window": "5m"
},
{
"item": "latency_p99",
"status": "pass",
"value": 320,
"threshold": 500,
"window": "10m"
},
{
"item": "saturation",
"status": "pass",
"value": 65,
"threshold": 80,
"window": "5m"
}
]
}
3.3.4 流水线集成代码片段(Python示例)
import requests
import sys
def gate_check(gate_url, deployment_id, environment):
"""调用门禁服务并处理结果"""
payload = {
"deployment_id": deployment_id,
"environment": environment,
"service": "user-service",
"check_items": ["error_rate", "latency_p99", "saturation"]
}
try:
resp = requests.post(
f"{gate_url}/api/v1/gate/check",
json=payload,
timeout=30
)
resp.raise_for_status()
result = resp.json()
if result["decision"] == "pass":
print(f"[PASS] 门禁检查通过: {result['summary']}")
return True
else:
print(f"[FAIL] 门禁检查拒绝: {result['summary']}")
for detail in result["details"]:
if detail["status"] == "fail":
print(f" - {detail['item']}: {detail['value']} > {detail['threshold']}")
return False
except requests.exceptions.RequestException as e:
print(f"[ERROR] 门禁服务调用失败: {e}")
# 默认安全策略:调用失败时拒绝发布
return False
# 在CI/CD脚本中调用
if __name__ == "__main__":
GATE_URL = "http://gate-service:8080"
DEPLOY_ID = sys.argv[1]
ENV = sys.argv[2]
if not gate_check(GATE_URL, DEPLOY_ID, ENV):
sys.exit(1) # 中止流水线
安全注意事项:门禁服务应配置认证令牌(),CI/CD流水线通过环境变量注入。避免门禁API暴露在公网,仅允许内网或CI/CD Runner IP访问。
3.4 门禁决策与熔断策略
门禁系统不仅返回通过/拒绝,还应支持熔断和降级策略,以应对指标存储故障或门禁服务自身异常。
| 决策类型 | 触发条件 | 行为 |
|---|---|---|
| 通过 (Pass) | 所有检查项在阈值内 | 允许流量切换 |
| 拒绝 (Reject) | 任一检查项超出阈值且超过容忍度 | 阻断流量切换,触发告警 |
| 熔断 (Circuit Break) | 门禁服务连续3次调用指标存储超时 | 自动降级为“通过”,但记录审计日志 |
| 降级 (Degrade) | 部分指标数据缺失(如饱和度无数据) | 仅检查可用指标,缺失项标记为“跳过” |
降级策略建议:当指标数据缺失时,优先采用“跳过”而非“拒绝”,避免因采集链路故障导致发布阻塞。但需在审计日志中明确记录降级原因,供事后复盘。