前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CDB 的控制台的超时雪崩问题

CDB 的控制台的超时雪崩问题

原创
作者头像
腾讯云开发者社区
修改2017-11-03 14:49:18
1.3K0
修改2017-11-03 14:49:18
举报

作者:蒋鹏

问题结论

由于web接入层在调用后方逻辑层接口,使用的调用方法concurrent_curl没有设置超时(默认200s),会由于后台单点故障,导致调用没返回而一直等待,引发雪崩,使web接入层的php也被占满未释放空闲,导致所有cdb的web控制台服务都不可访问。

问题场景

近日,测试同学 R 反馈整个测试环境,CDB的相关页面都不能访问了,实在找不到问题原因。表现如下:

1、三套cdb的测试环境都拉取不出页面,页面一直弹登录框,登录态校验失败。

2、做账户的登录态、用户信息校验等,校验接口大概率超时。

3、浏览器抓包,发现许多cgi请求一直处于pending状态。

问题分析过程

1、3套环境都这样,首先考虑是机器底层网络有问题?

-----通过与其他FT的测试环境运行情况,发现就只有CDB的环境这样,排除一种可能。

2、页面一直弹登录框,首先需要定位登录校验失败问题,难道是官网组件运行异常?

-----同样查看其他ft的环境,是否有登录的问题存在,发现不存在问题。那么排查CDB的环境是否连接鉴权的地址不正确?环境不通?

首先解决鉴权失败问题:

代码语言:javascript
复制
[2017-07-26 09:37:37,139][21563][ERROR][/data/release/websites/cdb.qcloud.com/module/helpers/common_helper.php:http_curl:162][curl_e
xec error|url=http://cgateway.qcloud.itd.com/interfaces/interface.php|request='{"regionId":"1","version":1,"componentName":"MC_CDB",
"eventId":1570119608,"seqId":"205b990c-4755-5fc4-5f9b-5977f2a2b680","spanId":"http:\\/\\/cdb.qcloud.com\\/cdb->http:\\/\\/cdb.qcloud
.com\\/cdb\\/getlist;1","interface":{"interfaceName":"qcloud.Qconfig.batchGetWhiteList","para":{"typeList":["CDB_CAM_USER_LIST"],"wh
iteList":["3227991405"]},"common":{"regionId":"1","appId":0,"uin":0,"ownerUin":0}}}'|timeout=6|error=Operation timed out after 6000
milliseconds with 0 bytes received]

*通过日志发现,鉴权相关接口出现超时, timeout=6|error=Operation timed out after 6000milliseconds with 0 bytes received

提取请求单独curl测试,发现请求一直不返回,那么我们往后端继续定位,发现被请求组件cgw的日志展示,鉴权的接口是正常处理,没有失败的情况。

mc:我发起请求正常 ——————————cgw:我处理请求也是正常,内部没有超时

这时候,问题的关键点就在mc到cgw之间了,他们直接的距离就是nginx+php,由于经验nginx的转发能力是很强大的,这里考虑php慢,结合定位cgw的日志,cgw逻辑耗时正常,这里考虑php的进程占用满了。

1、看php进程数量

2、查看/usr/local/services/php-fpm-5.6.30/etc/php-fpm.conf中max_children

3、该问题场景,两者数量相等,于是考虑php的进程占满。

尝试解决php问题,重启下php,刷新页面,出现下面情况:

页面可以正常刷新出来,多次刷新后,又陷入了大量超时失败,浏览器请求pending。

判断php重启不是根本办法,要定位出具体的是什么导致了线程急速耗费完。

于是我就去看ngnix 的请求处理日志了(要看nginx所有的请求日志):

代码语言:javascript
复制
 /usr/local/services/tnginx_1_0_0-1.0/log]# tail -f * -n 0

通过tail发现打印内容很久才会有一条,这里我们要知道一点:

nginx是在php处理返回后,返回内容给请求端时候才会打印请求的日志。

于是修改nginx的日志打印规则,看看请求具体耗用时间,设置规则参考nginx日志规则配置。通过在access_log中查询‘request_time 2’、‘request_time 1’等看看超过1s的请求处理。得到了如下的情况:

有请求耗时达到了200s,浏览器的请求也在200s后返回,这里需要从代码角度考虑,有哪些场景可能导致耗时很长:

1、代码中可能存在大的循环。

2、代码中出现阻塞,一直等待。

通过在代码中打桩,插入return语句,发现在如下的concurrent_curl函数前后打桩,浏览器分别会正常返回或者一直pending,所以考虑是这个函数的问题。

通过代码调用实现中,没有看到关于time_out的设置,而使用了默认的超时时间,并与研发对齐,的确是没有超时设置。初步定位到由于这里没有超时,而有一些php逻辑一直在等待后台返回,导致了web接入层机器的php进程耗用完。

这里又有问题了,什么情况导致concurrent_curl一直等待未返回,用同样上面方法了解,有一台逻辑层cgw组件机器,php也耗用满了,导致web接入层请求逻辑层cgw一直waiting,nginx没有返回。这样由于一台机器的问题,而影响到web接入层,从而扩散CDB控制台所有用户都不能使用。

补充问题1:nginx为何没有返回?

代码语言:javascript
复制
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SERVER_NAME $http_host;
fastcgi_ignore_client_abort on;
fastcgi_connect_timeout 600s;
fastcgi_send_timeout 600s;
fastcgi_read_timeout 600s;
}

nginx配置代理转发,cgi超时时间是10分钟,大于我们concurrent_curl的200s而没有出错。

补充问题2:在定位过程中,多次点击列表拉取按钮,每次会触发两个cgi访问,其中一个会pending,当点击到第六次后,两个cgi都会pending,场景必现。

代码语言:javascript
复制
第一次刷新
request A   返回200
request B   pengding
第二次刷新
request A   返回200
request B   pengding
第三次刷新
request A   返回200
request B   pengding
第四次刷新
request A   返回200
request B   pengding
第五次刷新
request A   返回200
request B   pengding
第六次刷新
request A   pengding
request B   pengding

这个主要是浏览器本身限制了单域名的连接个数,定位环境使用chrome,限制个数为6个连接。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题结论
  • 问题场景
    • 问题分析过程
    相关产品与服务
    云数据库 SQL Server
    腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
    http://www.vxiaotou.com