概述:
由于我们负责的基础组件(xxl-job)经常需要做一些定制化的改造因此会经常的重启测试环境(devops -> git pull 指定分支 -〉打包部署)考虑到7*24小时保证服务的可用,我们使用Linux 定时任务crontab 做了一个每分钟探活重启脚本,为了方便扩容这个脚本也上传到项目的git中,git 中的探活脚本指定的是生产环境(使用生产环境的Apollo配置)。因为发现接到用户反馈测试环境不可用了,因此登录ECS使用命令进行了重启,与用户沟通后确认可以。然后开始看为什么测试环境探活脚本没生效,因为很长时间没有改动测试环境认为探活脚本中的环境是测试,然后发现执行失败。发现探活脚本中的项目路径不正确,更改项目路径后。kill 掉应用线程观察探活脚本,一分钟后发现无效(crontab执行有问题,查看crontab tail -100f /var/log/cron)发现脚本有执行。验证探活重启脚本发现正常后几分钟后再次kill进程,发现脚本没有执行权限。
业务方反馈问题:有资损风险的任务出现执行失败,请求联合排查
影响时间:3分钟
在排查探活脚本为什么无效期间接到业务方反馈生产环境有资损风险的任务出现执行失败。查看调用记录发现有请求成功任务结果丢失标记失败有任务触发请求失败两种问题,同时发现任务执行的执行器地址竟然都是同一个。第一结论业务方这台机器可能有问题,然后联系业务方排查这台机器。
问题1:为什么有些请求成功?有些请求失败?
排查结果:因为我们的xxl- job经历过一次集群扩展(从3台ECS 扩展到了8台),发现老的三台ECS可以访问测试,预发和生产,新增的5台ECS只能和生产环境通信。因为网络安全组配置的不同
问题2:为什么都是这台机器执行失败?
排查结论:这台是测试环境的机器,生产数据在测试环境运行无论结果如何都是失败的业务逻辑不通,其次当我们测试环境xxl-job admin 关闭或者正常重启(没有使用生产环境的Apollo时),生产环境的执行结果是丢失的(生产和测试都没有执行结果)
先排查失败数据并修复数据降低影响:
1.从xxl-job执行日志中拉去哪些失败的数据没有被重试(标记结果丢失不会进行重试,老三台ECS触发的任务是无法接收到回调结果,因为测试环境已经正常)
2.新的5台ecs执行请求失败的都触发了失败重试逻辑
3.比对相关任务执行情况,将影响降到最低
初步问题定位 :
1.业务方测试服务错误的指定了xxl-job的注册地址或通过手动设定执行器地址导致测试环境进入到xxl-job生产的执行器列表中
依据:
1.生产环境xxl-job使用的数据库是有白名单的,只有在白名单中的ip才可以链接数据库
2.我们没有变动过生产的xxl-job(重启)
3.联系DB负责人确定我们的测试和预发环境不在白名单的IP中,xxl-job无法连接数据库是无法写入新的执行器地址的
业务方回复:他们没动生产环境,他们也没有操作重启测试环境。没有更改执行器注册地址(手动设置可以修改)
重新定位问题:
1.测试环境ping数据库连接地址验证是否可以ping通,发现可以
2. 确定测试环境验证探活脚本中的环境变量是指向生产,使用了生产环境的Apollo配置导致业务方的测试环境执行了生产环境数据,排查探活脚本发现确实是脚本中环境变量是生产。很庆幸业务方第一时间发现关注到失败告警,并认真处理将资损风险降到最低
疑问:为什么测试环境IP没有在白名单中也可以链接数据🤔️。。。
1.沟通DBA排查测试环境和预发环境为什么可以链接生产数据库
2.联系运维同学调整老的三台ECS调整安全策略(生产环境不允许访问测试,测试不允许访问生产)对不同环境的通信进行隔离
3.考虑解决方案:容器化部署(pod进行了不同环境间的隔离),ecs 调整安全组,环境验证
DBA回复:测试环境和预发环境在特殊的安全组,可以访问和链接生产环境DB,在一个白名单网段内。这是一个网段,一个网段!!!
我在风中凌乱,原来的DB白名单还藏着一个白名单网段,我原来在裸奔。。。。
总结:
1.开发人员一定要是使用最小权限,不要认为你技术多牛,有一天一个rm -rf 一个误操作一年或几年的付出都付之东流
2.基础组件一定要有日志和告警,这次多亏业务方效果关注并重视了失败告警才避免了一场浩劫
3.各环境间一定要做好隔离工作,禁止不同环境之间的通信请求
4.任何中间件尤其是基础组建的改动也要发公告,告知相关业务方,尤其是业务方会产生资损的可以将他们作为重点,每次功能的扩展和上线邀请他们参与验收(高频,资损,量大,影响范围广的也无妨)