Warning: WP_Syntax::substituteToken(): Argument #1 ($match) must be passed by reference, value given in /www/wwwroot/fawdlstty.com/wp-content/plugins/wp-syntax/wp-syntax.php on line 383
自动化部署主要用在linux服务器集群上。比如有后台服务器需要升级软件,基本做法就是ftp传上去,然后ssh上面重启服务。假如后台服务器一旦多了,这种方式就很麻烦了。这时候可以考虑使用自动化部署的方式来实现后台程序自动更新。由于实现方式太多,是否用docker、WebHook还是GitHook还是轮询都能实现,此处我使用一种自认为最简单的方式实现。大致流程为git仓库->WebHook->程序接受相应->更新并重启
1、首先需要一个git环境。比如github,如果觉得代码放github不安全那么可以自己撘一个git服务,推荐gitea、gogs、gitlabhq三种。其中前两者部署非常简单。部署成功后,新建仓库,提交代码,然后服务器端克隆一个,nohup运行。
2、第二步,找出一种通知机制。个人不太建议轮询。推荐使用WebHook和GitHook。两者区别是,WebHook在用户push后向一个http(s)地址发送请求,GitHook在用户push后执行一个shell脚本。具体添加方式在仓库设置里面操作。此处选择WebHook。
3、第三步是响应请求,也就是部署的服务至少需要有一个http服务器然后对外提供服务。将第二步的请求地址设置为服务地址。
4、程序收到http响应后,执行更新并重启。以C#为例,大概是这样的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | var _psi = new ProcessStartInfo ("git", "pull -v --progress \"origin\"") { RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true }; using (var _ps = Process.Start (_psi)) { _ps.OutputDataReceived += (_sender, _e) => { //// .Net Core 环境下,这段代码通常不生效,原因未知,解决方法为保存git密码 //if (_e.Data == null) // return; //if (_e.Data.IndexOf ("Username for") != -1) { // _ps.StandardInput.WriteLine ("TODO: git username"); //} else if (_e.Data.IndexOf ("Password for") != -1) { // _ps.StandardInput.WriteLine ("TODO: git password"); //} //// git保存密码的方式 //// cd $HOME //// git config --global credential.helper store //// # 进入项目所在路径 //// git pull //// # 输入一次账号密码,密码即被记录 }; _ps.ErrorDataReceived += (_sender, _e) => { }; _ps.BeginOutputReadLine (); _ps.BeginErrorReadLine (); while (!_ps.HasExited) Thread.Sleep (100); } Thread.Sleep (100); using (var _ps = Process.Start (new ProcessStartInfo ("dotnet", "MyServer.dll"))) {} new Thread (() => { Thread.Sleep (100); Environment.Exit (0); }).Start (); Response.Write ($"restart...{Process.GetCurrentProcess ().Id}"); |
其中有个需要注意的是,我当前使用的是.Net Core 2.2,当前对进程管道的管理有点问题,所以需要在git目录保存账号密码, 这样下次更新服务就不需要输入密码了 ,这个是根据git仓库保密性来确定是否需要这一步。如果你的仓库不需要密码也能直接拉取,那么可以跳过这一步。
5、然后重启服务时,当前程序可能还没退出,端口还被占用,所以程序启动时需要加入重试机制,避免重启失败。
这几步操作做完后,自动化部署整个功能就完成了。后续需要部署服务时,在git目录提交,推送,稍等一小会,所有服务就全部自动部署完成。