首页 > PHP编程 > PHP函数sem_get引起的“No space lelf on device”问题解决记录

PHP函数sem_get引起的“No space lelf on device”问题解决记录

2017年1月20日

PHP函数sem_get引起的“No space lelf on device”问题解决记录

http://hansionxu.blog.163.com/blog/static/2416981092015914533184/

1. 问题表现:

接收到告警,部分接口异常。

2. 问题追查:

首先,机器日志中忽然出现很多的flow_lock Faild to create semaphore的错误。

追查系统中的代码实现后,发现是sem_get函数引起,该函数用于根据一个key值来获取一个系统System V信号量的引用。

代码位置:

PHP函数sem_get引起的“No space lelf on device”问题解决记录 - 徐汉彬Hansion - 技术行者

我单独在指定机器上执行上述语句,发现了Warning信息:No space lelf on device,原本以为是磁盘或者内存的空间不足,实际检查后才发现是信号量被耗尽了。

PHP函数sem_get引起的“No space lelf on device”问题解决记录 - 徐汉彬Hansion - 技术行者

信号量是一种有限资源,通过Linux命令,查看系统信号量的限制数目是1024个。

PHP函数sem_get引起的“No space lelf on device”问题解决记录 - 徐汉彬Hansion - 技术行者

 

Web机器实际已经使用掉的信号量数目已经达到1024个,也就是说,可用的信号量已经被用完了。原因,已经比较明显了,就是信号量被申请使用之后,没有被释放。

PHP函数sem_get引起的“No space lelf on device”问题解决记录 - 徐汉彬Hansion - 技术行者

于是我们追查代码源头,发现确实如此,这里的sem_release是类似解锁的意思,并非释放这个信号量,真正释放的函数是sem_remove

PHP函数sem_get引起的“No space lelf on device”问题解决记录 - 徐汉彬Hansion - 技术行者

sem_release的官方文档说明:

PHP函数sem_get引起的“No space lelf on device”问题解决记录 - 徐汉彬Hansion - 技术行者

至此,找到问题所在。这个问题潜伏了很久,系统经常很长时间,累计申请了信号量而没有释放,慢慢达到1024个,最终触发该问题。

 

3. 问题解决方式:

1)使用root权限手动释放信号量,如果有多台机器,每一台都要执行。

for semid in `ipcs -s | cut -f2 -d””`; do ipcrm -s $semid; done

2)重启Apache服务,之后,信号量的使用情况,恢复到正常的数目。

PHP函数sem_get引起的“No space lelf on device”问题解决记录 - 徐汉彬Hansion - 技术行者

关键代码位置:

PHP函数sem_get引起的“No space lelf on device”问题解决记录 - 徐汉彬Hansion - 技术行者

函数ams_sem_remove会执行sem_remove的释放操作。

 

4. 问题小结:

Sem_get系列函数,通过信号量来达到类似Linux的互斥量(mutex)锁的效果,对一个内存共享对象加锁和解锁的方式,来控制并发请求数量(类似线程安全)。出问题的原因,是长期运行下,申请占用了很多个信号量,并且缺少sem_remove的释放操作。

PHP函数sem_get引起的“No space lelf on device”问题解决记录 - 徐汉彬Hansion - 技术行者
分类: PHP编程 标签:
本文的评论功能被关闭了.