记录一次调线的心路历程

引言    

    最近小编刚介入了一个上线三、四个月的项目,我直接负责调线上用户反馈的问题,主要的问题是最近一些数据频繁出现问题,用户已经还款,但是系统不显示,系统每天早上异常的卡。由于公司一些人事变动,之前参与这个项目开发的后台人员都撤了,现在交到我这里负责,还有很多新需求,我想尽快的close掉这个项目,新需求就直接交给我另一个同事负责开发,我直接介入线上问题,下面总结一下这一周来踩过的坑,以后在项目中一定要避免。

第一、又臭又长的SQL

    项目是给一家P2P公司的贷后团队用的,最近几周用户的数据量疯狂的上涨,有一个表的数据已经接近千万,在前两天早上用户一上班就开始在群里喊系统特别卡,根本没有办法使用,小编在后台看到mysql的IO非常的高,查看mysql执行进程show processlist的时候,有个别的sql竟然执行时间为900s,这些sql导致索引失效,下面看一下类似sql:

SELECT
CT
t1.case_id _id as case_id,
d,
t1.contact_nam_name as contact_name,
e,
t1.contact_tel_tel as contact_tel,
l,
t1.call_typ_type as call_type,
e,
t2.tel_len_length as  call_duration
FROM
case_tel${postfix} t1
INNER JOIN (
SELECT
case_id as case_id,
contact_tel as contact_tel,
max(tel_time) as tel_time,
sum(tel_length ) as tel_length
FROM
case_tel${postfix}
where tel_type = 1 and case_id in
<foreach close=")" collection="caseIdList" item="listItem" open="(" separator=",">
    #{listItem}
</foreach>
group by case_id,contact_tel) t2
on on t1.case_id _id =  = t2.case_id _id and  d  t1.contact_tel_tel =  = t2.contact_tel_tel and nd t1.tel_typ_type = 1 and  (  (t1.tel_tim_time =  = t2.tel_tim_time or or t1.tel_tim_time is null)
group by by t1.case_id,_id,id,t2.contact_tel_tel

在mysql终端执行:show full processlist;

解决办法:

    客户非常着急,所以在分析了这个sql主要目的后,直接将这个sql废弃掉,然后将这个sql的工作转移到内存中来实现。

第二、滥用索引

  有些insert语句也非常的慢,在查看表以后发现,有几张表上的索引六七个,并且有多个字段联合作为唯一索引,在跟踪日志和代码的时候发现,他们竟然用唯一所以在解决重复插入的问题,也就说在插入的时候并不验证是否重复,而是直接靠唯一索引来抛出异常,而在各插入操作在用户进入系统的40分钟以内是用非常频繁,因为我们需要去用户那里拉取数据。

解决办法:

    在数据库中加入唯一字段,在插入之前校验,然后去掉没有必要的索引,调整一些sql,在查询的时候避免索引失效

第三、增量获取数据

   我们去用户的核心系统柆取数据的时候竟然是全量拉取,在数据量少的时候没有什么感觉,但是数据量一旦上来必然导致接口卡顿,虽然这和用户提供的接口有关,但是我们的开发da当时竟然接受这样接口,现在我要求用户必须增加时间戳,增量拉取。

第四、慢sql

    原来项目组有两个特别喜欢写那种很长的sql,看起来sql写很牛逼,但是从来不考虑索引失效的问题,这就导致现在项目中的慢sql已经高达将近3G,让我们优化这些慢sql的人是一种什么样的体验,这是我们在写sql的时候必须要注意的一个问题,前期我们虽然不能百分百避免,但是我们一定要有这样的意识,要熟悉explain,看一下自己的sql执行效果。

第五、系统非常复杂

    因为是接手的新项目,所以在了解一些需求后,觉得系统做的非常复杂,这样的后果就是给自己埋雷,用户容易操作失误,这样就会导致事故,需要我们手动恢复数据,也是造成系统慢的一个非常重要的原因,有些需求就是需要我们把数据都load一遍才能给出用户的一些数据,这是产品层面的问题,就不过多的讨论。

接下来总结一下,这次数据问题频繁出现的原因

第一、代码隐藏事故

    这次出现的原因是在07.17号,由于用户的核心系统问题,给而我们的系统推送了一批没有逾期的案件(脏数据),当时主要开发的人请假没有来,另外一个同事帮忙解决,其实就是删除一些数据,因为是线上,所以采用了软删除,这就是问题的开始,而在08.07这批数据真正的逾期了,用户又推送了一批数据进来,和之前的一样,这样我们数据库就有两份同样的数据,但是在业务处理的时候,并没有在代码中增加软删除的状态标识,在取数据的时候,如果有多条就返回第一条,并且多处处理都有这个问题,这就是事故的开始。

    在跟踪了代码以后,需要及时处理这些问题,小编只得将数据备份以后,先手动删除那些脏数据。

第二、滥用try...catch..

   在代码中很多地方都采用了try..catch...按说这是一个好的习惯,但是你不能怕别人知道你系统报错,你就直接将错误吃掉啊,这就导致用户看到的结果是成功给我们系统推送了数据,实际上我们异常根本没有处理完,在其中某个环节出现问题,而我们只能跟踪代码才能知道,到底是那个环节出现问题,我们不能活在理想世界里编程,这就导致我们的重试机制根本就没有什么作用

小结

    因为是新项目,直接负责调线上,还是非常有压力的,尤其是修正一些线上数据的时候非常的紧张,生怕修改此处影响别的业务数据,在一个就是线上的问题都是非常着急的,需要我们在短时间内做出响应,所以还是比较锻炼人的,总之经过一周的奋斗问题解决的差不多了,在这总结一下这次调线的心路历程,希望在别的项目中避免。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

g-Jack

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值