上一篇我们介绍了系统日志与测试相关的内容并添加了相关的功能;本章我们将介绍跨域与程序部署相关的内容
一、跨域
1、跨域的概念
1、什么是跨域?
一个请求的URL由协议,域名,端口号组成,以百度的https://www.baidu.com为例,协议为https,域名由子域名www和主域名baidu组成,端口号若为80会自动隐藏(也可以配置为其它端口,通过代理服务器将80端口请求转发给实际的端口号)。而当请求的URL的协议,域名,端口号任意一个于当前页面的URL不同即为跨域
2、什么是同源策略?
浏览器存在一个同源策略,即为了防范跨站脚本的攻击,出现跨域请求时浏览器会限制自身不能执行其它网站的脚本(如JavaScript)。所以说当我们把项目部署到Web服务器后,通过浏览器进行请求时就会出现同源策略问题;而像PostMan软件因其是客户端形式的,所以不存在此类问题
3、跨域会导致什么问题?
同源策略会限制以下行为:
- Cookie、LocalStorage和IndexDb的读取
- DOM和JS对象的获取
- Ajax请求的发送
2、常用的解决方法
这里我们将简单介绍针对跨域问题常用的几种解决办法,并就其中的Cors方法进行配置,若对其它方式感兴趣,可参照老张的哲学的文章,⅖ 种方法实现完美跨域
2.1、JsonP
1、原理
上面有提到浏览器基于其同源策略会限制部分行为,但对于Script标签是没有限制的,而JsonP就是基于这一点,它会在页面种动态的插入Script标签,其Src属性对应的就是api接口的地址,前端会以Get方式将处理函数以回调的形式传递给后端,后端响应后会再以回调的方式传递给前端,最终页面得以显示
2、优缺点
JsonP出现时间较早,所以对旧版本浏览器支持性较好;但自身只支持Get请求,无法确认请求是否成功
2.2、 CORS
1、原理
CORS的全称是Corss Origin Resource Sharing,即跨域资源共享,它允许将当前域下的资源被其它域的脚本请求访问。其实现原理就是在响应的head中添加Access-Control-Allow-Origin,只要有该字段就支持跨域请求
2、优缺点
Cors支持所有Http方法,不用考虑接口规则,使用简单;但是对一些旧版本的浏览器支持性欠佳
3、使用
其使用非常简单,以我们的项目为例,在BlogSystem.Core项目的Startup类的ConfigureServices方法中进行如下配置
同时需要开启使用中间件,如下:
2.3、Nginx
1、原理
跨域问题是指在一个地址中发起另一个地址的请求,而Nginx可以利用其反向代理的功能,接受请求后直接请求该地址,类似打开了一个新的页面,所以可以避开跨域的问题
2、优缺点
配置简单,可以降低开发成本,方便配置负载均衡;灵活性差,每个环境都需要进行不同的配置
二、程序部署
1、部署模式
在.NET Core中,有两种部署模式,分别为FDD(Framework-dependent)框架依赖发布模式和SCD(Self-contained)自包含独立发布模式
- FDD:此类部署需要服务器安装.NET Core SDK环境,部署的包容量会比较小,但可能因SDK版本存在兼容性问题;
- SCD:此类部署自包含.NET Core SDK的环境,不同.NET Core版本可以共存,其部署包容量会较大,且需要对服务器进行相关配置
2、常用部署方式
以下内容均参考老张的哲学的文章最全的部署方案 & 最丰富的错误分析,有兴趣的朋友可以参考原文
2.1、Windows平台
- 直接运行:发布目标选择windows时会在文件夹中生成一个exe文件,我们可以直接执行exe文件或使用CLI命令调用dll运行;这种方式虽然方便,却存在一些弊端,比如说部署多个的情况下会存在很多控制台窗口,如误操作会导致窗口关闭等;
- 部署服务:除了上述直接运行的方式外,我们还可以将程序发布为服务,发布后我们可以像控制系统服务一样控制程序的启动和关闭
需要注意的是上述两类方法都需要借助IIS或者是代理服务器进行服务的转发,否则只能在本地进行访问;
2.2、Linux平台
Linux平台常用的部署方式即为程序+代理服务器,但是当我们配置完成后运行程序时,该运行命令会一直占用操作窗口,所以我们需要使用“守护进程”来解决这个问题,简单来说就是将程序放到后台运行,不影响我们进行其他操作
综上,部署模式、部署方式及部署平台有多种组合方式,接下来我们挑选下述3种方法进行演示:
方案 | 依赖运行时/宿主机 | 依赖代理服务器 | 其它配置 |
---|---|---|---|
Windows程序(SCD)+Nginx | 否 | 是 | 无 |
Windows服务(FDD)+IIS | 是 | 否 | 设置为服务 |
Linux程序(FDD)+Nginx | 是 | 是 | 守护进程 |
3、程序发布
1、这里我们右击BlogSystem.Core项目,选择发布,选择文件夹后,点击高级
2、为了演示后面的发布实例,这里我们分别选择3种组合模式,①独立+win-x64;②框架依赖+win-x64;③框架依赖+linux-x64
3、将发布实例拷贝到单独的文件夹种,这里我们使用SCD-Window验证下程序能否直接运行,运行BlogSystem.Core.exe,报错:
原来还是老问题,BLL没有添加到发布文件中,我们到项目的bin文件夹下将BLL和DAL的dll文件分别拷贝至3个文件夹,再次运行,出现404错误,经过确认发现,首页对应的是Swagger文档页面,而在配置中间件时我们有添加开发环境才配置swagger的逻辑,所以这里我们可以根据个人需求决定是否添加。
这里我为了方便确认发布是否成功,所以将其从判断逻辑中取出了。重新生成发布文件,拷贝BLL和DAL的dll文件,再次运行,还是报错。原来时Swagger的XML文件缺失,从bin文件夹下拷贝添加至发布文件,运行后成功显示页面
4、有的朋友会说了,每次都要拷贝这两个dll和这两个xml文件,太麻烦了。其实也是有对应的解决办法的,我们可以使用dotnet的CLI命令进行发布,选择引用的发布文件夹为bin文件夹,拷贝至发布文件夹即可,有兴趣的朋友可以自行研究
三、服务器发布
这里我用的是阿里云服务器,Window系统版本是Window Server2012 R2,Linux系统版本是CentOS 8.0;在操作前记得确认拷贝的发布文件能否在本地正常运行
1、Windows程序(SCD)+Nginx
1、解压后双击exe文件网站可以正常运行,如下:
2、这个时候我们发现了一个问题,服务器上没有数据库,所以无法确认功能是否正常,这里我们先下载安装一个Microsoft SQL Server 2012 Express数据库(建项目时没有考虑到发布后测试的问题,实际上像SQLite数据库是非常符合这类场景的)
安装完成后我们新建一个BlogSystem的数据库,通过Sql文件的形式将数据库结构和数据导入至服务器数据库,这时候又发现一个问题,由于我们连接数据库的逻辑放置在model层的BlogSystemContext文件夹下,所以需要将连接中的DataSource更改为Express数据库,重新发布后覆盖旧的发布文件(系统设计有缺陷,可以将EF上下文文件放在应用程序层或单独一层),再次运行,成功执行查询,如下:
3、这个时候本地已经可以进行正常的访问了,但是外部网络是无法访问调用接口的,这里我们借助Nginx进行服务的转发。下载Nginx后解压对conf文件夹下的nginx.conf文件进行如下配置:
4、在nginx.exe文件所在目录的文件路径输入cmd,键入nginx启动服务访问8081端口,成功显示页面(确保core程序正常运行)如下:
5、这个时候我们使用其它电脑访问接口,发现还是无法访问,经过查询是阿里云服务器进行了相关的限制,在阿里云控制台配置安全组规则后即可正常访问,如下:
6、配置完成后运行,成功访问该网站且功能正常。这类方法不需要借助Core的运行时环境,可以说十分便捷
2、Windows服务(FDD)+IIS
1、首先我们将FDD发布文件压缩后拷贝至Window Server主机,因FDD的部署方法需要借助.NET Core运行时环境,所以这里我们首先到官网https://dotnet.microsoft.com/download/dotnet-core/current/runtime下载安装.NET Core运行时,这里我们选择的是右边这个,安装完需要重新启动
2、上一个方法中桌面显示控制台窗口显然不是一个较佳的方案,所以这里我们将其注册为服务。官方提供了ASP.NET Core服务托管的方法,但使用较为复杂,这里我们借助一个名为nssm的工具来达到同样的目的。我们下载nssm后,在其exe路径运行cmd命令,执行nssm install,在弹出的窗口中进行如下配置:
3、我们在系统服务中开启BlogSytem.Core_Server,在控制面版中选择安装IIS服务,并发布对应的项目,安装完成后,添加部署为8082端口,将应用程序池修改为无托管,如下:
4、运行网站,成功显示页面,但是进行功能试用时发现报错;经过确认是由于IIS应用程序池的用户验证模式和sqlserver的验证模式不同,解决办法有三种①修改应用程序池高级设置中的进程模型中的标识②将连接数据库字符串中的Integrated Security=True去除,并添加数据库连接对应的账号密码③在数据库的“安全性”>“登录名”里面,添加对应IIS程序池的名称,并在这个用户的“服务器角色”和“用户映射”中给他对应的权限
后续尝试方案一失败,尝试方案二成功,方案三由于要安装SSMS所以没有尝试,有遇到相同问题的朋友可以自己试下
3、Linux程序(FDD)+Nginx
1、首先我们使用MobaXterm工具登录至Linux主机(选择此工具是由于其)同时支持文件传送和命令行操作),这里使用的Linux版本是CentOS 8.0;借助MobaXterm工具在home文件夹下创建WebSite文件夹,并在其内部创建BlogSystem文件夹,将我们准备好的FDD部署方式的发布文件上传至此文件夹后,使用命令sudo dnf install dotnet-sdk-3.1
安装.net core sdk,如下图
2、输入cd /home/WebSite/BlogSystem
切换至项目文件夹后,使用dotnet BlogSystem.Core.dll
运行程序,成功执行,但是由于我们没有数据库,且未配置代理服务器,所以无法验证服务是否正常运行;所以这里我们先参照微软doc快速入门:在 Red Hat 上安装 SQL Server 并创建数据库安装Sql Server数据库(阿里云默认安装了python3作为解释器所以无需重复安装),安装完成后我们开放在阿里云实例中开放1433端口,使用可视化工具导入表结构和数据
3、完成上述操作后我们需要配置守护进程,将程序放在后台运行。首先我们在/etc/systemd/system下新建守护进程文件,文件名以.service结尾,这里我们新建名为BlogSystem.service文件,使用MobaXterm自带的编辑器打开文件后进行如下配置,注意后面的中文备注需要去除否则会报错
[Unit]
Description=BlogSystem #服务描述,随便填就好
[Service]
WorkingDirectory=/home/WebSite/BlogSystem/ #工作目录,填你应用的绝对路径
ExecStart=/usr/bin/dotnet /home/WebSite/BlogSystem/BlogSystem.Core.dll #启动:前半截是你dotnet的位置(一般都在这个位置),后半部分是你程序入口的dll,中间用空格隔开
Restart=always
RestartSec=25 #如果服务出现问题会在25秒后重启,数值可自己设置
SyslogIdentifier=BlogSystem #设置日志标识,此行可以没有
User=root #配置服务用户,越高越好
Environment=ASPNETCORE_ENVIRONMENT=Production
[Install]
WantedBy=multi-user.target
我们使用cd /etc/systemd/system/
切换至BlogSystem.service对应的目录,使用systemctl enable BlogSystem.service
设置为开机运行后,再使用systemctl start BlogSystem.service
启动服务,另外可以使用systemctl status BlogSystem
确认服务状态
4、接下来我们安装代理Nginx代理默认的5000端口,使用sudo yum install nginx
安装nginx后,我们到\etc\nginx文件夹下打开nginx.conf文件进行如下配置:
配置完成我们进入\etc\nginx文件夹下,使用systemctl enable nginx
将nginx设置为开机启动,并使用systemctl start nginx
启用服务,同样可以使用systemctl status nginx
确认其状态。确认无误后在阿里云中开放8081端口,外网可正常访问,但功能试用时报错,原来是数据库连接错误,重新设置后即可正常访问
本章完~
本人知识点有限,若文中有错误的地方请及时指正,方便大家更好的学习和交流。
本文部分内容参考了网络上的视频内容和文章,仅为学习和交流,地址如下:
老张的哲学,系列一、ASP.NET Core 学习视频教程
solenovex,ASP.NET Core 3.x 入门视频