PHP不使用curl_multi并发调用Google翻译v3库的技术咨询
PHP并发调用Google翻译v3的简便实现方案
一、parallel扩展状态说明
parallel扩展目前仍在维护(截至2024年),支持线程、进程两种模式,属于PHP原生级别的并发方案,不用依赖复杂的大型库,学习成本低。
二、两种简便并发实现方案
1. 调整amphp的并发数解决超时
你之前用amphp的parallelMap出现进程创建超时,核心原因就是默认并发数太高。直接给parallelMap加个并发数参数限制就行,比如设5-10:
use Amp\Parallel\Functions\parallelMap; $targetLanguages = ['fr', 'de', 'es', 'ja']; // 目标语言列表 $textToTranslate = 'Hello world'; // 限制最大并发数为5 $results = parallelMap($targetLanguages, function ($lang) use ($textToTranslate) { // 直接调用Google翻译v3的translateText接口 $client = new Google\Cloud\Translate\V3\TranslationServiceClient(); $response = $client->translateText( [$textToTranslate], $lang, 'projects/your-project-id/locations/global' ); return [$lang => $response->getTranslations()[0]->getTranslatedText()]; }, 5);
改完这个参数基本就能解决超时问题,不用深入研究amphp的其他功能。
2. 用parallel扩展的工作池实现轻量化并发
parallel的工作池可以直接控制线程/进程数量,代码更简洁:
use parallel\Runtime; use parallel\Channel; $targetLanguages = ['fr', 'de', 'es', 'ja']; $textToTranslate = 'Hello world'; $maxWorkers = 5; // 最大并发数 $channel = new Channel(); $runtimes = []; foreach ($targetLanguages as $lang) { // 想用线程的话,把Runtime换成parallel\Thread,内存占用更低 $runtime = new Runtime(); $runtime->run(function ($lang, $text, $channel) { $client = new Google\Cloud\Translate\V3\TranslationServiceClient(); $response = $client->translateText( [$text], $lang, 'projects/your-project-id/locations/global' ); $channel->send([$lang => $response->getTranslations()[0]->getTranslatedText()]); }, [$lang, $textToTranslate, $channel]); $runtimes[] = $runtime; // 达到并发上限时,等待一个任务完成再创建新的 if (count($runtimes) >= $maxWorkers) { foreach ($runtimes as $i => $runtime) { $runtime->join(); unset($runtimes[$i]); } } } // 等待剩余任务结束 foreach ($runtimes as $runtime) { $runtime->join(); } // 收集翻译结果 $results = []; while (!$channel->isEmpty()) { $results = array_merge($results, $channel->recv()); } $channel->close();
线程模式比进程模式内存占用低,适合内存紧张的环境。
三、你的问题解答
1. 是否通常用工作池+限制最大并发数?
对,这是PHP处理并发网络请求的常规操作。不管是进程池还是线程池,限制最大并发数既能提升效率,又能避免系统资源耗尽(比如进程过多导致的超时、内存溢出)。
2. 时间紧迫时是否可以随意选非最优并发数?
完全可以。经验上,并发数设5-20之间(看服务器配置)都能正常跑,不用纠结精确的最优值。比如先设10,没问题就不用调;要是还是超时或内存高,再降到5就行。
3. 是否能根据可用内存动态设置并发数?
理论上可以,比如用memory_get_usage()或系统命令获取内存状态,但实际意义不大——内存状态实时变,而且Google翻译客户端的内存波动也不好预估,反而会增加代码复杂度,不如直接设个保守的固定值。
4. 是否需要分析单个进程/线程的内存占用?
如果是长期运行的服务,有必要用memory_get_peak_usage()分析单个任务的内存峰值,再结合总内存算合理的并发数;但如果只是学习或临时脚本,经验估算就够了,比如服务器1G内存的话,设5-10个并发基本不会出问题。
内容的提问来源于stack exchange,提问作者Kevin Wheeler
相关产品推荐
相关产品推荐

