昨天客户反馈业务系统很慢,而且偶尔报错。
查看nginx日志:
[root@s2 nginx]# tail log/error.log
2017/03/14 12:54:46 [error] 17042#17042: *9305256418 upstream timed out (110: Connection timed out) while reading response header from upstream
看来是请求超时了。再查看nginx.conf配置,读取时间已经设置得比较长了。
location ^~ /api/faqs { proxy_pass http://api_faqs; proxy_redirect default; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 10; proxy_send_timeout 10; proxy_read_timeout 120; }
看来问题在后面的应用服务器,这里的接口后面是有三个.Net系统在服务,分布在两台windows服务器上。
其中一台服务器上有两个w3wp进程负责处理该接口数据,另外一台有一个进程处理。发现前者cpu使用已经100%,后者cpu使用也高达80%.
而且对应的.Net进程内存占用高达两个G。
奈何dotTrace和dotMemory已经过了试用期,只能自己看了。
使用事件查看器查看每秒请求数 Request/Sec.(在asp.net application 4里面),单w3wp进程发现请求实际上每秒约200多个,这个水平是低于平时的。
看来已经受cpu影响,请求处理能力大幅下降了。
查看数据库服务器,top 一下,mysql cpu 使用780%+(8核32g,相当于cpu使用也是100%了)。
看来是数据库问题,查top sql,qps。直接用sqlyog查看进程状态就行。
发现果然是该接口同时有几十个连接,在查询数据。
对看到的sql 做索引和查询优化后,单条sql执行时间已经是0ms。这时候数据库的cpu压力小了点,但是 应用服务器还是 100%。
最后只能分析代码了,因为该接口是需要一次性返回大量数据。
用redis和.Net Cache做了两级缓存,感觉是缓存没有命中,多次请求数据库了。
偷摸暂停接口功能,复制同样功能的接口,打上全流程日志查看,发现单次请求测试接口其实正常。
问题可能在高并发上,从代码看有几个地方有问题,最后加锁解决。