Azure DevOps Server中downloadbuildartifacts@0下载过慢或失败问题求助
Azure DevOps Server构件下载过慢/超时问题求助
背景
我们正在使用Azure DevOps Server,遇到了构件下载过慢或60分钟超时的问题。
在DeploymentJob中添加downloadbuildartifacts@0任务时,即便构件大小仅为200KB也会出现该问题。
服务器性能表现
- Server A、B、C三台服务器下载同一构件分别耗时4分钟、6分钟,其中Server C出现60分钟超时。
- 三台服务器均配置了
NETWORK SERVICE账户。
已尝试的解决方法(均无效)
- 尝试使用
downloadbuildartifacts@1任务,但无法找到该任务。 - 尝试
downloadpipelineartifact@2任务,但该任务不适用于Azure DevOps Server。 - 通过浏览器使用API链接手动下载,速度正常(耗时不到2秒),排除网络问题。
手动下载的API链接:
http://{{server}}/DefaultCollection/_apis/resources/Containers/{{BuildID}}?itemPath={{ArtifactName}}&isShallow=true&api-version=4.1-preview.4
临时解决方案
1. 使用PowerShell自定义下载任务
我们采用PowerShell编写了自定义下载任务,耗时约40秒。
steps: - powershell: | function Get-ContentRecursively { param ( [string]$Url, [hashtable]$Headers, [string]$FilenameFilterPattern ) try { if ( $null -eq ($AccessUrl | Where-Object { $_ -eq $Url })){ $content = Invoke-WebRequest -Uri $Url -Headers $Headers -UseBasicParsing -TimeoutSec 60 Write-Host "[$($content.StatusCode)] $($content.StatusDescription) - Accessed $Url" $global:accessUrl += $Url } else { return } } catch { Write-Host "Error accessing ${Url}: $_" return } try { $json = $content.Content | ConvertFrom-Json } catch { Write-Host "Failed to parse JSON from $Url" return } foreach ($item in $json.value) { if ($item.itemType -eq "folder") { Get-ContentRecursively -Url $item.contentLocation -Headers $Headers -FilenameFilterPattern $FilenameFilterPattern } elseif ($item.itemType -eq "file") { $file = $global:files | Where-Object { $_.path -eq $item.path } # add if file not exists if( $file -eq $null ){ $global:files += $item Write-Host "Add $($item.path) to FileList" } } } } function Download-File { param ( [object]$File, [hashtable]$Headers, [string]$OutFilePath, [int]$RetryCount = 4 ) $retryAttempts = 0 do { try { $tempPath = Join-Path $OutFilePath $File.path $directory = Split-Path $tempPath if (-not (Test-Path $directory)) { New-Item -ItemType Directory -Force -Path $directory > $null } $response = Invoke-WebRequest -Uri $File.contentLocation -Headers $headers -UseBasicParsing -OutFile $tempPath -TimeoutSec 60 -PassThru Write-Host "[$($response.StatusCode)] $($response.StatusDescription) - Downloaded $($File.contentLocation)" Write-Host "Downloaded $($File.contentLocation) to $tempPath" return } catch { $retryAttempts++ Write-Host "[$($response.StatusCode)] $($response.StatusDescription) - Downloaded $($File.contentLocation)" Write-Host "Attempt $retryAttempts of $RetryCount for $Url failed. Error: $_" Start-Sleep -Seconds (2 * $retryAttempts) } } while ($retryAttempts -lt $RetryCount) Write-Host "Failed to download: $($File.contentLocation) after $RetryCount retries." $global:failDownload += $File.contentLocation } # Main logic $token = "$(System.AccessToken)" $organization = "$(System.TeamFoundationCollectionUri)" $project = "$(System.TeamProject)" $headers = @{Authorization = "Bearer $token"} $initialUrl = $env:SYSTEM_TASKDEFINITIONSURI + '/_apis/resources/Containers/' + $env:BUILD_CONTAINERID $outFilePath = $env:SYSTEM_ARTIFACTSDIRECTORY $filenameFilterPattern = "*" # Example pattern $global:files = @() $global:failDownload = @() $global:accessUrl = @() Get-ContentRecursively -Url $initialUrl -Headers $headers -FilenameFilterPattern $filenameFilterPattern Write-Host "Prepare to download" foreach ($file in $global:files) { Download-File -File $file -Headers $headers -OutFilePath $outFilePath } if ( $global:failDownload.Length -ne 0 ){ exit 1 } displayName: myDownloadTask
2. 使用经典发布流水线下载
通过经典发布流水线下载耗时仅5秒,但无法使用YAML进行部署。
寻求解决方案
请问是否有人遇到过类似问题并找到了解决方案?
内容的提问来源于stack exchange,提问作者littletree71
相关产品推荐
相关产品推荐

