git操作触发流量监控预警事件复盘
背景:
调研大仓.git内存治理方案,拉取大仓所有分支并在个人空间创建了私人仓库进行方案实践。由于大仓分支数和commit数等较多,一次性推送等批量操作在短时间内触发了大量api请求,导致gitlab告警。
告警统计:
略
能看到是在短的时刻,QPS突增。
问题定位:
到底什么原因导致的异常。需要理清上下文:
- 过去两天也在执行类似的指令,使用本机终端。
- 在无新增指令的情况下,用了vscode的终端执行命令。
- 在vscode的终端执行命令的过程中,有过多次无响应,并强行ctrl+c中断的操作。
问题猜测是否vscode的终端有重连重试机制,回看操作日志。最终发现如下问题:
vscode终端执行gc时,长时间没有交互输出,主观认为其卡住了,于是手动截停。换到本机终端,执行其他命令。在git remote update -p,以及git fetch 以后,查看本地分支仅有一个新建的分支,并且只有一个readme.md文件,进行git push origin --all,到此为止还没出现异常。
问题在于:后续执行了,git push --mirror
操作,因为分支权限问题,本地显示被拦截推送。问题是,虽然被拦截了,但是接口请求是发送出去了,再结合上图可知,进行git gc -- aggressive操作的不慎,增大了.git的空间。执行git push --mirror
操作,分支数、commit数是原来基础接近8-9倍。最终引发告警。
原理科普:
git push --mirror
是一个 Git 命令,用于推送本地仓库中的所有引用(包括分支和标签)到远程仓库,并同时删除远程仓库中本地不存在的任何引用。这使得本地仓库和远程仓库在结构上完全相同,即镜像。以下是
git push --mirror
的原理和工作方式:
- 列出所有本地引用:Git 首先列出本地仓库中的所有引用,包括所有的分支(例如
refs/heads/master
)、标签(例如refs/tags/v1.0
)以及其他可能的引用(例如笔记或远程跟踪分支)。- 比较本地和远程引用:然后,Git 获取远程仓库的所有引用列表,并与本地列表进行比较。这可以确定哪些引用在本地存在但在远程不存在,以及哪些引用在远程存在但在本地不存在。
- 推送本地引用到远程:对于本地存在但远程不存在的引用,Git 会使用适当的
git push
命令将这些引用推送到远程仓库。- 删除远程中本地不存在的引用:对于远程存在但本地不存在的引用,Git 会尝试删除这些远程引用。这是通过发送一个特殊的引用更新命令到远程仓库来实现的,该命令指示远程仓库删除相应的引用。
- 保持镜像状态:通过这种方式,
git push --mirror
确保本地仓库和远程仓库在引用结构上是完全相同的。这使得远程仓库成为本地仓库的一个镜像。需要注意的是,
git push --mirror
是一个强大的命令,应该谨慎使用。因为它会删除远程仓库中本地不存在的任何引用,所以如果不小心使用,可能会导致数据丢失。通常,这个命令主要用于完全同步的镜像仓库,而不是用于常规的代码协作仓库。
反思总结:
-
谨慎编码。
- 不仅要清楚指令原理,还需要理清验证好执行的上下文,一步步来。验证清楚上文,保证下文执行有效性和安全性。在这个案例里面就是执行
git push --mirror
之前没有验证du -sh .git
git的大小。 - 个人仓库,本地环境等都需要注意。在公司进行的很多开发操作,并没有完全地隔离。隔离有多个层面:代码逻辑层面、使用服务层面等。即使是个人仓库,使用的依然是整个gitlab的服务。本地对远程的每个操作都是以请求的形式使用gitlab的服务提供的服务。服务使用会占用资源,如果个人仓库服务占用资源过多,肯定会影响到其他正常请求。因此,是需要从多维度理解当前任务和操作的隔离性和风险。
- 不仅要清楚指令原理,还需要理清验证好执行的上下文,一步步来。验证清楚上文,保证下文执行有效性和安全性。在这个案例里面就是执行
-
对于依赖到其他服务的操作。需要评估当前任务的并发量,选择合适的时间,错峰操作。如周末,凌晨等。分批操作,减少统一大并发的操作。
-
信任与同步。
- 信任指的是,不能完全依赖服务供给侧的能力支撑。大批量访问等操作应在业务端做好拆分,增加安全屏障,在前置链路中做好问题处理,需要认识到链路末端集中处理的压力和风险。
- 同步风险操作,应告知服务供给侧计划操作内容、计划操作时间、范围等。在信息同步的过程中对齐认知差,减少不必要的问题耗时,多方协作提高生产效率。
转载自:https://juejin.cn/post/7351649413402476596