
如果你打开 GitHub 状态页看到 “GitHub Actions and Pages are experiencing degraded availability” 这一行提示第一反应不应该是不停刷新自己的仓库配置而是先搞清楚官方到底在降级什么。这段提示的意思是GitHub 官方托管的 Actions 构建服务和 Pages 静态托管服务正在经历可用性降级服务没有完全中断但请求可能变慢、排队可能变长、偶发失败的概率会上升。那么Actions 和 Pages 同时出现降级实际影响是什么它不像“磁盘写满”或“依赖装不上”那样能直接定位到某一台机器更像整个 CI/CD 链路变钝官方 runner 排队、artifact 上传变慢、Pages 构建迟迟不更新。如果团队发布流程完全依赖 GitHub这个提示意味着上线窗口可能被拉长关键部署可能需要人工介入。这篇文章不是事故复盘不讨论具体事故的发布时间和根因。这里给的是遇到这行提示之后马上能用的完整处理思路状态页怎么读、影响怎么判断、问题怎么排查、Actions 和 Pages 分别怎么临时处理、状态接口怎么写监控脚本、恢复后怎么验证、长期怎么避免单点依赖。适合维护开源项目的开发者、用 Actions 做 CI/CD 的团队以及用 Pages 作为文档站和项目主页的人。1. 状态提示解读degraded availability 到底在说什么GitHub 状态页的告警一般分几个级别operational 表示一切正常degraded performance 表示性能降级partial outage 表示部分中断major outage 表示重大中断。degraded availability本质上属于降级这一类官方不会直接说“服务完全不可用”而是用“正在经历可用性降级”来提示部分请求受到影响。具体到 Actions 和 Pages用户感知到的差异很明显建议按下表对照排查服务降级时常见的用户感知需要关注的信息源GitHub Actions任务长时间 queued、runner 建立慢、日志拉取延迟、artifact 上传失败、workflow 随机失败状态页、Actions 运行记录、runner 日志GitHub Pages构建状态不更新、站点内容停留在旧版本、部署 action 卡住、自定义域名访问偶发异常状态页、Pages 构建记录、deploy 工作流日志需要强调一点这不代表每个人都会遇到全部问题。降级影响的是概率不是确定性。同一时间有人正常触发有人任务排队有人构建失败。正因为如此排错时不能只盯着一个现象要结合状态页、运行记录和构建记录三个信息源一起判断。如果状态页已经明确写着 Actions 和 Pages 降级那就要先按“官方端故障”来对待而不是反复修改 workflow 文件。2. 影响面分析谁最需要关注这次降级2.1 使用 Actions 做自动部署的团队如果你的项目用 Actions 自动跑测试、自动构建、自动发布到服务器或云平台降级期间最典型的症状是 workflow 排队。默认使用ubuntu-latest这类官方 runner 时任务会进入官方执行队列官方 runner 资源紧张排队时间就会从几秒拉到几分钟甚至更久。更麻烦的是有些任务排队超时会直接失败又触发重试进一步加重队列拥堵。对发布流程来说这是连锁反应。比如一个发布 workflow 由 build、test、deploy 三个 job 组成第一个 job 排队超时后面所有 job 都跟着无法执行。如果团队设置了定时任务比如每天早上跑数据同步、生成报表降级期间定时任务可能错过执行窗口。这类问题靠改代码解决不了只能通过调整调度策略或切换 runner 来缓解。2.2 用 Pages 展示内容的项目GitHub Pages 是很多开源项目主页、个人博客、文档站的首选托管方案因为它免费、和仓库联动、部署方便。降级期间最常见的现象是仓库代码已经推送但 Pages 站点内容没有更新。这里的“没有更新”可能是构建阶段卡住也可能是部署阶段失败两种情况的处理方式不一样需要看仓库的 Pages 构建记录才能区分。Pages 站点的特性是更新频率低、内容以静态文件为主所以降级对普通浏览者影响通常不大已经发布的站点还能继续访问。影响最大的是“正在发布新版本”的团队文档更新发不出去博客文章看不到项目主页改版迟迟不生效。如果站点还绑定了自定义域名降级期间要额外确认域名解析和 HTTPS 证书状态避免把部署问题和域名配置问题混在一起。2.3 与 Actions 官方 runner 强绑定的工作流很多仓库的 workflow 直接使用 GitHub 官方提供的 runner 镜像比如ubuntu-latest、windows-latest、macos-latest这些 runner 由 GitHub 统一调度。降级期间这类工作流的稳定性完全取决于官方资源的恢复速度。相比之下如果仓库配置了自托管 runner任务会进入自己的执行环境受官方降级的影响会小很多但这需要提前配置不是降级发生时立刻就能切换的。另一个容易忽略的点是 Actions 的并发额度。免费仓库和付费套餐对并发 job 数量有限制正常情况下任务排队会很快消化。降级时任务积压并发额度被长期占满后面的新任务更难进入执行队列。所以降级期间优先取消已经积压或不再需要的任务把并发额度让给关键 job比盲目重跑更有效。3. 排查前准备与第一步判断3.1 需要准备的信息与工具开始排查之前先确认手上有这些信息一个有 Actions 或 Pages 操作权限的 GitHub 仓库本机安装好ghCLI或者准备好一个有repo权限的 Personal Access Token能正常访问 GitHub 状态页和api.github.com知道自己仓库 workflow 文件的位置以及 Pages 的源分支和目录配置。用ghCLI 查看 Actions 运行状态是最直接的方式命令如下# 查看最近 20 条 workflow 运行记录 gh run list --repo owner/repo --limit 20 # 查看某次运行的具体日志run-id 从上一步获取 gh run view run-id --repo owner/repo --log如果本机没有安装gh可以直接调 GitHub REST API但请求头里要带 Token# 获取仓库最近的 workflow 运行状态 curl -L \ -H Accept: application/vnd.githubjson \ -H Authorization: Bearer YOUR_TOKEN \ https://api.github.com/repos/owner/repo/actions/runs?per_page20注意任何代码示例里的owner/repo、YOUR_TOKEN、run-id都要替换成实际值Token 不要提交到仓库或写进公开配置。3.2 第一步判断官方故障还是本地问题判断原则可以用“三步对照法”来记状态页是不是有 Actions/GitHub Pages 相关提示。是不是大量任务同时异常而不是单个 workflow 的问题。通过api.github.com拉取数据是否稳定返回是否频繁出现 5xx。如果状态页明确提示降级第一步就优先认定是官方端问题不要急着改 workflow。此时反复重试只会增加官方队列压力正确做法是观察状态变化或者按下一节的临时方案处理。如果状态页显示一切正常但你的仓库任务仍然卡住就要回到仓库本身检查并发配置是否设置过小、workflow 是否踩了语法错误、action 版本是否失效、Token 是否有权限、Pages 源分支是否被误改。这里最容易被忽略的是“状态页更新滞后”。状态页是人工或自动检测后发布的和实时故障之间存在时间差。所以更稳妥的判断是结合状态页提示和仓库实际运行记录如果两者都指向 Actions 或 Pages 异常基本可以确定是官方端故障如果只有单个仓库出现异常优先查仓库配置。4. Actions 降级期间的处理检查队列、控制重试、自托管 runner4.1 先查队列和运行记录而不是直接重跑Actions 降级时第一个要做的是检查当前有哪些任务在排队、哪些失败、哪些被取消。用下面的命令可以快速看到运行状态# 查看所有运行中的任务 gh run list --repo owner/repo --status in_progress # 查看排队中的任务 gh run list --repo owner/repo --status queued # 查看最近失败的任务 gh run list --repo owner/repo --status failure排错时要区分“任务排队”和“任务执行慢”。看gh run list输出里的STATUS和起始时间如果大量任务长时间停在queued说明 runner 资源紧张这是官方降级的典型表现如果任务已经in_progress但耗时远超正常值说明执行环境可能有问题。两种情况处理方式不同排队是资源问题执行慢可能是 action 下载、依赖安装或网络问题。4.2 控制重试避免最后变成重试风暴降级期间最常见的错误操作是“所有失败任务同时点重跑”。十几个任务一起重试会瞬间占满并发额度导致后面的关键任务进不了队列。更合理的做法是先取消掉明显重复或不再需要的任务保留最高优先级的一个或两个任务重跑等它们成功后再按顺序放行其他任务。如果你想在 workflow 层面控制并发可以在工作流文件里加concurrency配置例如同一分支同一组任务只保留一个运行实例concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: truecancel-in-progress: true表示新的任务进来时自动取消同组正在运行的任务。这个配置在日常开发中很有用降级期间尤其能避免大量重复任务堆积。4.3 自托管 runner 作为临时通道自托管 runner 是降级期间比较可靠的替代方案。它的原理是在你自己的机器上运行 GitHub Actions runner 程序任务从 GitHub 下发到你本机执行不再依赖官方 runner 资源。但这里有一个很硬的安全边界自托管 runner 默认可以执行仓库里任何代码包括被提交的恶意代码所以只建议在可信仓库使用不要把它配置到公开仓库也不要让它随意访问敏感凭证。注册和启动自托管 runner 是标准流程命令模板如下实际执行时需要在仓库 Settings 的 Actions - Runners 页面获取注册 token并替换owner/repo# 下载 runner 后先注册 ./config.sh --url https://github.com/owner/repo --token TOKEN # 启动 runner ./run.sh自托管 runner 启动后回到仓库的 Actions 设置页面会看到这个 runner 处于 idle 状态。它默认会接收该仓库的 job如果需要指定 workflow 使用自托管 runner可以在 job 配置里写jobs: build: runs-on: [self-hosted]降级期间临时切到自托管 runner 是可以的但要记住官方服务恢复后最好把关键 job 改回官方 runner因为自托管 runner 的维护、安全补丁、环境一致性都需要你持续负责长期运行成本并不低。4.4 关键发布加人工审批如果发布流程对稳定性要求高降级期间还可以临时给部署 job 加上环境审批让人工确认后再执行。GitHub Actions 的 environment 支持 required reviewers在仓库 Settings - Environments 里配置后workflow 中引用该 environment 的 job 会在执行前等待人工审批。jobs: deploy: runs-on: ubuntu-latest environment: production steps: - run: echo 这里执行部署命令这个配置的意义在于降级导致自动发布不可靠时至少把“能不能发布”的决策权交给负责人而不是让无人值守的流程在一个不稳定的基础设施上反复触发。5. Pages 降级期间的处理构建记录、临时发布与内容验证5.1 看构建记录区分是构建失败还是部署失败GitHub Pages 的发布链路通常分两步第一步用 Actions 构建静态文件并上传 artifact第二步用 deploy-pages action 把 artifact 发布到 Pages 服务。降级期间可能卡在任意一步。查看方式很简单打开仓库的 Actions 页面找到最近一次 Pages 部署工作流看是 build job 失败还是 deploy job 失败。如果是 build job 失败问题可能出在构建命令或依赖拉取如果是 deploy job 失败且状态页提示 Pages 降级基本可以确定是官方端问题。同时还可以去仓库的 Settings - Pages 页面看部署状态GitHub 会在这里显示当前站点内容对应的提交记录。5.2 临时方案本地构建等恢复后再触发Pages 降级期间不建议反复点击部署按钮。更稳妥的做法是先在本地把静态站点构建好确认产物完整然后等官方状态恢复后用workflow_dispatch手动重新触发一次部署工作流。如果你用的是常见的 Pages 部署 workflow可以临时手动触发on: push: branches: - main workflow_dispatch: # 允许在 Actions 页面手动触发workflow_dispatch这个触发事件很有用它让 workflow 可以在没有新提交的情况下手动执行。遇到 Pages 降级时先把构建产物保存在本地恢复后再触发一次比多次重试更高效。5.3 检查域名与 HTTP 状态Pages 站点绑定自定义域名时降级会影响部署但不一定会影响域名解析。验证站点是否正常可以用 curl 检查返回状态# 检查站点首页返回的 HTTP 状态domain 替换成实际地址 curl -I https://your-domain.com正常情况下会返回200 OK如果返回 502、503 或长时间无响应说明 Pages 服务端仍然异常。如果返回 200 但页面内容还是旧版大概率是缓存问题可以尝试带查询参数强制刷新或者等缓存过期后再验证。这里要注意修改 DNS 解析和审核 HTTPS 证书是耗时操作不要在降级期间频繁改动域名配置确认是部署问题还是解析问题后再决定是否动 DNS。6. 用 GitHub Status API 做主动监控与告警6.1 手动获取状态信息等待官方恢复时与其反复刷新状态页不如直接用接口拉取。GitHub 状态页提供了公开接口可以拿到当前整体状态和组件状态。先手动试一次curl -s https://www.githubstatus.com/api/v2/summary.json返回内容里会有整体状态描述和各组件状态字段结构以实际接口为准。如果你是第一次接触建议先用浏览器打开这个接口地址把 JSON 结构看清楚再写监控脚本。注意状态页域名和接口路径如果有变化要以 GitHub 官方页面里展示的链接为准不要在脚本里硬编码一个不确定的地址。6.2 写一个简单的轮询脚本手动请求能确认当前状态但服务恢复需要时间更实际的做法是写一个轮询脚本隔几分钟检查一次遇到状态变化时打印提示。Python 脚本如下只做轮询和状态输出实际使用时可替换请求地址和间隔import json import time import urllib.request status_url https://www.githubstatus.com/api/v2/summary.json interval 300 # 轮询间隔单位秒建议不要低于 120 while True: try: with urllib.request.urlopen(status_url, timeout15) as resp: data json.load(resp) status data.get(status, {}) description status.get(description, unknown) indicator status.get(indicator, unknown) print(time.strftime(%Y-%m-%d %H:%M:%S), indicator:, indicator, description:, description) # 只有状态不是 none 时打印告警实际字段名以接口返回为准 if indicator ! none: print(注意GitHub 状态非正常建议检查 Actions/Pages 运行记录) except Exception as e: print(请求状态接口失败:, e) time.sleep(interval)这个脚本没有绑定具体的消息推送渠道。如果要接到钉钉、邮件或企业微信需要按各自 webhook 的格式改通知部分这里不展开。建议把轮询间隔设置成 5 分钟太频繁的请求意义不大状态页本身也有更新延迟。6.3 把状态检查接进发布流程更进一步的做法是在发布 workflow 里增加一个“先查状态”的 step。比如构建前请求状态接口如果返回非正常状态就直接失败并提示需要人工介入。这个思路有价值但要注意两点第一状态页更新滞后可能服务端已恢复但状态页还没更新第二发布 workflow 多一次外部请求就多一个网络依赖如果状态接口本身不可用反而会卡住发布。所以更合理的组合是状态检查作为提示手段不强制阻断真正的人工审批放在 environment 环节。这样既能在降级时提前暴露问题又不会因为状态接口抖动阻塞正常发布。7. 恢复后的验证与长期高可用设计7.1 恢复后先跑最小验证看到状态页恢复 operational也不要立刻把所有积压任务全部重跑。正确的顺序是先运行一个最小 workflow比如只跑一次简单构建确认 runner 正常、artifact 上传正常再触发一次 Pages 部署确认站点内容更新最后再处理积压任务按优先级逐步放行。恢复验证清单可以这样写在 Actions 页面手动触发一个最简单的 workflow确认 job 能进入运行状态并正常结束。检查 Steps 里的 artifact 上传是否成功这一步决定后续部署是否可靠。手动触发 Pages 部署工作流等结束确认页面更新到最新提交。检查自定义域名是否能访问最新内容HTTPS 证书是否正常。以上全部通过后再恢复定时任务和常规自动发布。7.2 把降级预案写进日常配置一次降级暴露的问题往往不是“官方挂了”而是“你的流程太依赖官方”。长期来看有几条值得落地的设计第一workflow 要幂等同一代码重复运行多次结果一致这样重试才是安全的。第二构建产物要留底Pages 站点内容最好在本地或有自己的备份而不是只有 GitHub 上的一份。第三关键发布流程不要绑死单个 runner官方 runner 拥堵时能快速切到自托管 runner 或其他 CI 平台。第四状态监控要主动不能等用户反馈才知道服务异常。第五每次降级结束后记录一下哪个环节受影响、临时方案是否可用、重试策略是否有效、下次有没有更快的切换路径。这些都是工程化习惯和具体某次故障无关但对维护稳定性很有用。8. 常见问题与排查方法问题现象可能原因排查方式解决方案Actions 任务长时间 queued官方 runner 资源紧张或仓库并发额度被占满查看状态页、gh run list --status queued、检查并发配置降低提交频率取消重复任务或临时切换自托管 runnerworkflow 随机失败但代码没有改动官方 runner 或依赖下载不稳定查看失败步骤日志和最近成功运行对比先单独重试一次确认是否稳定复现Pages 站点内容长时间不更新Pages 构建或部署阶段延迟查看仓库 Actions 里的部署工作流、Settings - Pages 构建记录等待恢复后手动触发部署不要反复重试API 请求频繁返回 5xxGitHub 服务端负载或故障查看状态页通过 curl 手动复现增加退避重试错峰调用接口状态页正常但仓库 Actions 异常仓库并发配置、action 版本、Token 权限问题检查 workflow 配置、action 版本、Token 权限按仓库配置问题排查不要等待官方恢复自托管 runner 注册失败token 过期、网络不通、配置重复检查 token、网络、runner 运行日志重新生成 token删除旧 runner 记录后重新注册恢复后运行失败任务仍然失败官方已恢复但代码或环境有残留问题查看具体失败步骤日志修复 workflow 或清理环境后重试9. 总结与使用建议状态页出现 degraded availability 时最值得记住的三件事先看状态页再动代码降级期间不要批量重试控制并发恢复后先跑最小验证再恢复正常发布节奏。这个顺序能避免大多数“越修越乱”的情况。如果你维护的是开源项目、个人博客或中小团队文档站这次提示的影响可能只是发布变慢不用太紧张按照上面的流程确认状态和记录即可。如果你负责的是生产发布、自动化测试或对外服务那就要把降级预案当成正式运维事项来准备自托管 runner、本地构建产物、人工审批环境、状态监控脚本这些都可以提前配置。建议收藏备用。下次再看到这行英文提示第一步不是到处问而是照着状态页、Actions 运行记录、Pages 构建记录三条线走一遍大概率能在十分钟内判断出是官方问题还是仓库问题然后决定是等待还是切换方案。把每次降级当成一次演练等真正需要紧急发布时提前准备好的临时方案比临时找办法可靠得多。