You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP 8.2中哪些内置函数会意外创建Unix Socket对?

PHP CLI进程Unix Socket泄漏排查

我们在Kubernetes上运行的多个PHP Pod中,有两个出现了Unix Socket泄漏问题。PHP CLI进程持续打开Unix Socket却不关闭,最终在无关代码处触发PHP崩溃,报错:

PHP Warning: stream_select(): You MUST recompile PHP with a larger value of FD_SETSIZE.

其他Pod也会打开少量Unix Socket,但数量极少,不构成问题。

令人困惑的是,我们并未主动使用Unix Socket,所有进程间通信均通过TCP/IP完成。这些泄漏的Socket具备以下特征:

  • 处于ESTABLISHED状态
  • ss -x显示这些Socket未发送或接收任何数据
  • 文件系统中无对应文件
  • netstat显示它们的RefCount均为3
  • ss -xp显示每个Socket的两端均由同一个PHP进程持有

代码中未调用stream_socket_pair或socket_create_pair函数,推测这些Socket是调用其他PHP内置函数时的副作用产生的。CURL是主要怀疑对象,但其他Pod也大量使用CURL却无此问题,且暂时未发现这两个Pod的特殊操作。

疑问:哪些PHP内置函数(含默认捆绑扩展中的函数)会意外创建Unix Socket对?

补充:ss -xp输出

# ss -xp
Netid               State               Recv-Q               Send-Q                             Local Address:Port                                  Peer Address:Port                   Process
u_str               ESTAB               0                    0                                              * 481304571                                        * 481304572               users:(("php",pid=7,fd=494))
u_str               ESTAB               0                    0                                              * 480934363                                        * 480934362               users:(("php",pid=7,fd=289))
u_str               ESTAB               0                    0                                              * 480899260                                        * 480899259               users:(("php",pid=7,fd=255))
u_str               ESTAB               0                    0                                              * 480853228                                        * 480853229               users:(("php",pid=7,fd=207))
u_str               ESTAB               0                    0                                              * 478659551                                        * 478659550               users:(("php",pid=7,fd=82))
u_str               ESTAB               0                    0                                              * 481263776                                        * 481263775               users:(("php",pid=7,fd=484))
u_str               ESTAB               0                    0                                              * 481014545                                        * 481014546               users:(("php",pid=7,fd=339))
u_str               ESTAB               0                    0                                              * 480847844                                        * 480847845               users:(("php",pid=7,fd=221))
u_str               ESTAB               0                    0                                              * 479446282                                        * 479446283               users:(("php",pid=7,fd=185))
u_str               ESTAB               0                    0                                              * 479430966                                        * 479430965               users:(("php",pid=7,fd=162))
u_str               ESTAB               0                    0                                              * 481391710                                        * 481391711               users:(("php",pid=7,fd=515))
u_str               ESTAB               0                    0                                              * 481013994                                        * 481013995               users:(("php",pid=7,fd=352))
u_str               ESTAB               0                    0                                              * 480884372                                        * 480884373               users:(("php",pid=7,fd=233))
.... many, many more lines ...

可能的PHP内置函数及分析

以下是可能在内部创建Unix Socket对的PHP内置函数/扩展,结合你的场景逐一分析:

1. CURL扩展相关操作

虽然其他Pod也使用CURL,但特定场景下仍可能触发内部Socket创建:

  • 若CURL启用CURLOPT_PROXY且存在配置错误(比如误设为Unix Socket类型代理),或PHP/CURL版本存在bug,可能意外创建Unix Socket对
  • 第三方库、配置文件或环境变量可能间接设置CURLOPT_UNIX_SOCKET_PATH参数,导致Socket创建
  • 长运行CLI进程中,部分PHP版本的CURL扩展在连接池管理、超时回调逻辑中存在Socket未正确回收的bug

2. 进程控制(pcntl)扩展

如果代码使用pcntl_fork()等函数,PHP内部可能通过Unix Socket对实现父子进程间通信(如信号同步、状态传递)。若子进程退出时未正确关闭Socket,会导致父进程残留Socket描述符。

3. 外部命令执行函数

  • proc_open():未显式指定管道类型时,PHP可能默认创建Unix Socket对作为进程间通信管道,若未调用proc_close()关闭资源,会造成泄漏
  • exec()/shell_exec():部分PHP版本处理标准IO重定向时,内部可能创建临时Unix Socket对,回收逻辑bug会导致泄漏

4. 流处理函数

  • popen():内部可能创建Unix Socket对作为管道,未通过pclose()关闭会引发泄漏
  • stream_select()本身不创建Socket,但未关闭的泄漏Socket会加剧文件描述符耗尽问题

5. 其他默认扩展

  • posix扩展:部分进程间通信相关函数可能回退使用Unix Socket
  • sysvmsg/sysvsem等IPC扩展:部分实现会以Unix Socket作为 fallback 机制

额外排查建议

  1. 对比异常Pod与正常Pod的PHP版本、扩展版本(重点CURL、pcntl),定位版本差异引发的bug
  2. 启用zend.detect_leaks配置,结合valgrind跟踪文件描述符变化,定位具体触发函数
  3. 检查异常Pod的环境变量、php.ini等配置文件,确认是否存在与正常Pod不同的Socket/代理相关配置

内容的提问来源于stack exchange,提问作者Vilx-

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 07:27:49