.NET Core系统的部署

 目录

一、ASP.NET Core网站的发布     

二、在 Visual Studio 中发布ASP.NET Core 项目

三、网站部署需要注意的几个问题

四、如何构建一个安全的系统


       到目前为止,我们开发的系统都是运行在开发人员的开发环境中的。在系统开发完成后,
我们需要把项目部署、运行在生产环境的服务器上,ASP.NET Core开发的网站部署在服务器上。  

一、ASP.NET Core网站的发布     

       我们在开发环境中运行的项目所加载的程序集是为了方便开发工具调试而生成的调试附程序集,运行效率并不高,因此我们不能直接把项目文件夹下 bin/Debug 中的程序集部署到生产环境的服务器上。我们应该创建网站的发布版,创建网站发布版的过程简称为“发布”。

        在发布一个ASP.NET Core 网站的时候,我们有两种部署模式可供选择,分别是“框架依赖”和“独立”。在框架依赖模式下,我们发布生成的程序集中不包含.NET 运行时,所以我们需要在服务器上安装对应版本的.NET 运行时:在独立模式下,我们发布生成的程序集中嵌入了.NET运行时,所以我们不需要在服务器上安装.NET 运行时。对于大部分情况来进,独立模式更符合项目的部署要求,在独立模式下,我们只要把程序集复制到服务器上就可以运行,不需要再去安装额外的运行时,而且如果服务器上同时安装了多个.NET Core 应用,这些应用的运行时不会产生干扰,比如A应用可以采用.NET Core 3.1 运行,而B应用可以采用NET6运行。独立模式唯一的缺点就是生成的程序包比框架依赖的大,毕竟独立模式把.NET 运行时打包到了程序包中,但是利大于弊。

        在独立模式下,我们需要在程序包中包含.NET 运行时,虽然.NET程序集是跨平台的,但是由于.NET 运行时需要和操作系统打交道,因此不同操作系统下的.NET 运行时有一定的差异性,在用独立模式部署的时候,我们需要选择目标操作系统和 CPU 类型。

二、在 Visual Studio 中发布ASP.NET Core 项目

        第1步,选择发布的目标。在 Visual Studio 待发布的项目上右击,选择菜单中的[发布]会显示对话框。这个对话框供我们选择项目的发布目标。我们选择[文件夹]后,单击[下一步]按钮,Visual Studio 就会提示我们选择程序生成的目标文件夹,我们选择程序要生成的目标文件夹后,单击[完成]按钮,即可完成少布目标的选择。

        第2步,配置发布选项。在上一步操作完成后打开的界面中,单击[显示所有设置]按钮Visual Studio 将会显示对话框。

        [配置]选择默认的[Release],这样我们可以生成为生产环境优化的程序集;[部署模式]选择[独立]。我们一旦把[部署模式]选择为[独立],[目标运行时]中就会有[wi-x86].[win-x64][linux-x64]等选项可供选择,这是用来选择入的NET 运行时的版本,请根据目标服务器的操作系统和CPU的类型选择合适的目标运行时。

        单击展开[文件发布选项]建议勾选[启用ReadyToRun编译],因为它会尝试在发布的时候把部分程序集编译为本地代码,从而提高程序的启动速度。

        我们还可以看到[数据库]和[Entity Framework迁移]两个选项,它们分别用来在发布的时候修改连接字符串为生产环境的数据库配置,以及对生产环境的数据库执行数据库迁移。这两个选项不太符合大部分项目的上线流程,因此我们一般不使用它们。

        第3步,单击[发布]按钮,我们就启动了发布流程。根据项目的规模及计算机的配置不同,发布的耗时也不同,一般至少也要几十秒,所以启动发布流程之后请耐心等待。项目发布完成后,我们只要把发布目录下生成的 DLL等全部文件复制到服务器的操作系统上就可以了。

        我们也可以用同样的独立部署模式发布用NET6编写的WinForm、WPF程序,虽然WimnForm、WPF程序不能跨平台运行在非Windows操作系统下,但是我们的程序依然可以不要提前安装NET运行时就在目标计算机上运行。

