运维平台API优化实践小结
author:一佰互联 2019-03-29   click:221

简介:大家对运维系统的定位是能用,好用,对于高可用和性能的关注会比较少。一般来说,我们都会感觉差不多就行了,直到今天临时停了下服务,发现对已有的业务使用产生了一些影响,所以系统的稳定性和性能问题成为我们要格 ...

大家对运维系统的定位是能用,好用,对于高可用和性能的关注会比较少。一般来说,我们都会感觉差不多就行了,直到今天临时停了下服务,发现对已有的业务使用产生了一些影响,所以系统的稳定性和性能问题成为我们要格外关注的一个方面,简单来说,现状需要改变。

如果把近期的几个问题汇总起来,你会发现有些问题开始变得严重起来。

1)有一天晚上9:00左右的时候,运维系统的服务突然无响应,页面打开很卡顿,查看系统进程都是正常的,日志中也没有额外的信息显示,最后重启服务了事。

2)最近完成了初版的任务系统部署,要逐步把一部分的数据库批量任务迁移到任务系统中,结果在元旦前,自己在任务系统接入任务的时候,任务系统的默认并发是20,而平常数据库运维系统是5,导致数据库运维系统直接无响应,说起来真是尴尬。

报错信息如下,感觉是超时自动终止了。

运维平台API优化实践小结

3)使用postman调用单独的API任务时,超时60秒会直接无响应。

运维平台API优化实践小结

4)同样的任务使用测试环境竟然会比线上环境要快,性能差异有10-20倍,就好比测试环境10秒左右,线上环境需要近200秒5)使用Uwsgi的超时参数进行对比测试,暂没有达到预期效果这些问题综合起来,会让我们本来对使用还算顺利的系统充满疑问,一种疑问是功能上的,按照目前的支持情况,是存在一些潜在问题的,会对正常的业务支持有影响吗,另外就是性能,测试环境性能比线上的还要好,这个很难解释的清楚,而且实际说起来也很尴尬。面对这样的一些问题,初步的感觉是这个问题本身是比较明显的,解决的方向就是处理超时问题,只是暂时没有找到一个合适的配置,或者说是开关。首先这是一个独立的API, 能够独立运行,说明业务逻辑是基本正确的。我们最开始的着手点是分析web服务器层面的配置,目前直接的差别就是测试环境是mange.py方式的部署启动,线上环境是Uwsgi的部署方式。通过反复的对比测试,可以明确几点:
  1. 测试环境的应用配置和线上配置是基本一致的,除了服务器和数据库IP不同之外,其他的配置都是统一的。
  2. 线上环境临时切换成manage.py方式,重新调用API,唯一的差别是产生60秒超时的时候,mange.py的方式会一直等待任务正确执行完毕,而Uwsgi的方式会报无响应的错误。
所以按照目前的分析进度,这个问题陷入了僵局,所以一个解法就是查看API的逻辑,看看逻辑层面是怎么回事。 这个API任务是一个看起来很普通的任务,主要的流程是通过sql调用得到数据库中的表的元数据信息,然后把这些元数据持久化起来,通过时间维度来采集表级元数据,为后续可以分析表的碎片率,表的数据量增长情况打好基础。从任务的流程来说,我通过子任务描述来细化:
  1. 通过ansible的方式调用sql得到表的元数据信息
  2. 解析得到的元数据信息
  3. 在持久化之前,会从已有的数据表把最新的一条记录更新,这样持久化之后的记录中的表只有一个是最新的。
  4. 完成持久化操作,即insert的操作
整个4步流程中,直接看是没问题的。如果要细化问题的瓶颈,我们可以在每个步骤都打上时间戳,这样就可以明确定位出么每一步的执行时间。在做这个补充操作的时候,我开始重新理解这个流程,突然发现了一个潜在的问题。 代码里有这样的一段:if MySQL_table_status.objects.filter(ip_addr=vm_ip_addr, db_port=int(vm_db_port),db_name=database_name, table_name=table_name,latest_flag=1).count() == 1: MySQL_table_status.objects.filter(ip_addr=vm_ip_addr, db_port=int(vm_db_port), db_name=database_name, table_name=table_name,latest_flag=1).update(latest_flag=0,)仔细看来突然发现不大对劲。这个表的数据量在线上已经接近百万了。而这个表的索引只有一个id主键,所以明显是在这个查询条件中脱离了,也就是这个查询是走了全表扫描,试想如果这个数据库有1000张表,按照这种逻辑,性能会放大许多倍,所以到了这里问题的瓶颈已经比较明确了。在线上环境添加了相关的索引之后,重新调用API,在10秒内就给出了结果,和测试环境的时长是类似的了。 然后我们再来看看之前的几个比较诡异的问题。

1)有一天晚上9:00左右的时候,运维系统的服务突然无响应,页面打开很卡顿,查看系统进程都是正常的,日志中也没有额外的信息显示,最后重启服务了事。 其实明白了原因,再加上一个背景,问题就很明显了,晚上9:00的时候会跑一批任务,会把几百个MySQL实例的元数据都采集一遍,结果触发的时候,并发导致系统无响应。

2)最近完成了初版的任务系统部署,要逐步把一部分的数据库批量任务迁移到任务系统中,结果在元旦前,自己在任务系统接入任务的时候,任务系统的默认并发是20,而平常数据库运维系统是5,导致数据库运维系统直接无响应,说起来真是尴尬。

这个解决了API的效率问题,超时的概率就很低了。所以也不会存在并发20导致系统崩溃了。

3)使用postman调用单独的API任务时,超时60秒会直接无响应。 这个问题迎刃而解。

4)同样的任务使用测试环境竟然会比线上环境要快,性能差异有10-20倍,就好比测试环境10秒左右,线上环境需要近200秒。这个问题很明确了。5)使用Uwsgi的超时参数进行对比测试,暂没有达到预期效果所以到此问题的初步解决就告一段落了,而对于Uwsgi的超时问题还需要继续排查,但是对于现在的任务接入来说已经基本可以满足。顺着这条路来对比下有索引和不存在索引时,异步任务的性能差异。原本需要近3000多秒。

运维平台API优化实践小结

而改进之后,只需要50多秒。

运维平台API优化实践小结

通过这样一个问题也可以折射出我们对于性能优化的必要性和问题的分析思路对于我们解决大多数问题是相通的。

本文仅代表作者个人观点,不代表巅云官方发声,对观点有疑义请先联系作者本人进行修改,若内容非法请联系平台管理员,邮箱2522407257@qq.com。更多相关资讯,请到巅云www.yinxi.net学习互联网营销技术请到巅云建站www.yx10011.com。