11月21日mcq队列code47问题排查

背景

总是一段时间transfer就无法写入队列,报47错误。根据google得到的消息,47代表服务器临时不可用,于是一直怀疑是队列的锅。

今天再次出现47问题时,尝试用telnet访问队列,发现无法建立连接,报错,随即找运维,运维看了后表示端口不够用了,开了更大范围的端口使用。到此47错误暂时消失,不过为什么端口会不用用?在机器上使用netstat -nat|grep ESTABLISH|wc -l ,不看不知道,建立的连接有10多W…我靠,接着通过lsof -Pni|awk ‘{print $2}’|sort|uniq -c 找出占用最多的进程id,发现居然是最新上线的监控脚本,脚本中使用了内部编写的mc扩展,大致逻辑如下

1
2
3
4
5
6
7
8
9
10
while(true){
if($data = readQueue()){
...
}
}
func readQueue($key){
$mc = new Mc();
return $mc->get($key);
}

每次new新的mc对象都会建立一个连接,最终导致连接过多

ps:另外尝试使用官方扩展在循环中new对象,发现会复用之前的连接,不会建立多个连接。