PHP cURL调用WhatsApp API致Apache CPU占用持续飙升求助
解决PHP cURL对接WhatsApp API导致Apache CPU持续升高的问题
以下是针对你的环境(WampServer 3.3.2、Apache 2.4.58、PHP 8.3.0、Windows 10 Pro 22H2)的具体解决步骤:
1. 确保cURL资源被强制释放
你的代码虽调用了curl_close,但脚本执行中若出现未捕获异常,可能导致资源无法正常释放。用try-finally包裹cURL操作,确保资源一定会被关闭:
$curl = curl_init(); try { curl_setopt($curl, CURLOPT_URL, "https://graph.facebook.com/v19.0/<PHONE_NUMBER_ID>/messages"); curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode([ 'messaging_product' => 'whatsapp', 'to' => '<PHONE_NUMBER_TO_SEND>', 'type' => 'template', 'template' => [ 'name' => 'hello_world', 'language' => [ 'code' => 'en_US', ], ], ])); curl_setopt($curl, CURLOPT_HTTPHEADER, [ "Authorization: Bearer <TOKEN>", 'Content-Type: application/json', ]); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // 后续会替换掉这个不安全的设置 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); $response = curl_exec($curl); var_dump($response); } finally { curl_close($curl); // 额外重置cURL资源(针对PHP 8.x的潜在泄漏问题) unset($curl); }
2. 修复SSL验证配置,避免资源泄漏
禁用CURLOPT_SSL_VERIFYPEER可能触发SSL底层的资源泄漏,建议配置合法的CA证书:
- 下载最新的CA证书包(如curl官方的
cacert.pem),放在Wamp的bin/php/php8.3.0/extras/ssl/目录下 - 修改php.ini,添加或调整:
curl.cainfo = "D:/wamp64/bin/php/php8.3.0/extras/ssl/cacert.pem"(路径根据你的Wamp安装目录调整) - 代码中替换SSL验证设置:
// 替换之前的CURLOPT_SSL_VERIFYPEER设置 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($curl, CURLOPT_CAINFO, "D:/wamp64/bin/php/php8.3.0/extras/ssl/cacert.pem");
3. 调整Apache MPM参数,强制进程回收
Windows下Apache默认使用winnt MPM,设置MaxRequestsPerChild参数让进程处理一定请求后自动重启,避免资源累积:
- 打开Wamp的Apache配置文件
httpd.conf - 找到
<IfModule mpm_winnt_module>区块,添加或修改:
<IfModule mpm_winnt_module> ThreadsPerChild 150 MaxRequestsPerChild 1000 # 处理1000个请求后重启子进程 ListenBacklog 511 </IfModule>
- 重启Apache生效
4. 排查PHP cURL扩展兼容性
Wamp自带的PHP 8.3.0的cURL扩展可能存在版本兼容问题:
- 查看当前cURL版本:执行
php -i | findstr curl,检查cURL Information的版本 - 如果版本较低,尝试下载适配PHP 8.3的x64版本cURL扩展,替换
bin/php/php8.3.0/ext/php_curl.dll - 替换后重启Apache
5. 监控脚本资源占用
添加代码监控每次执行的内存和CPU使用,定位是否是脚本本身的问题:
// 脚本开头记录初始资源 $initialMemory = memory_get_usage(true); $initialCpu = getrusage(); // ... 你的cURL代码 ... // 脚本结尾输出资源变化 $finalMemory = memory_get_usage(true); $finalCpu = getrusage(); echo "内存变化:" . ($finalMemory - $initialMemory) . "字节\n"; echo "CPU用户时间:" . ($finalCpu['ru_utime.tv_sec'] - $initialCpu['ru_utime.tv_sec']) . "秒\n";
如果每次执行后内存/CPU持续增长,说明存在资源泄漏,需进一步排查扩展问题。
6. 替换HTTP客户端测试
如果上述方法无效,尝试用GuzzleHTTP替代原生cURL:
- 通过Composer安装Guzzle:
composer require guzzlehttp/guzzle - 替换为以下代码:
require 'vendor/autoload.php'; $client = new GuzzleHttp\Client(); try { $response = $client->post('https://graph.facebook.com/v19.0/<PHONE_NUMBER_ID>/messages', [ 'headers' => [ 'Authorization' => 'Bearer <TOKEN>', 'Content-Type' => 'application/json', ], 'json' => [ 'messaging_product' => 'whatsapp', 'to' => '<PHONE_NUMBER_TO_SEND>', 'type' => 'template', 'template' => [ 'name' => 'hello_world', 'language' => ['code' => 'en_US'], ], ], ]); var_dump($response->getBody()->getContents()); } catch (Exception $e) { var_dump($e->getMessage()); }
内容的提问来源于stack exchange,提问作者prueba prueba
相关产品推荐
相关产品推荐

