PHP中连续调用SMS发送API时第二条短信无法发送的排查
连续调用sendSMS函数失败但链式调用成功的原因分析
核心现象
- 单次调用
sendSMS()可正常发送短信 - 无返回值的连续两次调用仅第一条成功,第二条失败
- 为函数添加
true/false返回值后,通过if链式串行调用(等待第一条成功后再发第二条),两条均可正常发送
可能的原因及排查方向
1. 隐性并发请求限制
尽管API提供商声称无限制,但多数服务会对同一IP的并发请求频率做隐性限流。连续调用时两个请求几乎同时发起,可能触发了该限制;而链式调用是串行执行,请求间有自然的时间间隔,避开了限流规则。
- 排查验证:在两次连续调用之间添加
sleep(1),若第二条能成功发送,即可确认是并发频率问题。
2. Curl资源竞争或网络栈阻塞
短时间内连续创建curl会话发起请求,服务器的网络栈或curl扩展可能出现资源竞争(如套接字端口不足、连接未及时释放)。链式调用会等待第一个请求完成并释放资源后再发起第二个,避免了资源冲突。
- 排查验证:在函数中添加curl错误日志,查看第二次调用的具体错误信息:
$result = curl_exec($c); if(curl_errno($c)){ error_log('Curl Error (sendSMS): ' . curl_error($c) . ' | Errno: ' . curl_errno($c)); } curl_close($c);
3. 脚本执行时序问题
原始函数无返回值,PHP解释器可能在第一个curl请求尚未完成(仍在等待响应)时,就开始执行第二个调用,导致网络请求堆积。添加返回值后,链式调用会等待第一个curl_exec()完全执行并返回结果,保证了请求的串行执行顺序。
4. 辅助函数的副作用
检查getCleanPhone()函数是否依赖静态变量或修改了全局变量。若该函数在第一次调用后未重置内部状态,可能导致第二次调用返回无效的号码格式,触发函数开头的exit()逻辑。
- 排查验证:在两次调用前分别打印
getCleanPhone($number)的结果,确认两次输出的号码格式均有效。
临时解决方案
若确认是并发或时序问题,可将连续调用改为串行执行(如链式调用的方式),或在调用间添加短暂延迟,保证请求依次完成。
内容的提问来源于stack exchange,提问作者Sherwin Flight
相关产品推荐
相关产品推荐

