我的物联网项目(三十三) 2.0平台线上事故

2018-09-02 22:07:03

一大早到公司,厕所都来不及上,就被运维同事拉到一边,急促促反馈问题,说外面很多城市合伙人现在在投诉他们的账目数据不对,可提现的资金从昨天到现在一直没大的变化,平时一天可提现几百到几千,但是昨天无现可提取。了解了大概情况后,叫运维同事先安抚外面的城市合伙人,也和客服那边打了招呼,说正在紧急处理中,并和相关开发同事传达了目前的情况,叫他们也先分析下故障原因,我先出去倒杯开始,然后去趟厕所。我知道,这些事情本身处理也许不难,但是找到原因并根除才是需要时间去分析,我得先利用去厕所的时间自己先冷静的想想看看怎么去入手解决。

首先从我们的整个订单系统入手,订单系统设计如下:

112429_kePu_3724481.png

1.订单数据库,用户数据库,商家数据库,城市合伙人数据库,分别都有一张t_eventPublis(待发布事件表)和t_eventProcess(待处理事件表)。

2.订单库的待发布事件表是硬件设备上传订单数据的第一手数据源,后面做业务所涉及到的用户,商家,合伙人等(后面还有更多业务)都是从此源头一 一 下发。

3.简单的描述下整个流程。订单业务层MQ监听到设备上传订单数据,就会在订单库的待发布事件表插入记录,状态为未处理,定时调度会轮询此待发布事件表状态为未处理的记录,将未处理的数据通过MQ发送到用户层,用户业务层MQ监听到订单层发过来的数据,首先去用户库的待处理事件表查询此订单流水号是否存在,如果不存在,将记录插入待处理事件表,状态为未处理,同时回复订单业务层MQ已接收,订单业务层MQ监听到消息,会修改待发布事件表状态已处理。这样的话,订单业务层这块已做完。用户业务层定时调度轮询待处理事件表状态为未处理的记录,将此记录用来做用户相关的业务,如扣费等,同时在待发布事件表插入未处理记录(下一站:商家层),并修改待处理记录状态为已处理,这个扣费+插入待发布事件表+修改待处理记录状态三者是一个数据库层的事务。用户业务层定时调度轮询待发布事件表状态为未处理的记录,发给商家......,后面都是类似出来流程,这个不多重复。

按照此订单流程设计,合伙人账上没分成,首先得先查订单库的待发布事件表,先确定下设备有没有上传数据,要是这个地方没有上传数据,在这一块就丢订单的话,那基本就是无力回天了。从厕所出来,急急忙忙的登录到生产环境数据库,查询订单库的待发布事件表,发现昨天一共有五十几万数据,这个是正常的呀。说明订单数据库上传是正常的,总算放了大半的心了。那接着要查的是,订单库待发布事件表状态为未处理的有多少,查询一看,蒙了,居然有三十多万未处理,不断刷新查看,待发布事件表数据的确在处理,有时候会少1,2条,但是瞬间又多了6,7条,总的趋势是不断上涨的,说明处理的数据跟不上。不应该的,调度平台每台服务器每个业务有6个调度任务在处理,2台(后面有3台)服务器也就是12个调度任务在跑,不应该这么慢,查询了用户库和商家库相关事件表,发现也有一些事件数据在堆积,虽然不多,处理的也是缓慢。问题已经找出来了,结论是:订单数据并没有丢,只是事件堆积,来不及处理。

和开发人员沟通后,大家都去检查下调度任务做业务相关的日志,看看能不能发现什么。一会后,有人反馈,说订单调度日志中发现有大量调度任务经常抢不到分布式redis锁,报锁超时异常。

redisyc123.png

这个里面锁的默认释放时间是10秒,现在几乎有一大半的调度任务拿不到锁,只能靠锁默认时间释放,事件表处理速度肯定是跟不上的,这个里面我们需要去分析,为什么通过redis的setnx去拿锁会报锁超时,我们怀疑代码本身的逻辑有问题,就是拿到锁做完业务后,没有成功释放。查询代码后发现这个里面有两块地方是有问题的(都是低级错误)。

1.释放锁的地方很不规范,按照常规写法应该try{}catch{}finally{},在finally里面去释放,但是很多地方直接在try里面去做,甚至有些代码都忘记写释放了锁的操作,这个错误太低级,就不贴代码了。

2.spring.redis.pool.max-active=8 这个redis连接池最大连接数配置太低,估计当初也是从测试环境copy过来没有修改,线上环境这点连接数肯定不行的,因为现在线上redis就一个高配的,包括线上的常规业务用到也是这个redis,可以想象对redis的操作有多频繁,将此连接数据加到2000即可。

调度任务这块是可以单独发包的(这个也是分段式订单系统设计的优势),将上述问题修改后,发包后观察,事件数据库处理很快,1秒下降40多条,按照这个速度,大概几个小时后堆积的数据会慢慢处理完毕。

针对这次的故障事情,我也在反思,其实这种问题是可以规避的,除了日常项目管理中包括代码走查,审核的工作没有做好外,平台也缺一个监控平台,尤其是针对系统故障的预警(包括这次的事件堆积预警,锁的异常预警可以提前告知相关人员),毕竟做一个好用实在的预警监控平台也不是1,2天的事情,但是通过这些故障可引起警戒,并规划到下一步开发工作中。


(微信打赏)

(支付宝打赏)
原创不易,谢谢赞赏。你的支持就是我的动力,我会更加努力。
  1. 2018-10-02 19:34:58

    你文章中的泳道图画的很漂亮,请问是用什么软件画的呢?

    • 2018-10-02 20:52:02 - 管理员回复

      就是ppt,其实ppt很强大的,用的多了就熟悉了,随便发挥。

  2. 2018-09-03 16:19:05

    请问你们的事务是强一致性吗?

    • 2018-09-03 16:20:37 - 管理员回复

      是的,其实有些地方还在优化,后面会提到,将坑踩完,才会发现不完美,继续改进。

刚进公司的时候,公司明确招人只招毕业生,工作经验小于2年的开发人员,按照当初这样招人的原因很简单:工作经验多的,贵。所以这个事情就这么定了,当初java后台招了2个刚毕业的,1个工作经验1年半的,我们4个人一起搞后台

阿里云产品1000元服务器代金券大礼包免费领取。

阿里云服务器低门槛上云捷径,普惠上云,云服务器1核1G仅需293元/年。

企业级高性能实例,限时2-5折,限首次购买ECS用户参与,限购4台。