记一次驻场开发协助优化

本次驻场主要任务

1:协助解决排查性能问题

2:排查隐患问题

3:上线之后的保障

性能问题排查

性能问题大部分集中在和mysql相关的调用,以及redis使用相关的问题,mogodb相关问题,内存问题,sso问题等等。

性能压测时以及驻场这段时间具体遇到的问题如下

mysql相关

1:mysql连接池打满,导致mysql挂掉,后来排查下来基本和慢查询有关系,慢查询个数和连接个数是成正比的。后面找到慢查询,逐个优化

2:mysql字段没做索引,增加索引/增加联合索引。

3:直接调用的接口包含很多数据和调用,其实不需要那么多数据和调用,重写接口,免去不必要的调用

4:类型语句

update `xxx` set join_status = 'Approved',latest_updated_user_id ='ba2c0000-00ce-5254-f4ba-08d7fb3cb569',latest_updated_date = NOW() where id  in (select user_id from xxx where id in ('ba2c0000-00ce-5254-8dd3-08d7fd9e80da'));

这种两层in的语句效率特别差,执行时间要上百秒,咨询dba之后,建议使用join,改为join之后效率提升。

5:发现有update语句有慢查询,最后发现是对一条记录每秒发送了大量的update请求,导致了行锁,最后对压测用例进行修改,随机选择key。

6:一个sql查询出来的结果有几百万条,查询需要100多秒(索引也都做了),后面推荐改为分页查询/改为为limit 10;

7:myslq where条件顺序不对导致影响sql性能,如:where a=xx and b=yy; 如果a=xx的区分度很低,这条sql性能就不会很高,需要将b=yy放到where条件的前面。

其他db相关

1:乱用redis,value大小有1.8M,导致redis挂掉,还有使用了zset,value有好几百兆,居然还有这种的。。。。。。

2:mogodb字段没做索引,导致全表扫描,查询需要100多秒,导致服务不可用,后续mogodb加上索引即可(问题是压测环境已经加了,居然生产环境没加。。。。。)

3:mogodb连接池打满的问题,调整mongodb客户端字符串参数minPoolSize=0,连接基本降低下来了(但是过程挺曲折,中间做了多次调整参数,最后才发现这个参数有效)。

4:es性能一直不达标,经过我们的es专家排查,发现是做了10个索引,每个索引5个分片。

5:sso压测,使用非集群版的时候redis会cpu消耗非常高,想换为集群版来解决该问题,但是发现使用了redis事务,集群版不支持事务,后来修改开源源码,将事务部分代码改掉

其他

1:使用了C#原生的字符串拼接+=,效率很差(我是c++技术栈,后来才知道这个),改为stringbuild

2:压测环境和准生产环境配置不一致,导致压测结果看起来不正常,梳理环境配置问题(nginx配置,mysql索引,mongo索引,apoll配置),改为一致,提了好多天,推了好多次,一直没人力,最后终于改为基本一致,准生产环境性能才能提升起来。

其中遇到一个坑爹的问题是,clb后端的nginx有配置某台机器,但是该机器的gateway这个域名的转发根本就没有配置,导致压测gateway相关接口的时候qps总是掉坑,查了好久才查出来问题。

3:部分接口在准生产环境性能开始能到6~8万,忽然降低到4w,然后以为维持在4w qps,经过多次排查发现是jmeter压测集群导致,集群压力过高。

4:java的程序,能上到30k的qps,但是马上掉到20k,一会又到30k,然后又会掉下来,最后排查下来是java gc的问题。

5:压测是有的接口qps几乎掉0,后来发现和基础组件有关,mq队列很容易满,相应接口只能减少对mq的依赖,比较奇葩的是一个服务发送数据到mq,然后居然还是这个服务来消费mq的数据。

6:压测过程中,发现consule服务注册发现cpu很高,出口带宽也很高,最后发现使用consule不合理,居然没使用agent缓存,每次获取对应服务的ip等信息,都要调用到consule服务端的主节点,主节点压力太大,这个需要改为最好使用agent缓存的方式,而且最好是有变动了,服务端主动通知agent,不要去轮询,增加服务器压力,没想到他们的使用方式真的很奇葩。

7:很多接口都要加频控和验证,防止被刷,比如按照ip/user_id来做频控,控制每5秒/10次,可使用redis来实现。

8:比如登录接口,担心流量大/被刷,可增加一层滑动验证/验证码,确认之后才能登录。

风险问题:

1:虽然导致redis大key的相关接口已经修改,但是监控不能少,还要实时监控大key,但是监控有滞后性

2:mysql及时改掉了测试时候的慢查询,但是最终上线环境可能不一样,还是有可能有很大慢查询,而且上线有几百台服务器,很有可能mysql扛不住(因为他们基本是单库单表),所以增加了两个解决方案,一个是督促分库,后来多次要求,终于可以把一个库分为三个库(上线之后就是3个实例),另外增加一个同步工具,根据业务将部分数据同步到redis,部分数据就可以直接读redis,不用读db,减少db压力。

3:soo的问题一直不达标,经过多次排查发现是和组件使用方法关系很大,修改代码之后,并且扩容机器qps扩上去(然后c#还有很多坑,内部都走http请求,还有的走https请求,调用一个本服务的方法,还有经过一个https请求绕一圈)。

4:mongodb随便通过参数配置,连接数降低下来,但是面对几百台机器的时候,连接池随时还可能打满,所以还需要通过分实例的方式来拆分mongodb,减少风险。

5:监控不够完善,告警机制不够完善,应急预警不够完善。

6:对于有安全漏洞的接口,加上修补漏洞的相关代码之后,可能会导致性能降低,甚至接口性能不达标。

 

这段时间其实大家都挺辛苦的,压力也比较大,每天下班都很晚,想办法做各种性能优化,以及各种问题排查。

最后项目上线了,才发现其实没有多大的流量,系统上线十几天,也基本能稳定运行,偶尔也会出现一些小问题,但基本也能被解决。

最后一个很大的感受就是很多业务为主的公司只要能保证业务99%以上的情况正常,对应他们来讲也完全ok,但是对于大公司来讲,对技术最求完全不一样,至少希望是三个9,甚至更高,这就导致了过程中对某些问题的看法有不同的重视程度,从而也会产生一些相互diss的情况。

 

 

你可能感兴趣的:(记一次驻场开发协助优化)