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

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
日志服务 SLS,月写入数据量 50GB 1个月
简介:

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

  这不,最近又出了一个锅:从周五开始,每天到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
目录
相关文章
|
4月前
|
缓存 NoSQL 网络安全
【Azure Redis 缓存】Azure Redis服务开启了SSL(6380端口), PHP如何访问缓存呢?
【Azure Redis 缓存】Azure Redis服务开启了SSL(6380端口), PHP如何访问缓存呢?
|
3月前
|
NoSQL Redis Windows
windows服务器重装系统之后,Redis服务如何恢复?
windows服务器重装系统之后,Redis服务如何恢复?
74 6
|
4月前
|
存储 缓存 NoSQL
【Azure Redis 缓存】关于Azure Cache for Redis 服务在传输和存储键值对(Key/Value)的加密问题
【Azure Redis 缓存】关于Azure Cache for Redis 服务在传输和存储键值对(Key/Value)的加密问题
|
4月前
|
缓存 NoSQL 网络协议
【Azure Redis 缓存】Lettuce 连接到Azure Redis服务,出现15分钟Timeout问题
【Azure Redis 缓存】Lettuce 连接到Azure Redis服务,出现15分钟Timeout问题
【Azure Redis 缓存】Lettuce 连接到Azure Redis服务,出现15分钟Timeout问题
|
4月前
|
NoSQL Unix 网络安全
【Azure Cache for Redis】Python Django-Redis连接Azure Redis服务遇上(104, 'Connection reset by peer')
【Azure Cache for Redis】Python Django-Redis连接Azure Redis服务遇上(104, 'Connection reset by peer')
【Azure Cache for Redis】Python Django-Redis连接Azure Redis服务遇上(104, 'Connection reset by peer')
|
4月前
|
缓存 NoSQL Java
【Azure Redis 缓存】示例使用 redisson-spring-boot-starter 连接/使用 Azure Redis 服务
【Azure Redis 缓存】示例使用 redisson-spring-boot-starter 连接/使用 Azure Redis 服务
|
3月前
|
NoSQL Linux 测试技术
redis的安装步骤及前台,后台redis服务启动
这篇文章介绍了Redis的安装步骤,包括在Linux系统中下载、传输、解压、编译、安装Redis,以及Redis服务的前台和后台启动方法。
redis的安装步骤及前台,后台redis服务启动
|
3月前
|
NoSQL Linux Redis
Linux Redis 服务设置开机自启动
【9月更文挑战第2天】在 Linux 系统中,可使用两种方法设置 Redis 开机自启动:一是通过创建 `redis.service` 文件并利用 systemd 进行管理,包括定义服务参数和启动脚本;二是编辑 `/etc/rc.local` 文件,在其中添加启动命令。推荐使用 systemd 方法,因为它更符合现代 Linux 系统的设计理念。设置完成后,可通过 `sudo systemctl status redis.service` 检查服务状态。
472 3
|
4月前
|
存储 NoSQL Redis
【Azure Developer】一个复制Redis Key到另一个Redis服务的工具(redis_copy_net8)
【Azure Developer】一个复制Redis Key到另一个Redis服务的工具(redis_copy_net8)
【Azure Developer】一个复制Redis Key到另一个Redis服务的工具(redis_copy_net8)
|
4月前
|
NoSQL 网络协议 Linux
【AKS+Redis】AKS中客户端(ioredis)遇见Azure Redis服务Failover后链接中断的可能性
【AKS+Redis】AKS中客户端(ioredis)遇见Azure Redis服务Failover后链接中断的可能性