目录
LTS
长期维护的版本。
IIS如何托管.NetCore的项目
- IIS在托管.NetCore的项目时,需要先将.NetCore的项目发布。
- 然后在IIS中需要安装 Asp.NetCoreModuleV2。
什么是.NetCore
- .NetCore是一个服务。
- 这个服务会启动了一个网络监听器,并且这个监听器需要长时间的运行。
- 一旦这个监听器接收到一个HTTP的请求以后,就会将HTTP的请求传递给应用的管道进行处理。
- 当完成处理后就会产生HTTP请求的响应,并且通过这个监听器返回给客户端。
Hosting
- 这个长时间运行的服务需要寄宿在托管进程里面。
- 提供了这个功能的组件就是Hosting。
- 像这种寄宿在托管进程里面由Hosting长时间管理的服务,就是托管服务。
- 所以.NetCore的应用就是一个寄宿在Hosting上面的一个托管服务。
- 任何需要在后台长时间运行的程序,都可以按照一定的标准把它定义成一个服务然后寄宿在Hosting 上面。
- 创建一个托管服务实际上就是一个实现了IHostedServce接口的类。
Kestrel
- 但是对于HTTP请求的处理必须要有一个服务器,来接收HTTP的请求,这个服务器就是Kestrel。
- 当Web服务器启动以后,配置的HTTP请求管道才会被构建出来。
- 这个管道就会被绑定到Kestrel默认的端口上面,默认的端口号是5000,并且开始监听HTTP的请求。
- 当HTTP的请求一旦到达Kestrel服务器,就会将其标准化为一个HTTP的上下文对象。
- 也就是HttpContext对象,然后再把HttpContext对象发送给管道。
- 处理HTTP请求的是配置在管道中的各个组件,这个组件就是管道中间件。
- 所以管道就是由一个服务器和一组中间件构成。
- 也可以把管道理解为HTTP的请求被处理的步骤。
中间件
是什么
- Kestrel负责HTTP请求的监听,接收,分发和最终的响应。
- 对于HTTP请求的处理就是根据中间件来完成的。
- 中间件实际上是个Func委托,Func委托的入参是RequestDelegate,返回值也是RequestDeleagate。
- RequestDeleagate也是个委托,是用delegate直接声明的委托,返回的类型是Task,入参是HttpContext。
- 所以RequestDeleagate就表示了HTTP请求的处理器,中间件就是借助了RequestDeleagate将HTTP的 请求往后传递。
- 所以管道也可以理解为由委托组成的一条双向责任链,形成了一个闭环。
自定义中间件
app.UseMiddleware<TMiddleware>()
注册模式
Run方式
- 通过Run的方式进行注册,只是对HttpContext对象进行处理,并没有去执行RequestDelegate委托。
- 所以一般作为HTTP请求的终结点,也就是不在执行下一个中间件。
Use方式
- 通过Use的方式进行注册,一般不把它作为HTTP请求的终结点。
- 在对HttpContext对象进行处理完成之后,可以执行传入的RequestDelegate委托,去执行下一个中间件。
中间件实现原理
- 通过Use的方式进行注册就是在集合里面添加元素,该元素就是一个Func委托,Func委托的入参是 RequestDelegate,返回值也是RequestDeleagate。
- 最后需要调用该集合的Reverse方法,把集合里面的元素进行反转。
- 如果对该集合的元素不进行反转,就会先执行最后加入的中间件。
应用场景
异常处理
- 可以自定义中间件来处理异常,这类异常属于Action方法之外的异常。
- 最常见的就是输入一个不存在的路径,然后服务端返回的HTTP响应状态码是400,表示这个HTTP的 请求是错误的。
防盗链
中间件/IIS
- 也可以自定义中间件来进行防盗链。
- 在HTTP协议中,有一个请求头的键名叫做referer。
- 可以通过referer来跟踪网站的来源,如果检测到referer的域名地址不是当前网站的域名地址,就需要 对当前HTTP的请求进行阻止。
- 如果服务器使用的是IIS,需要通过第三方的插件来实现防盗链的功能,比较常用的一款插件叫做 ISAPI_Rewrite。
referer真的能防盗链?
- referer只能在一定程度上进行防盗链。
- 很多Web项目的测试工具,都是可以直接在HTTP请求中设置referer。
- 如果盗链的网站使用的是HTTPS协议,而图片的链接使用的是HTTP协议,从HTTPS向HTTP发起的请 求,会不带referer。
- 这是因为HTTPS是安全的传输协议,它规定了客户端不应该在非安全的HTTP请求中包含referer字段。
- 如果代码写的不严谨,没有判断referer为空的情况,就会绕过防盗链的检查。
- 所以想要更严格的防盗链,就可以考虑使用Nginx。
ConfigureServices/Configure
ConfigureServices
- ConfigureServices方法主要是服务的注册。
- .NetCore自己的服务注册完成以后才会去调用ConfigureServices方法,用来注册用户自定义的服务。
Configure
Configure方法主要是中间件的注册。
HttpClientFactory
- .NetCore提供了HttpClientFactory对象来发送HTTP的请求。
- 在.NetFramework中没有HttpClientFactory对象。所以只能不断的创建HttpClient对象,最终TCP的连 接数会被耗尽。虽然使用了using的方式在退出前调用了Dispose方法可以将HttpClient对象占用的非 托管资源给释放掉,但是TCP仍然处于保持连接的状态,一般在240秒后才会自动断开。
- 所以当短期的HTTP请求过多时,就可能导致套接字资源耗尽的异常。如果不想释放创建的HttpClient 对象,就可以将它作为单例一直使用,这样就解决了套接字资源耗尽的问题。
- 但是当主机的DNS有更新时,就有可能产生无法解析主机名称的异常。因为单例的HttpClient对象是 不会随着DNS的更新去进行更新的。
- 所以.NetCore就提供了HttpClientFactory对象来彻底解决这些问题。在HttpClientFactory对象的内部管 理着一个TCP的连接句柄池,会对每一个HttpClient对象使用一个句柄进行跟踪管理,当该实例使用 完毕之后,句柄仍然控制着资源的释放。
- 所以在处理短期大量的HTTP请求时,可以通过句柄对不同的HTTP请求实例进行跟踪管理,从而让TCP 套接字的生命周期延长,完成对套接字的复用。