Core在IIS的热发布问题或者报错文件已在另一个程序中打开

技术分享 Story 74浏览 0评论

关于Core发布到IIS的热发布问题,或者覆盖dll文件的时候会报错"文件已在另一个程序中打开",也就是无法覆盖程序的问题,经过百度和分析总结以下几种方案:

一、使用app_offline.htm文件,这个方案网上最多:

1.具体步骤:

1)在发布路径新建一个文件夹"UpdateFiles"

2)文件夹"UpdateFiles"里面放一个app_offline.htm文件,这个文件是网站处于离线状态的时候的返回给客户端的页面内容

3)文件夹"UpdateFiles"里面放一个"PublishFiles"文件夹,这个文件夹里面放需要发布的文件

4)在发布路径下面新建一个"pubish.bat"文件,里面输入如下内容:其实就是先复制app_offline.htm文件到发布路径,让网站处于离线状态,然后覆盖发布的文件,再删除pp_offline.htm文件,让网站恢复在线状态

@echo off
call xcopy %~dp0UpdateFiles\app_offline.htm %~dp0
call xcopy %~dp0UpdateFiles\PublishFiles %~dp0 /s /e /Y
del %~dp0app_offline.htm
pause

2.利弊分析:

好处:

1.实现简单

2.不用开发

弊端:

1.复制app_offline.htm文件到发布路径之后,网站不能立即结束,需要等最后的请求结束,才能复制,不然以上脚本复制的时候会失败

2.复制app_offline.htm文件到发布路径之后,时没有结束的请求返回的结果会最终会是空白内容,也即会是失败,这样会造成客户端发布的时候偶发性的失败问题

3.覆盖文件期间,网站处于离线状态,无法正常访问

二、改文件名字,然后复制发布程序,然后退出网:

来源:https://bbs.csdn.net/topics/395986630

1.具体步骤:

如下代码,在一个控制器创建一个如下的方法,然后需要更新的时候Post这个方法就行。以下代码没有具体测试过,只测试过可以修改文件名字和application.StopApplication();会退出网站,所以应该是可行的。

 [HttpPost]
        public IActionResult Update([FromServices]IHostApplicationLifetime application)
        {
            //获取程序的工作目录路径,依赖注入 IWebHostEnvironment
            var web = WebHost.ContentRootPath;
 
            //// 改名方法-假设项目的dll 为 WebApplication1.dll
            FileInfo fi = new FileInfo(Path.Combine(web, "WebApplication1.dll"));
            //// 改为 a1234
            fi.MoveTo(Path.Combine(web, "a1234.dll"));
 
            //要复制的新文件路径-你的新dll 路径 可以是下载或者复制或移动
            string pLocalFilePath = Path.Combine(WebHost.WebRootPath, "css", "WebApplication1.dll");
 
            //将新文件复制过去基目录
            string pSaveFilePath = Path.Combine(web, "WebApplication1.dll");
            if (System.IO.File.Exists(pLocalFilePath))
            {
                System.IO.File.Copy(pLocalFilePath, pSaveFilePath, true);
 
                //复制成功后, 杀死当前的进程=相当于重启了  依赖注入 IHostApplicationLifetime
                application.StopApplication();
            }
 
            return Content("ok");
        }

2.利弊分析:

好处:

1.基本可以实现IIS的热发布

弊端:

1.application.StopApplication();之后,当时没有结束的请求返回的结果会最终会是空白内容,也即会是失败,这样会造成客户端发布的时候偶发性的失败问题

2.现稍微复杂,需用开发

三、使用使用网关(例如ocelot)或负载均衡(nginx)软件实现(推荐):

1.具体实现:

这个还没有来得及具体验证,不过理论上是比较完美的解决方案,但实现起来有点复杂,其实就是利用网关(例如ocelot)或负载均衡(nginx)软件的高可用功能来实现,可以IIS中部署2个相同的网站服务,然后发布的时候一个个发布更新网站,更新服务的时候"优雅"的停止(nginx好像直接命令就可以实现),这样就可以在不影响客户端的情况下更新网站了。当然也可以用多服务器来实现高可用。

2.利弊分析:

好处:

1.比较完美的实现热发布,实现高可用

弊端:

1.需要搭建Consul,部署2个或多个网站

 

本来刚接触Core,希望有经验的大佬推荐更加完善的解决方案。

转载请注明:成长的对话 » Core在IIS的热发布问题或者报错文件已在另一个程序中打开