发布管理vNext组件部署瓶颈

时间:2015-11-11 19:52:34

标签: powershell powershell-remoting ms-release-management

我们将版本管理2015与vNext版本模板结合使用。我们为应用程序的每个部分都提供了基于Powershell DSC的组件部署,事实上,我们正在部署两个不同的应用程序,这些应用程序处于活动开发状态,并且通常几乎同时部署。

我们经常在部署期间收到以下错误:

  

OperationFailedException:由于正在进行另一个部署,因此不允许进行新部署。有一段时间后重试部署。

完整堆栈跟踪显示错误不是来自Powershell本身,而是来自负责在目标计算机上执行powershell脚本的发布管理系统:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> Microsoft.TeamFoundation.Release.Common.Helpers.OperationFailedException: New deployment is not allowed as an another deployment is in progress. Retry the deployment after sometime.
   at Microsoft.TeamFoundation.Release.EnvironmentProvider.OnPrem.Implementation.OnPremDeploymentProvider.ReadDeploymentResponse(DeploymentResponse response)
   at Microsoft.TeamFoundation.Release.EnvironmentProvider.OnPrem.Implementation.OnPremDeploymentProvider.RunScript(String scriptPath, String configurationPath, MachineSpecification machine, StorageSpecification storage, Dictionary`2 configurationVariables)
   at Microsoft.TeamFoundation.Release.MonitorServices.Dsc.OnPrem.OnPremDeploymentActions.InvokePlatform(String activityId, MachineSpecification machineSpecification, StorageSpecification storageSpecification, String scriptPath, String configurationPath, Dictionary`2 configurationVariables)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.TeamFoundation.Release.DeploymentAgent.Services.Deployer.Dsc.DscComponentInstaller.InvokeMethodByReflection(String methodArguments)

上述错误导致整个部署失败,我们被迫重试阶段或整个部署以完成部署。

有两种情况导致这种情况:

  1. 两个版本模板同时在同一目标服务器上执行其PowerShell脚本
  2. 单个版本模板具有并行控制流,其中包含两个不同的组件,这两个组件都在同一目标服务器上执行脚本
  3. 换句话说,Release Management用于在远程服务器上执行powershell脚本的机制似乎只能一次执行一个脚本,并且无法等待/保持其他人完成。

    如果有问题的脚本主动修改它正在执行的服务器,那么这种类型/ sorta是有意义的,但在我们的例子中,服务器基本上是一个运行脚本的暂存区域。 "真实"脚本的目标与PowerShell碰巧正在执行的服务器无关。

    除了拥有每个服务器同时部署的组件(哇)之外,这里的工作是什么?这似乎是一个重大的疏忽,它让我考虑完全放弃发布管理。

2 个答案:

答案 0 :(得分:7)

我遇到了在远程服务器上运行Powershell脚本的问题。我最终走的路线略有不同。相反,我只使用Invoke-Command块运行正常的Powershell命令。我相信你应该能够同时运行它。

Function Get-PSCredential($User,$Password) {
    $SecPass = ConvertTo-SecureString -AsPlainText -String $Password -Force
    $Creds = New-Object System.Management.Automation.PSCredential -ArgumentList $User,$SecPass
    Return $Creds
}    

$credential = Get-PSCredential -User $deployUser -Password $deployPass
$session = New-PSSession YourServerName -Credential $credential

Invoke-Command -Session $session -ScriptBlock {
    # do your work here
}

如果您作为可以访问该计算机的服务帐户运行,您应该可以取消凭据,只需使用

$session = New-PSSession YourServerName

本周我才开始使用发布管理,所以这似乎是在这么短的时间内完成的最佳方式。

此外,如果您之前从未使用过Invoke-Command,那么脚本块中的所有内容实际上都在其自己的范围内,因此如果您有任何内容,则需要使用-ArgumentList将变量传递给它。如果您对此有任何疑问,请查看this文章。

答案 1 :(得分:1)

正如我今天在another post中解释的那样,MS Release Management的部署方式有点违反直觉:它不是仅使用PSRemoting对目标服务器执行Powershell部署脚本,而是使用PSRemoting安装Windows服务(VisualStudioRemoteDeployer.exe)在目标服务器上。然后,此服务在本地运行您的部署脚本,并且MSRM服务器会定期轮询此Windows服务(请参阅here)以查看它是否已完成部署。

我怀疑这个奇怪的设置与避免double-hop issue有关 - 所以它允许你的脚本从目标服务器到另一个服务器进行第二跳,例如用于网络服务电话。

无论如何,这个Windows服务可能会形成瓶颈,因为每个服务器只能运行一个这样的实例 - 因此,同一服务器上组件的并行部署似乎会发生冲突。

我认为您的问题源于您选择“服务器基本上是运行脚本的临时区域”的设置 - MS Release Management 2013/2015不能很好地运行在这种情况下(如您所知),您应该将组件直接部署到需要安装它们的目标服务器上,从而避免暂存区域瓶颈。

next version of MS Release Management将使用部署代理,该部署代理将用作将组件部署到其他服务器的临时点。这有助于减少MS Release Manager与目标服务器之间必须允许的连接数量(这可能是您选择暂存区域设置的原因),同时仍允许并行(或至少排队)部署。