首页 > 解决方案 > Azure Service Fabric - 自动删除/重新创建服务

问题描述

我们的 Azure Service Fabric 集群中有一项服务,它似乎每 48 小时就会冻结并失去与数据库的连接。在我让开发人员调查该问题之前,我的解决方法是通过 Service Fabric Explorer 删除该服务,然后立即重新创建它。这暂时解决了这个问题,直到它再次冻结。

我的问题是无论如何我可以自动化这个过程吗?至少要一两个月才能让开发人员对其进行研究,因此我正在寻找每天自动运行一次该过程的方法。

标签: azure-service-fabric

解决方案


这是我用来重启无状态服务的脚本。它使用Restart-ServiceFabricDeployedCodePackage上面提到的。

我已经调用了它Restart-ServiceFabricServiceCodePackages.ps1,你可以用 a 调用它,-ServiceName fabric:/application/service并根据你的服务的正常启动时间调整等待时间。

Param (
    [Parameter(Mandatory=$true)]
    [uri] $ServiceName,

    [int] $WaitBetweenNodesSeconds = 30
)

try {
    Test-ServiceFabricClusterConnection | Out-Null
}
catch {
    throw "Active connection to Service Fabric cluster required"
}

$serviceDescription = Get-ServiceFabricServiceDescription -ServiceName $ServiceName -ErrorAction SilentlyContinue
if (!$serviceDescription) {
    throw "Invalid Service Fabric service name"
}

if ($serviceDescription.ServiceKind -ne "Stateless") {
    throw "Unknown outcomes could occur for non-stateless services"
}

$applicationName = $serviceDescription.ApplicationName
$serviceTypeName = $serviceDescription.ServiceTypeName
$service = Get-ServiceFabricService -ServiceName $ServiceName -ApplicationName $applicationName
$application = Get-ServiceFabricApplication -ApplicationName $applicationName
$serviceType = Get-ServiceFabricServiceType -ServiceTypeName $serviceTypeName -ApplicationTypeName $application.ApplicationTypeName -ApplicationTypeVersion $application.ApplicationTypeVersion
$serviceManifestName = $serviceType.ServiceManifestName
$nodes = Get-ServiceFabricNode -StatusFilter Up
$nodes | Where-Object {
    $nodeName = $_.NodeName
    $hasService = $null
    $hasApplication = Get-ServiceFabricDeployedApplication -NodeName $nodeName -ApplicationName $applicationName
    if ($hasApplication) {
        $hasService = Get-ServiceFabricDeployedServicePackage -NodeName $nodeName -ApplicationName $applicationName -ServiceManifestName $serviceManifestName -ErrorAction SilentlyContinue
    }

    return $hasApplication -and $hasService
} | ForEach-Object {
    $nodeName = $_.NodeName
    $codePackages = Get-ServiceFabricDeployedCodePackage -NodeName $nodeName -ApplicationName $applicationName -ServiceManifestName $serviceManifestName
    $codePackages | ForEach-Object {
        $codePackageName = $_.CodePackageName
        $servicePackageActivationId = $_.ServicePackageActivationId
        $codePackageInstanceId = $_.EntryPoint.CodePackageInstanceId
        Write-Host "Restarting deployed package on $nodeName named $codePackageName (for service package id: $servicePackageActivationId and code package id: $codePackageInstanceId)"
      
        $success = Restart-ServiceFabricDeployedCodePackage -NodeName $nodeName -ApplicationName $applicationName -ServiceManifestName $serviceManifestName -CodePackageName $codePackageName -CodePackageInstanceId $codePackageInstanceId -ServicePackageActivationId $servicePackageActivationId -CommandCompletionMode Invalid
        if ($success) {
            Write-Host "Successfully restored deployed package on $nodeName" -ForegroundColor Green
        }

        Write-Host "Waiting for $WaitBetweenNodesSeconds seconds for previous node to restart before continuing"
        Start-Sleep -Seconds $WaitBetweenNodesSeconds

        $retries = 0
        $service = Get-ServiceFabricService -ServiceName $ServiceName -ApplicationName $applicationName
        while ($retries -lt 3 -and ($service.HealthState -ne "Ok" -or $service.ServiceStatus -ne "Active")) {
            $service = Get-ServiceFabricService -ServiceName $ServiceName -ApplicationName $applicationName
            $retries = $retries + 1

            Write-Host "Waiting for an additional 15 seconds for previous node to restart before continuing because service state is not healthy"
            Start-Sleep -Seconds 15
        }
    }
}

推荐阅读