调用Google Drive API获取大页数文档时遭遇503错误求助
Google Docs API 获取大文档时触发503连接拒绝错误
环境配置
- PHP 8.1.27
- Symfony 6.4.*
- Ubuntu 22.04.3 LTS
- Google API Client 2.15.3
问题描述
获取300-400页的文档时一切正常,但获取950-1000页、大小仅550-600KB的文档时,始终触发503错误,错误提示为Connection refused for URI https://docs.googleapis.com/v1/documents/xxx。删除部分页面后可正常调用,但业务需要完整文档,该方案不可行。
相关代码
try { $service = new Docs($client); $doc = $service ->documents ->get($file->id); $drive = new Drive($client); $fileDetails = $drive->files->get($doc->getDocumentId(), ["fields" => "createdTime,modifiedTime"]); } catch (\Throwable $t) { error_log($t->getCode(), 0); error_log($t->getMessage(), 0); error_log($t->getTraceAsString(), 0); }
错误栈
Connection refused for URI https://docs.googleapis.com/v1/documents/1SDq_m48Ctg*********** #0 /var/www/*****.com/vendor/google/auth/src/Middleware/AuthTokenMiddleware.php(117): GuzzleHttp\Handler\StreamHandler->__invoke() #1 /var/www/*****.com/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php(35): Google\Auth\Middleware\AuthTokenMiddleware->Google\Auth\Middleware\{closure}() #2 /var/www/*****.com/vendor/guzzlehttp/guzzle/src/Middleware.php(31): GuzzleHttp\PrepareBodyMiddleware->__invoke() #3 /var/www/*****.com/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php(71): GuzzleHttp\Middleware::GuzzleHttp\{closure}() #4 /var/www/*****.com/vendor/guzzlehttp/guzzle/src/Middleware.php(63): GuzzleHttp\RedirectMiddleware->__invoke() #5 /var/www/*****.com/vendor/guzzlehttp/guzzle/src/HandlerStack.php(75): GuzzleHttp\Middleware::GuzzleHttp\{closure}() #6 /var/www/*****.com/vendor/guzzlehttp/guzzle/src/Client.php(333): GuzzleHttp\HandlerStack->__invoke() #7 /var/www/*****.com/vendor/guzzlehttp/guzzle/src/Client.php(107): GuzzleHttp\Client->transfer() #8 /var/www/*****.com/vendor/guzzlehttp/guzzle/src/Client.php(124): GuzzleHttp\Client->sendAsync() #9 /var/www/*****.com/vendor/google/auth/src/HttpHandler/Guzzle6HttpHandler.php(47): GuzzleHttp\Client->send() #10 /var/www/*****.com/vendor/google/apiclient/src/Http/REST.php(84): Google\Auth\HttpHandler\Guzzle6HttpHandler->__invoke() #11 [internal function]: Google\Http\REST::doExecute() #12 /var/www/*****.com/vendor/google/apiclient/src/Task/Runner.php(187): call_user_func_array() #13 /var/www/*****.com/vendor/google/apiclient/src/Http/REST.php(66): Google\Task\Runner->run() #14 /var/www/*****.com/vendor/google/apiclient/src/Client.php(926): Google\Http\REST::execute() #15 /var/www/*****.com/vendor/google/apiclient/src/Service/Resource.php(238): Google\Client->execute() #16 /var/www/*****.com/vendor/google/apiclient-services/src/Docs/Resource/Documents.php(91): Google\Service\Resource->call() #17 /var/www/*****.com/src/Service/Google/DocsApiService.php(59): Google\Service\Docs\Resource\Documents->get() #18 /var/www/*****.com/src/Command/GranularAudience/ImportDocsCommand.php(83): App\Service\Google\DocsApiService->getLinkedCustomListStructure() #19 /var/www/*****.com/vendor/symfony/console/Command/Command.php(326): App\Command\GranularAudience\ImportDocsCommand->execute() #20 /var/www/*****.com/vendor/symfony/console/Application.php(1096): Symfony\Component\Console\Command\Command->run() #21 /var/www/*****.com/vendor/symfony/framework-bundle/Console/Application.php(126): Symfony\Component\Console\Application->doRunCommand() #22 /var/www/*****.com/vendor/symfony/console/Application.php(324): Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand() #23 /var/www/*****.com/vendor/symfony/framework-bundle/Console/Application.php(80): Symfony\Component\Console\Application->doRun() #24 /var/www/*****.com/vendor/symfony/console/Application.php(175): Symfony\Bundle\FrameworkBundle\Console\Application->doRun() #25 /var/www/*****.com/vendor/symfony/runtime/Runner/Symfony/ConsoleApplicationRunner.php(49): Symfony\Component\Console\Application->run() #26 /var/www/*****.com/vendor/autoload_runtime.php(29): Symfony\Component\Runtime\Runner\Symfony\ConsoleApplicationRunner->run() #27 /var/www/*****.com/bin/console(11): require_once('...') #28 {main}
解决办法
1. 启用请求重试机制
针对503错误和连接异常添加重试逻辑,避免单次请求失败导致任务中断:
use GuzzleHttp\Middleware; // 初始化Google Client后,获取并修改handler stack $handlerStack = $client->getHttpClient()->getConfig('handler'); $handlerStack->push(Middleware::retry(function ($retries, $request, $response, $exception) { // 最多重试3次,仅针对连接错误和503状态码 if ($retries < 3 && ($exception instanceof \GuzzleHttp\Exception\ConnectException || ($response && $response->getStatusCode() === 503))) { return true; } return false; }));
2. 分批次获取文档内容
利用fields参数拆分请求,先获取文档元数据,再按需拉取内容,减少单次请求的数据量:
// 先获取文档基本信息和内容索引 $docMeta = $service->documents->get($file->id, ['fields' => 'documentId,title,body.content(startIndex,endIndex)']); // 再获取完整内容和时间信息 $fullDoc = $service->documents->get($file->id, ['fields' => 'body.content,createdTime,modifiedTime']);
3. 调整请求超时时间
大文档处理需要更长时间,增加Guzzle的超时配置:
$client->setHttpClient(new \GuzzleHttp\Client([ 'timeout' => 60, // 整体请求超时60秒 'connect_timeout' => 10 // 连接超时10秒 ]));
4. 导出为其他格式解析
如果不需要Docs API的结构化数据,可通过Drive API将文档导出为HTML或纯文本,再解析内容:
// 导出为HTML格式 $response = $drive->files->export($file->id, 'text/html', ['alt' => 'media']); $htmlContent = $response->getBody()->getContents(); // 后续解析HTML获取所需内容
5. 检查API配额
登录Google Cloud控制台,确认Docs API的请求配额是否充足,若达到限制可申请配额提升。
内容的提问来源于stack exchange,提问作者R1k3r
相关产品推荐
相关产品推荐