三、网站部署需要注意的几个问题

        网站发布后生成的程序是可以运行的,比如我们发布生成以 Windows 服务器为目标的独立部署模式的程序,然后直接运行生成目录下的WebApplicationl.exe(具体文件名和项目的名字一致),会发现程序能够正常运行

        问题一,推荐的部署方式。如果公司有比较好的运维能力,并且系统的复杂度比较高,那么作者建议采用Linux作为服务器的操作系统,并且采用容器化部署,让应用程序运行在容器中,用Kubemmetes进行容器的管理,这种做法是目前行业的推荐做法,也符合NET Core的设计初衷。如果公司没有对容器化研究深入的技术人员,但有技术能力支撑使用 Linux 服务器那么可以采用 Linux 服务器部署网站,然后把外部负载均衡服务器的请求转发到应用程序的Kestrcl 中。如果公司没有足够的 Linux 技术能力, 那么可以使用 Windows 服务器,推荐用进程内托管模型方式来让网站以托管的方式运行在 IIS 中,因为这样性能更好,而且可以避免缩写 Windows 服务让网站应用程序“随操作系统启动”。

        问题二,HTTPS 证书配置在哪里。由于 HTTPS 具有避免运营商劫持、保护通信过程不被窃听等优点,因此现在大部分网站都已经肩用 HTTPS,微信小程序、苹果 App 等更是要求应用程序的网络接口必须采用 HTTPS。 对于采用了负载均衡服务器的部署方式来讲,我们一般把证书配置在负载均衡服务器上由于 HTTPS 通信要进行加密和解密,因此启用 HTTPS 之后网站的内存、CPU 压力会增大,如果负载均衡服务器到网站应用程序之间的通信是安全可信的,那么我们在网站应用程序中就不启用 HTTPS 了,也就是用户到负载均衡服务器是 HTTPS 通信,而负载均衡服务器到网站应用程序的 Kestrel 之间是 HTTP 通信。如果我们配置了负载均衡服务器到网站应用程序之间采用 HTTP 通信,那么一定要删掉 Program.cs 中的 UseHttpsRedirection,以避免程序把 HTTP请求重定向到 HTTPS 请求。

        问题三,如何获取客户端的 IP 地址。对于启用了负载均衡服务器的网站来讲,由于用户的请求由负载均衡服务器转发给网站应用程序,因此在网站应用程序看来,请求是负载均衡服备器发出的,我们在使用 HttpContext.Connection.RemotelpAddress 获取客户端的 IP 地址的时候,获取的其实是负载均衡服务器地址,而非原始的用户 IP 地址。

        问题四,程序的更新。,NET 程序在运行时会锁定 DLL 等文件,因此如果我们有新版网站应用程序要替换在运行中的版本的时候,操作系统会提示“文件被占用”,从而无法完成替换。如果网站部署在 IIS 中,有两种解决方法。一种方法是我们编写一个内容包含“网站正在更新”的 HTML 文件,文件名是 app omline.htm,然后把这个文件放到网站的根目录下,当I 检测到这个文件以后,就会关闭网站,我们就可以覆盖程序进行更新了。在更新期间,对f新的请求,IIS 会把 appomine.htm 的内容返回给客户端,因此访问者看到的就是“网站正在更新”这样的提示信息。当网站完成更新后,我们删除 app_omine.htm 即可,下一个请求到后IIS 将自动启动并应用。这种方法比较适合企业内部应用等允许有下线时间的系统,对于互联网网站等不允许有下线时间的系统,我们可以使用NET6新增的“影子拷贝”(shadow-copying),它允许我们在程序运行时替换程序集,具体用法请查看微软文档。

        无论是appofline.htm还是影子拷贝,它们都只能在IS中部署网站时使用。如果我们使用容器+负载均衡服务器的方式来部署网站,只要启动新版网站的容器,然后把旧版网站的容器停止就可以了。如果我们用Kestrel+负载均衡服务器的方式部署网站,因为我们有多台应用服务器,所以我们可以分批更新,也就是先停止其中一批服务器,对它们的程序进行更新,然后重新启动这些服务器,再停止另一批服务器,对它们的程序进行更新,最后重新启动这些服务器。由于我们不是一次性把所有服务器都停止,因此我们的更新操作不会影响用户的访问。

        无论采用哪种方式更新网站,只要我们用负载均衡服务器把用户请求转发给多台网站服务器,就会存在新旧版网站同时运行的短暂时间,甚至有可能来自同一个用户的属于同一个业务流程的两个连续的请求分别被新旧版两个程序处理。因此我们在编写新版系统的时候,要考虑规避这样的短时间内新旧版程序共存导致的逻辑混乱的问题。

