目前团队项目中有多个Web、服务以及与大数据平台对接接口等应用,每次的发布和部署采用手工的方式进行。停止应用程序,拷贝发布包,启动应用程序,不停的循环着,并且时不时地会出现一些人为错误性问题。这种模式消耗的很多团队时间和精力。
为了解决该问题,决定引入自动构建和持续部署的一些辅助工具,采用的是微软公司的TeamFoundationServer2017,并把DevOps相关模式推广到团队中。
在这个过程中,有一系列已遇到或会将遇到的问题需要解决,作为一个整理和记录,希望以后可以快速处理类似的问题。
在我们的应用中,有一个数据计算和文件上传入库计算的两个Self-Host WCF服务,服务运行在多个服务器上,每台服务器运行一个或多个服务实例进行着大量和较长时间的计算服务。服务以控制台的形式运行在WindowServer2012 R2系统上,并提供一些数据计算过程信息的过程步骤监控信息。基于这样的操作环境和应用服务类型,使用Invoke-Command等方式,因为操作系统内权限等问题,是无法正常启动远程机器上带有界面的应用程序的,通常是进程启动了但是没有应用的交互界面(比如启动远程服务上的计算器)。针对这样的应用,下面是我采用实现停止、发布和启动服务过程的一些具体实现方法。
实现这个发布流程需要两个PowerShell脚本,一个应用在构建服务Agent服务器上,负责完成对分发服务器的认证授权和指令发送,另一个运行在服务所运行在的服务上,负责启动和关闭服务器上的Self-Host应用程序。TFS构建代理上通过调用代理服务上的脚本,实现基本认证和授权,传递命令到服务寄宿的服务上,并调用脚本完成应用程序的启动和停止。
构建服务器上的脚本文件1
1 param( 2 [string]$applicationName = '**.Service.WebSocketHost', 3 [string]$switchType = 'on', 4 [string]$account = "administrator", 5 [string]$password = "111", 6 [string[]]$computername="10.0.0.102", 7 [string]$applicationType ="UploadHost" 8 ) 9 10 Write-Host 'ApplicatnonName:' $applicationName 11 Write-Host 'SwithType:' $switchType 12 Write-Host 'Account:' $account 13 Write-Host 'Password:' $password 14 Write-Host 'IP:' $computername 15 16 $secpwd = convertto-securestring $password -asplaintext -force 17 $cred = new-object System.Management.Automation.PSCredential -argumentlist $account,$secpwd 18 19 $session_many = new-pssession -computername $computername -Credential $cred 20 if( $applicationType -eq "WebSocketHost") 21 { 22 if($switchType -eq 'on') 23 { 24 Invoke-Command -Session $session_many -ThrottleLimit 1 -ScriptBlock { C:\CICD\ExecutedAppManagement.ps1 -applicationName 'C:\ODWebSocketHost\ Service.WebSocketHost.exe' -switchType 'on' -applicationType 'WebSocketHost' } 25 } 26 if($switchType -eq 'off') 27 { 28 Invoke-Command -Session $session_many -ThrottleLimit 1 -ScriptBlock { C:\CICD\ExecutedAppManagement.ps1 -applicationName 'Service.WebSocketHost' -switchType 'off' -applicationType 'WebSocketHost' } 29 } 30 }
服务器端的脚本文件2,
脚本文件1中对应ExecutedAppManagement.ps1文件名
1 param( 2 [string]$applicationName = 'applicationName', 3 [string]$switchType = 'on', 4 [string]$applicationType = 'WebSocketHost' 5 ) 6 Write-Host $switchType 7 8 if($switchType -eq "on") 9 { 10 Write-Host "Turn on App!" $applicationName 11 #开启WebSocket应用程序 12 if($applicationType -eq 'WebSocketHost') 13 { 14 $registerTask = Get-ScheduledTaskInfo -TaskName "TaskODWebSocketHost" 15 if( !$registerTask) 16 { 17 Write-Host $registerTask 18 $taskAction = New-ScheduledTaskAction $applicationName #"C:\ODWebSocketHost\Service.WebSocketHost.exe" 19 $taskTrigger = New-ScheduledTaskTrigger -AtStartup 20 Register-ScheduledTask TaskODWebSocketHost -Action $taskAction -Trigger $taskTrigger 21 } 22 Start-ScheduledTask -TaskName "TaskODWebSocketHost" 23 } 24 25 } 26 if($switchType -eq "off") 27 { 28 Write-Host "Turn off App!" $applicationName 29 stop-process -name $applicationName 30 Write-Host $applicationName + "has turn off" 31 }
控制过程
首先需要在构建代理服务器上添加对应用寄宿服务器上的信任
Set-Item wsman:\localhost\Client\TrustedHosts -value 10.0.0.*
将脚本文件2拷贝的应用寄宿服务器上指定的违章。
通过调用脚本文件1,并传递适当的参数实现对Sefl-Host服务器的启停控制。
最后将调用脚本文件1的命令集成到TFS2107的发布定义中,实现对类似Windows环境上运行的带有交互界面的应用程序进行启动、发布和停止控制。下图是持续发布结果