记一次redis挂机导致的服务雪崩事故,哦不对,是故事~

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介:

事故时常有,最近特别多!但每次事故总会有人出来背锅!如果不是自己的锅,解决了对自己是一种成长。如果是自己的锅,恐怕锅大了,就得走人了,哈哈哈。。。

  这不,最近又出了一个锅:从周五开始,每天到11点就不停的接到服务器报警,对于一般的报警,我们早已见怪不怪了,然后作了稍微排查(监控工具: CAT),发现是redis问题,没找到原因,然后过了一会自己就好了,所以刚开始也没怎么管他。然后,第二天报警,第三天报警。然后领导火了,然后我们只好说,要不等到周一上班咱们再解决吧!


周一,开发同学还没去找运维同学查问题,运维同学倒先紧张起来了。
原因是,他们从监控(监控工具: granfana, zabbix)上发现,服务器到这个点就会有一个访问量的暴增,真的是暴增哦,从图中可以看出,一个笔直的线就上去了。然后运维同学也给出了具体哪些接口的访问次数,然后给出了对比性的数据,在这个点的接口访问次数比其他时间要多上一倍以上的访问量。

然后开始排查:
  1. 是不是代码有问题,会不会因为自己调用自己导致流量激增?
确认最近项目有上线吗?我擦,我还真有一个项目是差不多这个时间上去的,吓死我了,赶紧查看代码是否有漏洞存在,几经排查后,确认没有问题。然后,抛弃该条路。

  2. 是不是代码里连接redis后,不释放该连接?

    从连接原理上和代码逻辑上,确认代码连接redis都是短链接,本次访问完成后释放该连接。(针对该问题,我还一度怀疑redis的连接可能被默默重用,但最终证明我是错的)
  3. 对比之前没有报警时的访问情况和现在的情况?
对比出问题前后访问情况之后,得知:在没有该问题时,也会有流量高峰,但是不是这个点,而且服务器也是正常运行。所以可以肯定,是后面发生了什么,才导致的问题!
  4. 会不会是定时任务反复访问自己的服务器,从而导致该流量高峰?
仔细检查任务中心(quartz),以及每台机器上的crontab,确认异常的脚本运行发生。不过,后来排除了该可能,可我们曾一度花了很长时间在排查这个可能性上!
  5. 统计每个接口的访问量,对比问题前与问题后?
对于该问题,主要通过统计服务器的访问日志,如apache的access_log, 得到接口地址,当然了,我们都是很多的集群环境,如果要在每台机器进行日志搜索,自然是要累死人的。咱们使用 salt工具,进行一台机器上直接搜索所有机器上的日志文件,进行统计。如:

salt 'cc*.cc' cmd.run "cat access_log | awk -F ' ' '{print $9}' | sort | uniq -c" > 1.log # 该处的双引号不一定能用哦

  6. 发现可疑接口,怀疑可能被黑客攻击,重点排查?

    排查过程中发现某些接口,正常的访问只能是get,但是却发现有post请求,以为是异常请求。于是找了一台测试环境下访问日志,也进行相应的统计:

grep -E 'POST /x/cc/public/notice |POST /x/cc/Public/init ' access_log | less

    结果,测试环境一样搜索出该情况,由于机制决定,最终确认该情况也为正常访问。


  7. 统计每个ip的访问情况,确认是否有黑客攻击行为?
与每个接口访问统计一样,统计ip

cat access_log | awk -F ' ' '{print $2}' | sort | uniq -c > 1.log

    最后,发现,ip都是无规律分布的,我们假设是被肉机模拟的ip,但是这条路也已经走不通了。

  8. 统计每个开放域名的访问情况,以确认是否是某个不安全的域名被扫描或者攻击了?
其实这个工作应该是留在前面进行的,但是我们也是到了后面,实在没了方向,才又折回来的,统计方法和(5)是一样的。

cat access_log | awk -F ' ' '{print $2}' | sort | uniq -c > 1.log

    然后,发现我们好几个业务的域名都暴增了,然后又没方向了,因为并不是哪个特定的业务出了问题,而是整体的。

  9. 查看业务代码日志,检查是否出现了相应的访问后端接口缓慢或异常的情况?
我随机抽看了下某台机器的日志,发现一切访问都正常,除了几个redis读取的异常外,并无异常值得注意。然后我作出了判定,后端接口没有问题。当然,这最终证明了我是错的,因为正是由于后端服务响应慢,从而导致了前端请求一直挂起,从而redis连接未释放情况,从而导致许多的redis连接!
  10. 根据统计中发现,在出现问题时,access_log中,有大量的" OPTION * " 的请求,为什么?