四、如何构建一个安全的系统

        对于一个系统,特别是开放给互联网用户使用的系统来讲,系统的安全性是重要问题。个系统,如果系统架构差一点儿,最多开发效率低,代码写得差一点儿,最多系统运行速度慢但是如果系统安全有问题,导致核心业务数据被泄露或者系统被黑客攻击,那就是危及企业亡的灾难性问题。因此公司的所有人员都必须对系统的安全性提高警惕。系统的安全管控是个非常庞大的话题,这里主要从开发人员的角度来谈一下需要注意的一些事项。

        网站一定要启用HTTPS,从而避免网站内容被运营商劫持,以及避免网站通信被窃听。

        Web服务器一定要只开放 Web 服务的端口,其他端口不要开放。如果运维人员需要通过远程桌面或者SSH(secure shell,安全外壳)连接到服务器,那么一定要在服务器的防火墙上设置只允许运维人员的P段访问相关端口。

        要启用负载均衡服务器。这样恶意攻击者就只知道负载均衡服务器的 I 地址,而不知道Web 服务器的IP地址,降低恶意攻击者直接访问 Web 服务器的安全风险。

        要启用 WAF(Web application firewall,Web 应用程序防火墙),WAF可以阻挡相当一部分潜在的网络攻击。

        数据库服务器只允许 Web 服务器的IP 地址访问;数据库服务器一定要设置定时自动备份机制,并且把备份文件异地保存,以便在出现问题时及时恢复数据。

        严格区分开发环境和生产环境,增强生产环境的访问权限管理,避免开发人员直接访问生产环境的服务器。

        对开发人员的代码进行审查,特别要防范CSRF(cross-site request forgery,跨站请求伪造)XsS(cross sitescripting,跨站脚本攻击)、SOL注入漏洞、请求重放攻击等。

        不要相信客户端提交的任何数据,要对客户端提交的数据进行校验,因为客户端提交的数据有可能是造假的。比如我们要实现“删除评论”的功能,我们限定“只有评论的作者才能除自己发表的评论”,如果我们只是在非当前用户发表的评论中不显示“删除评论”链接的话,恶意用户就可以直接找到删除评论的链接,然后把其他人发表的链接的 D 拼接到“删除评论的链接中,从而删除其他人发表的评论。应对这样的漏洞的解决方案就是在所有操作中都要对请求的数据进行校验,比如在“删除评论”操作中,我们就要校验被删除的评论是否是当前用户发表的。

        防范关键业务数据的“可预测性”。如果我们用自动增长值作为订单的主键的话,竞争对
手就可以从订单的主键推测出我们的业务量,而且竞争对手也可以通过对订单主键值的简单递增遍历来批量抓取数据。这个问题的解决方案就是用 Guid 等不可预测的值作为主键值。

        避免服务器端发送给客户端的报错信息造成的泄密,尽量不要把服务器内部的细节发送给客户端。比如我们不能直接把服务器端的异常堆栈发送到客户端,因为异常堆栈中可能包含系统重要的技术秘密,甚至可能包含数据库的连接配置等信息。再如,登录失败给客户端的报错信息应该是“用户名或者密码错误”这样比较笼统的信息,如果服务器端给客户端的报错信息是“用户名不存在”,那么就会给恶意攻击者通过这个报错信息猜测合法用户名的机会。特别应该注意的一个问题是,我们不要直接把 EF Core 中的实体类对象作为请求的响应报文体,因为实体类对象中可能包含一些不应该发送给客户端的数据。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咬口大葱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值