日志如下:

0 127.0.0.1 cc.c.com - - [24/Jun/2017:21:21:47 +0800] "OPTIONS * HTTP/1.0" 200 - "-" "Apache/2.2.3 (CentOS) (internal dummy connection)" 85 202 "-"

    该请求达到好几十万的访问,然后我们又去找,为什么会有这种请求,然后努力模拟这种请求,甚至想用线上服务器地址作为请求对象,但最终也没有模拟出这种情况。因为无论怎么请求,都会有一个相对路径地址产生,而且在OPTION成功之后,会默认触发一次GET请求。

    最终证明,这只是apache在管理子进程时,对自身进程的监听所产生的access log日志,对不是问题的方向。
  11. 所有问题都排查了,仍然不知道这流量是从哪里来的,只能问其他人了?
突然有人想起,产品改过某个流控规则,提示文案为”xx业务在xx点开抢,不要错过“!我靠,这不是秒杀系统了吗?流量不暴增才怪!
12. 终于找到问题了,然后再是拉上架构师,去理论!!!

原来是虚惊一场啊(业务人员一不小心搞的秒杀活动~,流量暴增属正常情况),虽然服务器多次挂掉,但是由于不是自己的锅,悬着的心总算掉下来了。

但是,归根结底,还是我们的系统不够牛逼啊,对于这突发的流量,一下没扛住,当然,在本案中,主要表现为redis没有扛住压力,赶紧强化进来吧!~

  对于推送活动一类的操作,一定要先跟技术运维做好沟通,将所有的流量预估,机器新增,安全因素考虑在内。让系统做好足够的准备,才能安稳地去搞自己的活动,否则任何一个环节都可能导致瓶颈,从而合使服务瘫痪。(应对这种情况,我们只有一种办法,重启服务甚至服务器)

  当然,这里有个问题也是我没想太明白的,就是有时候对于调用第三方的东西,你搞活动不去跟别人打招呼(一般情况都不会),那么,你的系统扛住了压力,那么别人的系统呢?

不要害怕今日的苦,你要相信明天,更苦!
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
7月前
|
存储 缓存 NoSQL
服务搭建篇(五) Redis单机/redis-cluster集群搭建
当客户端向一个错误的节点发出了指令,该节点会发现指令的 key 所在的槽位并不归自己管理,这时它会向客户端发送一个特殊的跳转指令携带目标操作的节点地址,告诉客户端去连这个节点去获取数据。客户端收到指令后除了跳转到正确的节点上去操作,还会同步更新纠正本地的槽位映射表缓存,后续所有 key 将使用新的槽位映射表。下面第21步操作会有演示
97 0
|
10月前
|
NoSQL Java Linux
Centos7实现单服务器安装并开启多个Redis服务
Centos7实现单服务器安装并开启多个Redis服务
344 0
|
2月前
|
弹性计算 NoSQL Redis
阿里云ECS使用docke搭建redis服务
阿里云ECS使用docke搭建redis服务
158 1
|
2月前
|
存储 NoSQL 前端开发
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(集群指令分析—实战篇)
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(集群指令分析—实战篇)
12 0
|
2月前
|
存储 NoSQL 算法
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(集群指令分析—上篇)(二)
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(集群指令分析—上篇)
31 0
|
2月前
|
存储 监控 NoSQL
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(集群指令分析—上篇)(一)
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(集群指令分析—上篇)
30 0
|
2月前
|
缓存 NoSQL Shell
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(持久化功能分析)
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(持久化功能分析)
165 0
|
2月前
|
存储 缓存 NoSQL
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(集群功能分析)(一)
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(集群功能分析)
394 0
|
2月前
|
NoSQL 关系型数据库 MySQL
Docker安装详细步骤及相关环境安装配置(mysql、jdk、redis、自己的私有仓库Gitlab 、C和C++环境以及Nginx服务代理)
Docker安装详细步骤及相关环境安装配置(mysql、jdk、redis、自己的私有仓库Gitlab 、C和C++环境以及Nginx服务代理)
249 0
|
2月前
|
缓存 NoSQL Java
【九】springboot整合redis实现启动服务时热点数据保存在全局和缓存
【九】springboot整合redis实现启动服务时热点数据保存在全局和缓存
49 0