最新版本号[免费下载]
  • AServer - 基于Asp.net core Kestrel的超迷你http服务器
    AServer - 基于Asp.net core Kestrel的超迷你http服务器

     

    三:总结

      对于AServer的介绍也差不多了。希望对同学们有帮助。AServer虽然功能很简单,就是对Http请求做出响应。但是我也可以说AServer的功能很强大,因为它能对Http请求做出响应。因为从Http的本质上来说,AServer几乎可以实现所有基于Http的功能。我们可以用它来实现restful api,可以用来实现各种管理系统,可以用来实现cms系统。。。

      不管使用ASP.NET MVC或者JSP或者node express等web框架开发bs/web系统的时候其实套路都是一样的,概况一下就这么几步:

      1.拦截请求(路由)

      2.解析请求携带的参数(url,headers,querystrings,body等)

      3.根据参数处理业务(查数据,持久数据等)

      4.根据业务处理结果做出响应(html,json,xml等)

      我们只要了解这个套路,不管用什么技术,什么框架,其实都是一样的,只要查下api,弄明白怎么获取http请求的参数,怎么做出响应。AServer也实现了这个套路。如果有心的话,对AServer实现过滤器,参数绑定,视图引擎等功能,那基本上就是一个简易的mvc框架了。当然如果你的业务复杂,请选用ASP.NET Core MVC,它功能强大,性能强悍;如果你只是需要实现几个简单的Http接口,可以考虑AServer来实现。

     


    ,220)/}

    服务器,迷你,基于,
    2019-01-31

    1223

  • 使用IIS在Windows上托管ASP.NET Core中文手册(Window服务器版)
    使用IIS在Windows上托管ASP.NET Core中文手册(Window服务器版)

    博文背景: 最近想用.Net Core进行做毕业设计

    服务器,手册,使用,托管,中文
    2018-12-20

    3627

  • asp.net core + 前端H5 页面视频站制作尝试
    asp.net core + 前端H5 页面视频站制作尝试

    .net core 2.1出来一段时间了,一直关注,前周花了半天时间学习了一下,特制作了一个视频小站(欢迎扫码体验):页面首页效果如下: 播放页面效果如下:部分代码:using ENT.IBLL;using ENT.WebApp.IModels;using ENT.WebApp.ViewModels;using NCore;using NCore.Web.Models;using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;namespace ENT.WebApp.Models {    public class HomeModel : ModelCore

    视频,前端,页面,制作,尝试
    2018-09-30

    501

  • ASP.NET Core依赖注入最佳实践,提示&技巧
    ASP.NET Core依赖注入最佳实践,提示&技巧

    分享翻译一篇Abp框架作者(Halil İbrahim Kalkan)关于ASP.NET Core依赖注入的博文.在本文中quot;Deleted a product with id = {id}");         }     } }

    ProductService具有公开的Logger属性. 依赖注入容器可以自动设置Logger(前提是ILogger之前注册到DI容器中).

    建议做法

    1. 仅对可选依赖项使用属性注入。这意味着你的服务可以脱离这些依赖能正常工作.

    2. 尽可能得使用Null对象模式(如本例所示Logger = NullLogger<ProductService>.Instance;), 不然就需要在使用依赖项时始终做空引用的检查.

    服务定位器

    服务定位器模式是获取依赖服务的另一种方式.
    例如:

    public class ProductService{    private readonly IProductRepository _productRepository;    private readonly ILogger<ProductService> _logger;    
        public ProductService(IServiceProvider serviceProvider)    {
            _productRepository = serviceProvider
              .GetRequiredService<IProductRepository>();
              
            _logger = serviceProvider
              .GetService<ILogger<ProductService>>() ??
                NullLogger<ProductService>.Instance;
        }    
        public void Delete(int id)    {
            _productRepository.Delete(id);
            _logger.LogInformation(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;Deleted a product with id = {id}");     } }

    ProductService服务注入IServiceProvider并使用它来解析其依赖,如果欲解析的依赖未注册GetRequiredService会抛出异常,GetService只返回NULL.

    在构造函数中解析的依赖,它们将会在服务被释放的时候释放,因此你不需要关心在构造函数中解析的服务释放/处置(release/dispose),这点同样适用于构造函数注入和属性注入.

    建议做法

    1. 如果在开发过程中已知依赖的服务尽可能不使用服务定位器模式, 因为它使依赖关系含糊不清,这意味着在创建服务实例时无法获得依赖关系,特别是在单元测试中需要模拟服务的依赖性尤为重要.

    2. 尽可能在构造函数中解析所有的依赖服务,在服务的方法中解析服务会使你的应用程序更加的复杂且容易出错.我将在下一节中介绍在服务方法中解析依赖服务

    服务生命周期

    ASP.NET Core下依赖注入中有三种服务生命周期:

    1. Transient,每次注入或请求时都会创建转瞬即逝的服务.

    2. Scoped,是按范围创建的,在Web应用程序中,每个Web请求都会创建一个新的独立服务范围.这意味着服务根据每个Web请求创建.

    3. Singleton,每个DI容器创建一个单例服务,这通常意味着它们在每个应用程序只创建一次,然后用于整个应用程序生命周期.

    DI容器自动跟踪所有已解析的服务,服务在其生命周期结束时被释放/处置(release/dispose)

    1. 如果服务具有依赖关系,则它们的依赖的服务也会自动释放/处置(release/dispose)

    2. 如果服务实现IDisposable接口,则在服务被释放时自动调用Dispose方法.

    建议做法

    1. 尽可能将你的服务生命周期注册为Transient,因为设计Transient服务很简单,你通常不关心多线程和内存泄漏,该服务的寿命很短.

    2. 请谨慎使用Scoped生命周期的服务,因为如果你创建子服务作用域或从非Web应用程序使用这些服务,则可能会非常棘手.

    3. 小心使用Singleton生命周期的服务,这种情况你需要处理多线程和潜在的内存泄漏问题.

    4. 不要在Singleton生命周期的服务中依赖TransientScoped生命周期的服务.因为Transient生命周期的服务注入到Singleton生命周期的服务时变为单例实例,如果Transient生命周期的服务没有对此种情况特意设计过,则可能导致问题. ASP.NET Core默认DI容器会对这种情况抛出异常.

    在服务方法中解析依赖服务

    在某些情况下你可能需要在服务方法中解析其他服务.在这种情况下,请确保在使用后及时释放解析得服务,确保这一点的最佳方法是创建Scoped服务.
    例如:

    public class PriceCalculator{    private readonly IServiceProvider _serviceProvider;    
        public PriceCalculator(IServiceProvider serviceProvider)    {
            _serviceProvider = serviceProvider;
        }    
        public float Calculate(Product product, int count,
          Type taxStrategyServiceType)    {        using (var scope = _serviceProvider.CreateScope())
            {            var taxStrategy = (ITaxStrategy)scope.ServiceProvider
                  .GetRequiredService(taxStrategyServiceType);            var price = product.Price * count;            return price + taxStrategy.CalculateTax(price);
            }
        }
    }

    PriceCalculator在构造函数中注入IServiceProvider服务,并赋值给_serviceProvider属性. 然后在PriceCalculator的Calculate方法中使用它来创建子服务范围。 它使用scope.ServiceProvider来解析服务,而不是注入的_serviceProvider实例。 因此从范围中解析的所有服务都将在using语句的末尾自动释放/处置(release/dispose)

    建议做法

    1. 如果要在方法体中解析服务,请始终创建子服务范围以确保正确的释放已解析的服务.

    2. 如果将IServiceProvider作为方法的参数,那么你可以直接从中解析服务而无需关心释放/处置(release/dispose). 创建/管理服务范围是调用方法的代码的责任. 遵循这一原则使你的代码更清晰.

    3. 不要引用解析到的服务,不然它可能会导致内存泄漏或者在你以后使用对象引用时可能访问已处置的(dispose)服务(除非服务是单例)

    单例服务(Singleton Services)

    单例服务通常用于保持应用程序状态. 缓存服务是应用程序状态的一个很好的例子.
    例如:

    public class FileService{    private readonly ConcurrentDictionary<string, byte[]> _cache;    
        public FileService()    {
            _cache = new ConcurrentDictionary<string, byte[]>();
        }    
        public byte[] GetFileContent(string filePath)    {        return _cache.GetOrAdd(filePath, _ =>
            {            return File.ReadAllBytes(filePath);
            });
        }
    }

    FileService缓存文件内容以减少磁盘读取. 此服务应注册为Singleton,否则缓存将无法按预期工作.

    建议做法

    1. 如果服务需要保持状态,则应以线程安全的方式访问该状态.因为所有请求同时使用相同的服务实例.我使用ConcurrentDictionary而不是Dictionary来确保线程安全.

    2. 不要在单例服务中使用Scoped生命周期或Transient生命周期的服务.因为临时服务可能不是设计为线程安全.如果必须使用它们那么在使用这些服务时请注意多线程问题(例如使用锁).

    3. 内存泄漏通常由单例服务引起.它们在应用程序结束前不会被释放/处置(release/dispose). 因此如果他们实例化的类(或注入)但不释放/处置(release/dispose).它们,它们也将留在内存中直到应用程序结束. 确保在正确的时间释放/处置(released/disposed)它们。 请参阅上面的在方法中的解析服务内容.

    4. 如果缓存数据(本示例中的文件内容),则应创建一种机制,以便在原始数据源更改时更新/使缓存的数据无效(当上面示例中磁盘上的缓存文件发生更改时).

    范围服务(Scoped Services)

    Scoped生命周期的服务乍一看似乎是存储每个Web请求数据的良好候选者.因为ASP.NET Core会为每个Web请求创建一个服务范围. 因此,如果你将服务注册为作用域则可以在Web请求期间共享该服务.
    例如:

    public class RequestItemsService{    private readonly Dictionary<string, object> _items;    
        public RequestItemsService()    {
            _items = new Dictionary<string, object>();
        }    
        public void Set(string name, object value)    {
            _items[name] = value;
        }    
        public object Get(string name)    {        return _items[name];
        }
    }

    如果将RequestItemsService注册为Scoped并将其注入两个不同的服务,则可以获取从另一个服务添加的项,因为它们将共享相同的RequestItemsService实例.这就是我们对Scoped生命周期服务的期望.

    但是...事实可能并不总是那样. 如果你创建子服务范围并从子范围解析RequestItemsService,那么你将获得RequestItemsService的新实例,它将无法按预期工作.因此,作用域服务并不总是表示每个Web请求的实例。

    你可能认为你没有犯这样一个明显的错误(在子范围内解析服务). 情况可能不那么简单. 如果你的服务之间存在大的依赖关系,则无法知道是否有人创建了子范围并解析了注入另一个服务的服务.最终注入了作用域服务.

    建议做法

    1. Scoped生命周期的服务可以被认为是在Web请求中由太多服务注入的优化.因此,所有这些服务将在同一Web请求期间使用该服务的单个实例.

    2. Scoped生命周期的服务不需要设计为线程安全的. 因为它们通常应由单个Web请求/线程使用.但是...在这种情况下,你不应该在不同的线程之间共享Scoped生命周期服务!

    3. 如果你设计Scoped生命周期服务以在Web请求中的其他服务之间共享数据,请务必小心(如上所述). 你可以将每个Web请求数据存储在HttpContext中(注入IHttpContextAccessor以访问它),这是更安全的方式. HttpContext的生命周期不是作用域. 实际上它根本没有注册到DI(这就是为什么你不注入它,而是注入IHttpContextAccessor). HttpContextAccessor使用AsyncLocal实现在Web请求期间共享相同的HttpContext.

    结论

    依赖注入起初看起来很简单,但是如果你不遵循一些严格的原则,就会存在潜在的多线程和内存泄漏问题. 我根据自己在ASP.NET Boilerplate框架开发过程中的经验分享了一些很好的原则.

    原文地址:ASP.NET Core Dependency Injection Best Practices, Tips & Tricks


    ,220)/}

    实践,提示,依赖,最佳,注入
    2018-09-30

    177

  • asp.net core 外部认证多站点模式实现
    asp.net core 外部认证多站点模式实现

    PS:之前因为需要扩展了微信和QQ的认证,使得网站是可以使用QQ和微信直接登录。github 传送门 。然后有小伙伴问,能否让这个配置信息(appid, appsecret)按需改变,而不是在 ConfigureServices  里面写好。先上 官方文档 :  https://docs.microsoft.com/zh-cn/aspnet/core/security/authentication/social/?view=aspnetcore-2.1 官方已经实现了 microsft

    实现,模式,认证,站点,外部
    2018-09-30

    452

  • asp.net core 2.1 部署IIS(win10/win7)
    asp.net core 2.1 部署IIS(win10/win7)

    概述与ASP.NET时代不同,ASP.NET Core不再是由IIS工作进程(w3wp.exe)托管,而是使用自托管Web服务器(Kestrel)运行,IIS则是作为反向代理的角色转发请求到Kestrel不同端口的ASP.NET Core程序中,随后就将接收到的请求推送至中间件管道中去,处理完你的请求和相关业务逻辑之后再将HTTP响应数据重新回写到IIS中,最终转达到不同的客户端(浏览器,APP,客户端等)。而配置文件和过程都会由些许调

    部署,
    2018-09-30

    264

  • .NET Core开发日志——配置
    .NET Core开发日志——配置

    熟悉ASP.NET的开发者一定对web.config文件不陌生。在ASP.NET环境中,要想添加配置参数,一般也都会在此文件中操作。其中最常用的莫过于AppSettings与ConnectionStrings两项。而要在代码中获得文件中的配置信息,ConfigurationManager则是必不可少需要引入的程序集。然而到了ASP.NET Core时代,存储与读取配置的方式都发生了改变。如果对ASP.NET Core项目有所了解的话,应该会看到过appsettings.json这个文件。这里就从JSON文件配置方式开始解释ASP.NET Core中是如何读取配置信息的。假设有预先设置的appsettings.json文件:{  "option1": "value1_from_json"quot;option1 = {Configuration["Option1"]}");         Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;option2 = {Configuration["option2"]}");         Console.WriteLine(            

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;suboption1 = {Configuration["subsection:suboption1"]}");         Console.WriteLine();         Console.WriteLine("Wizards:");         Console.Write(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;{Configuration["wizards:0:Name"]}, ");         Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;age {Configuration["wizards:0:Age"]}");         Console.Write(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;{Configuration["wizards:1:Name"]}, ");         Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;age {Configuration["wizards:1:Age"]}");         Console.WriteLine();         Console.WriteLine("Press a key...");         Console.ReadKey();     } }

    首先,实例化一个ConfigurationBuilder对象,接着设置基础路径。

    SetBasePath的操作其实是在ConfigurationBuilder的属性字典里设置FileProvider的值。

    public static IConfigurationBuilder SetBasePath(this IConfigurationBuilder builder, string basePath){
        ...    
        return builder.SetFileProvider(new PhysicalFileProvider(basePath));
    }public static IConfigurationBuilder SetFileProvider(this IConfigurationBuilder builder, IFileProvider fileProvider){
        ...
    
        builder.Properties[FileProviderKey] = fileProvider ?? throw new ArgumentNullException(nameof(fileProvider));    return builder;
    }

    然后是添加JSON文件。

    public static IConfigurationBuilder AddJsonFile(this IConfigurationBuilder builder, IFileProvider provider, string path, bool optional, bool reloadOnChange){
        ...    return builder.AddJsonFile(s =>
        {
            s.FileProvider = provider;
            s.Path = path;
            s.Optional = optional;
            s.ReloadOnChange = reloadOnChange;
            s.ResolveFileProvider();
        });
    }public static IConfigurationBuilder AddJsonFile(this IConfigurationBuilder builder, Action<JsonConfigurationSource> configureSource)    => builder.Add(configureSource);

    ConfigurationBuilder里添加了一个JsonConfigurationSource对象。

    最后,执行ConfigurationBuilder的Build方法,就可以得到保存配置信息的Configuration对象。

    总结例子中的代码,获取配置信息的操作其实就分为两步:

    1. 生成Configuration对象

    2. 按键值从Configuration对象中获取信息

    生成Configuration对象的步骤至少要有三个基础环节。

    1. 生成ConfigurationBuilder对象

    2. 添加ConfigurationSource对象

    3. 创建Configuration对象

    查看创建Configuration对象的代码,会发现内部利用的其实是ConfigurationSource中创建的ConfigurationProvider对象。

    public IConfigurationRoot Build(){    var providers = new List<IConfigurationProvider>();    foreach (var source in Sources)
        {        var provider = source.Build(this);
            providers.Add(provider);
        }    return new ConfigurationRoot(providers);
    }

    再看IConfiguratonSource接口,也只有一个Build方法。

    public interface IConfigurationSource{    IConfigurationProvider Build(IConfigurationBuilder builder);
    }

    最终创建的Configuration对象,即ConfigurationRoot中包含了所有的ConfigurationProvider,说明配置信息都由这些ConfigurationProvider所提供。

    跟踪至ConfigurationRoot类型的构造方法,果然在其生成对象时,对所有ConfigurationProvider进行了加载操作。

    public ConfigurationRoot(IList<IConfigurationProvider> providers){
        ...
    
        _providers = providers;    foreach (var p in providers)
        {
            p.Load();
            ChangeToken.OnChange(() => p.GetReloadToken(), () => RaiseChanged());
        }
    }

    比如JsonConfigurationProvider中:

    public override void Load(Stream stream){    try
        {
            Data = JsonConfigurationFileParser.Parse(stream);
        }
        ...
    }

    通过JSON解析器,将JSON文件的配置信息读取至ConfigurationProvider的Data属性中。这个属性即是用于保存所有配置信息。

      /// <summary>
      /// The configuration key value pairs for this provider.
      /// </summary>
      protected IDictionary<string, string> Data { get; set; }

    有了ConfigurationRoot对象后,获取配置信息的操作就很简单了。遍历各个ConfigurationProvider,从中获取第一个匹配键值的数据。

    public string this[string key]
    {    get
        {        foreach (var provider in _providers.Reverse())
            {            string value;            if (provider.TryGet(key, out value))
                {                return value;
                }
            }        return null;
        }
    
        ...
    }

    ConfigurationProvider对象从Data属性获取配置的值。

    public virtual bool TryGet(string key, out string value)    => Data.TryGetValue(key, out value);

    在最初的例子中可以看Configuration["wizards:0:Name"]这样的写法,这是因为在Load文件时,存储的方式就是用:为分隔符,以作为嵌套对象的键值。

    也可以用另一种方法来写,将配置信息绑定为对象。

    先定义对象类型:

    public class AppSettings{    public string Option1 { get; set; }    public int Option2 { get; set; }    public Subsection Subsection { get; set; }    public IList<Wizards> Wizards { get; set; }
    }public class Subsection{    public string Suboption1 { get; set; }
    }public class Wizards{    public string Name { get; set; }    public string Age { get; set; }
    }

    再绑定对象:

    static void Main(string[] args){    var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json");
    
        Configuration = builder.Build();    var appConfig = new AppSettings();
        Configuration.Bind(appConfig);
    
        Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;option1 = {appConfig.Option1}");     Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;option2 = {appConfig.Option2}");     Console.WriteLine(        

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;suboption1 = {appConfig.Subsection.Suboption1}");     Console.WriteLine();     Console.WriteLine("Wizards:");     Console.Write(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;{appConfig.Wizards[0].Name}, ");     Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;age {appConfig.Wizards[0].Age}");     Console.Write(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;{appConfig.Wizards[1].Name}, ");     Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;age {appConfig.Wizards[1].Age}");     Console.WriteLine();     Console.WriteLine("Press a key...");     Console.ReadKey(); }

    写法变成了常见的对象调用属性方式,但结果是一样的。

    除了可以用JSON文件存储配置信息外,ASP.NET Core同时也支持INI与XML文件。当然有其它类型文件时,也可以通过实现IConfigurationSource接口并继承ConfigurationProvider类建立自定义的ConfigrationProvider对象来加载配置文件。

    至于文件以外的方式,ASP.NET Core也提供了不少。

    • 命令行,AddCommandLine

    • 环境变量,AddEnvironmentVariables

    • 内存, AddInMemoryCollection

    • 用户机密,AddUserSecrets

    • Azure Key Vault,AddAzureKeyVault

    选择何种存储与读取配置的方法取决于实际场景,ASP.NET Core已经开放了配置方面的入口,任何接入方式理论上都是可行的。实践方面,则需要开发者们不断去尝试与探索。


    ,220)/}

    配置,日志,开发,
    2018-09-30

    200

  • .NET Core开发日志——简述路由
    .NET Core开发日志——简述路由

    有过ASP.NET或其它现代Web框架开发经历的开发者对路由这一名字应该不陌生。如果要用一句话解释什么是路由,可以这样形容:通过对URL的解析,指定相应的处理程序。回忆下在Web Forms应用程序中使用路由的方式:public static void RegisterRoutes(RouteCollection routes){     routes.MapPageRoute(""

    日志,开发,简述,路由,
    2018-09-30

    133

  • .NET Core开发日志——Controller
    .NET Core开发日志——Controller

    在理清路由的工作流程后,接下来需要考虑的,是MVC框架如何生成Controller以及它的生成时机。根据以前ASP.NET MVC的经验,Controller应该是由一个ControllerFactory构建的。查看ASP.NET Core MVC的源码,果然是有一个DefaultControllerFactory类,并且不出意外的,它拥有一个CreateController方法。public virtual object CreateController(ControllerContext context){     ...    var controller = _controllerActivator.Create(context);    foreach (var propertyActivator in _propertyActivators)     {         propertyActivator.Activate(context

    日志,开发,
    2018-09-30

    184

  • .NET Core开发日志——Action
    .NET Core开发日志——Action

    在叙述Controller一文中,有一处未做解释,即CreateControllerFactory方法中ControllerActionDescriptor参数是如何产生的。这是因为其与Action的关联性更大,所以放在本文中继续描述。回到MvcRouteHandler或者MvcAttributeRouteHandler的方法中:public Task RouteAsync(RouteContext context){     ...    var candidates = _actionSelector.SelectCandidates(context);    if (candidates == null || candidates.Count == 0)     {         _logger.NoActionsMatched(context.RouteData.Values);        return Task.CompletedTask;     }    var actionDescriptor = _actionSelector.SelectBestCandidate(context

    日志,开发,
    2018-09-30

    124

  • .NET Core开发日志——Model Binding
    .NET Core开发日志——Model Binding

    ASP.NET Core MVC中所提供的Model Binding功能简单但实用,其主要目的是将请求中包含的数据映射到action的方法参数中。这样就避免了开发者像在Web Forms时代那样需要从Request类中手动获取数据的繁锁操作,直接提高了开发效率。此功能继承自ASP.NET MVC,所以熟悉上一代框架开发的工程师,可以毫无障碍地继续享有它的便利。本文想要探索下Model Binding相关的内容,这里先从源码中找到其发生的时机与场合。在ControllerActionInvoker类的Next方法内部,可以看到对BindArgumentsAsync方法的调用,这里即会对方法的参数进行绑定数据的处理。private Task Next(ref State next

    日志,开发,
    2018-09-30

    141

  • .NET Core开发日志——Filter
    .NET Core开发日志——Filter

    ASP.NET Core MVC中的Filter作用是在请求处理管道的某些阶段之前或之后可以运行特定的代码。Filter特性在之前的ASP.NET MVC中已经出现,但过去只有Authorization,Exception,Action,Result四种类型,现在又增加了一种Resource类型。所以共计五种。Resource类型Filter在Authorization类型Filter之后执行,但又在其它类型的Filter之前。且执行顺序也在Model Binding之前,所以可以对Model Binding产生影响。ASP.NET Core MVC框架中可以看到有ConsumesAttribute及FormatFilter两种实现IResourceFilter接口的类。ConsumesAttribute会按请求中的Content-Type(内容类型)进行过滤,而FormatFilter能对路由或路径中设置了format值的请求作过滤。一旦不符合要求,就对ResourceExecutingContext的Result属性设置,这样可以达到短路效果,阻止进行下面的处理。ConsumesAttribute类的例子:public void OnResourceExecuting(ResourceExecutingContext context){     ...    // Only execute if the current filter is the one which is closest to the action.     // Ignore all other filters. This is to ensure we have a overriding behavior.     if (IsApplicable(context.ActionDescriptor))     {        var requestContentType = context.HttpContext.Request.ContentType;        // Confirm the request's content type is more specific than a media type this action supports e.g. OK         // if client sent "text/plain" data and this action supports "text/*".         if (requestContentType != null && !IsSubsetOfAnyContentType(requestContentType))         {             context.Result = new UnsupportedMediaTypeResult();         }     } }Filter在ASP.NET Core MVC里除了保留原有的包含同步方法的接口,现在又增加了包含异步方法的接口。同步IActionFilterIAuthorizationFilterIExceptionFilterIResourceFilterIResultFilter异步IAsyncActionFilterIAsyncAuthorizationFilterIAsyncExceptionFilterIAsyncResourceFilterIAsyncResultFilter新的接口不像旧有的接口包含两个同步方法,它们只有一个异步方法。但可以实现同样的功能。public class SampleAsyncActionFilter : IAsyncActionFilter{    public async Task OnActionExecutionAsync(         ActionExecutingContext context

    日志,开发,
    2018-09-30

    204

  • 你需要知道的这几种 asp.net core 修改默认端口的方式
    你需要知道的这几种 asp.net core 修改默认端口的方式

    一般情况下,aspnetcore发布后的默认端口是5000,这个大家都知道,而且默认骨架代码中没有看到任何让你输入的ip地址和端口号,但作为程序员的我们,不希望被框架所管制,那如何实现默认端口的修改呢? 骨架代码:    public class Program     {        public static void Main(string[] args)         {             CreateWebHostBuilder(args).Build().Run();         }        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>             WebHost.CreateDefaultBuilder(args)                 .UseStartup<Startup>();     } 发布如下: 一:解决办法1(UseUrls)       骨架代码就那么几行,很容易在这个IWebHostBuilder中找到一个叫做UseUrls的方法,从注解中可以看得出来让WebHost监听指定的端口号,截图如下: 那么答案就出来了,你需要自己来指定一下端口,改完之后截图如下:    public class Program     {        public static void Main(string[] args)         {             CreateWebHostBuilder(args).Build().Run();         }        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>             WebHost.CreateDefaultBuilder(args)                   .UseUrls("http://*:8080")                 .UseStartup<Startup>();     }  但是在发布之后,你突然发现,卧槽,端口冲突了,我想换端口,tmd我还得为此再发一次程序,一个字麻烦,说一送一。差点被砍到的第一反应就是把硬编码送到配置文件中。 二:解决办法2 (host.json)       你会突然发现要使用到的Configuration属性只能在Startup类中,毕竟在WebHost的Build之前ServiceCollection都没有初始化,哪里有统一化的配置系统呢, 那怎么办,还能怎么办,自己定义一个Configuration了,然后修改的步骤如下: 1. 新增一个host.json,名字随便定义,自己看得懂就行啦。{    "url": "http://*:9099"} 2. webhost代码修改         public static IWebHostBuilder CreateWebHostBuilder(string[] args)         {            var configuration = new ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory)                                           .AddJsonFile("host.json")                                           .Build();            var url = configuration["url"];            return WebHost.CreateDefaultBuilder(args).UseUrls(configuration["url"])                                                      .UseStartup<Startup>();         }         问题倒是解决了,但是总发现有一点不爽,突然新来的Configration就好像半路杀出的陈咬金,所以说如果将陈咬金收编过来就完美了。 三:不够优雅后的整合      接下来你很容易会在WebHostBuilder中发现另一个方法UseConfiguration,看参数就是用来接收ConfigurationRoot的,所以就把代码修改如下:        public static IWebHostBuilder CreateWebHostBuilder(string[] args)         {            var configuration = new ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory)                                           .AddJsonFile("host.json")                                           .Build();            //var url = configuration["url"];             return WebHost.CreateDefaultBuilder(args).UseConfiguration(configuration)                                                      .UseStartup<Startup>();         }         但是这里有一个问题,asp.netcore能识别我自定义的url吗?肯定是不能识别的啦,那问题就是,AspnetCore模式会用哪一个key作为url的地址呢??要找到答案的话得需要从源码上啦,从UseUrls入手吧。 从上面可以看到,UseUrls默认是使用 WebHostDefaults.ServerUrlsKey 作为url的key的,然后继续F12看一下它的 内容是什么?     好了,真想大白了,原来是urls,接下来我只需要把host.json 的url改成urls就可以了,对吧。 {    "urls": "http://*:9099"} 四:解决办法3 (使用docker)      如果你不想做出任何改变,不想做任何退步,那没办法,只能把你关进docker里啦。 1. dockerfileFROM microsoft/dotnet:2.1-aspnetcore-runtimeMAINTAINER hxc@qq.comRUN mkdir /dataCOPY ./publish/ /dataWORKDIR /dataCMD [ "dotnet"

    默认,知道,修改,需要,方式
    2018-09-30

    864

  • netcore服务程序暴力退出导致的业务数据不一致的一种解决方案(优雅退出)
    netcore服务程序暴力退出导致的业务数据不一致的一种解决方案(优雅退出)

    [ERR:(RemoveHtmlTag)标签缺少参数]quot;{DateTime.Now}: 1. 获取mysql"); 8                 System.Threading.Thread.Sleep(2000); 9                 Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;{DateTime.Now}: 2. 获取redis");10                 System.Threading.Thread.Sleep(2000);11                 Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;{DateTime.Now}: 3. 更新monogdb");12                 System.Threading.Thread.Sleep(2000);13                 Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;{DateTime.Now}: 4. 通知kafka");14                 System.Threading.Thread.Sleep(2000);15                 Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;{DateTime.Now}: 5. 所有业务处理完毕");16                 System.Threading.Thread.Sleep(2000);17             }18         }19     }

    复制代码

     

    2. Main程序

    1         public static void Main(string[] args)2         {3             var bgtask = Task.Run(() => { TestService.Run(); });4 5             bgtask.Wait();6         }

     

          这里不考虑程序的健壮性,只表达这里可能出现的问题,当程序退出后,这里必然会遇到TestService.Run方法出现未执行完的情况,导致数据不一致,比如下

    面我简单的部署了一下,可以看到程序到了 5:03:24s之后就结束了,显然破坏了业务逻辑。程序没有完整的执行结束,那问题该怎么解决呢?

    复制代码

    [root@localhost netcore]# nohup dotnet ConsoleApp4.dll &
    [1] 4101[root@localhost netcore]# nohup: ignoring input and appending output to ‘nohup.out’
    
    [root@localhost netcore]# ps -ef | grep dotnet
    root       4101   2865  0 17:03 pts/0    00:00:00 dotnet ConsoleApp4.dll
    root       4118   2865  0 17:03 pts/0    00:00:00 grep --color=auto dotnet
    [root@localhost netcore]# kill 4101[root@localhost netcore]# tail nohup.out9/2/18 5:03:06 PM: 2. 获取redis9/2/18 5:03:08 PM: 3. 更新monogdb9/2/18 5:03:10 PM: 4. 通知kafka9/2/18 5:03:12 PM: 5. 所有业务处理完毕9/2/18 5:03:14 PM: 1. 获取mysql9/2/18 5:03:16 PM: 2. 获取redis9/2/18 5:03:18 PM: 3. 更新monogdb9/2/18 5:03:20 PM: 4. 通知kafka9/2/18 5:03:22 PM: 5. 所有业务处理完毕9/2/18 5:03:24 PM: 1. 获取mysql
    [1]+  Done                    nohup dotnet ConsoleApp4.dll
    [root@localhost netcore]#

    复制代码

        

    二:思考 kill 命令

      要解决这个问题,大家一定要从kill命令入手, 在centos上进行kill  -x pid 的时候,不知道有多少人了解了这个命令,除了常见的 kill -9 pid ,其实还有很多其

    他的数字,则代表其他的意思,可以通过kill -l 看一下。

    复制代码

     1 [root@localhost ~]# kill -l 2  1) SIGHUP     2) SIGINT     3) SIGQUIT     4) SIGILL     5) SIGTRAP 3  6) SIGABRT     7) SIGBUS     8) SIGFPE     9) SIGKILL    10) SIGUSR1 4 11) SIGSEGV    12) SIGUSR2    13) SIGPIPE    14) SIGALRM    15) SIGTERM 5 16) SIGSTKFLT    17) SIGCHLD    18) SIGCONT    19) SIGSTOP    20) SIGTSTP 6 21) SIGTTIN    22) SIGTTOU    23) SIGURG    24) SIGXCPU    25) SIGXFSZ 7 26) SIGVTALRM    27) SIGPROF    28) SIGWINCH    29) SIGIO    30) SIGPWR 8 31) SIGSYS    34) SIGRTMIN    35) SIGRTMIN+1    36) SIGRTMIN+2    37) SIGRTMIN+3 9 38) SIGRTMIN+4    39) SIGRTMIN+5    40) SIGRTMIN+6    41) SIGRTMIN+7    42) SIGRTMIN+810 43) SIGRTMIN+9    44) SIGRTMIN+10    45) SIGRTMIN+11    46) SIGRTMIN+12    47) SIGRTMIN+1311 48) SIGRTMIN+14    49) SIGRTMIN+15    50) SIGRTMAX-14    51) SIGRTMAX-13    52) SIGRTMAX-1212 53) SIGRTMAX-11    54) SIGRTMAX-10    55) SIGRTMAX-9    56) SIGRTMAX-8    57) SIGRTMAX-713 58) SIGRTMAX-6    59) SIGRTMAX-5    60) SIGRTMAX-4    61) SIGRTMAX-3    62) SIGRTMAX-214 63) SIGRTMAX-1    64) SIGRTMAX

    复制代码

     

     其中里面的

    2.   SIGNIT  (Ctrl+C)

    3.   SIGQUIT (退出)

    9.   SIGKILL   (强制终止)

    15. SIGTERM (终止)

     

    都可以让程序退出,好了,线索出来了,那我能不能让程序捕获到kill命令发出的这Sigxxx信号呢??? 通过寻找资料之后的一阵浑身痉挛,你明白了原来只有

    -9是不能让程序捕获到,其他的程序都能捕获,那么既然能捕获,我就可以在捕获的事件中做程序的安全退出。 大概的脑图就像下面这样:

     

    三:研究如何捕获

       

             在core 2.0之后,获取sigterm就非常简单了,可以在当前应用程序域中挂载一个ProcessExit 事件,在ProcessExit中让应用程序安全的退出。

     

    然后还有一个问题就是,如何在ProcessExit中通知TestService结束执行呢? 这里就用到了CancellationTokenSource 这种线程安全的取消协调机制,思考之后

    画出来的脑图大概是这个样子,不一定对,但是逻辑大概出来了。。。

     

    四: 问题解决

        有了上面的脑图,写起代码就快啦~~~

     

    1. Main函数

    复制代码

     1         public static void Main(string[] args) 2         { 3             var cts = new CancellationTokenSource(); 4  5             var bgtask = Task.Run(() => { TestService.Run(cts.Token); }); 6  7             AppDomain.CurrentDomain.ProcessExit += (s, e) => 8             { 9                 Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;{DateTime.Now} 后台测试服务,准备进行资源清理!");10 11                 cts.Cancel();    //设置IsCancellationRequested=true,让TestService今早结束 12                 bgtask.Wait();   //等待 testService 结束执行13 14                 Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;{DateTime.Now} 恭喜,Test服务程序已正常退出!");15 16                 Environment.Exit(0);17             };18 19             Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;{DateTime.Now} 后端服务程序正常启动!");20 21             bgtask.Wait();22         }

    复制代码

     

       Main函数中做了如上的变更,将CancellationToken传递给 Run方法,这样当我执行Cancel的时候,Run方法就能感知到Token的变化,然后就是调用Wait等待

    TestService执行结束。

     

    2. TestService

    复制代码

     1     public class TestService 2     { 3         public static void Run(CancellationToken token) 4         { 5             while (true) 6             { 7                 if (token.IsCancellationRequested) break; 8  9                 Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;{DateTime.Now}: 1. 获取mysql");10                 System.Threading.Thread.Sleep(2000);11                 Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;{DateTime.Now}: 2. 获取redis");12                 System.Threading.Thread.Sleep(2000);13                 Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;{DateTime.Now}: 3. 更新monogdb");14                 System.Threading.Thread.Sleep(2000);15                 Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;{DateTime.Now}: 4. 通知kafka");16                 System.Threading.Thread.Sleep(2000);17                 Console.WriteLine(

    1.1. 名词解释

    内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。

    用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

    1.2. Kestrel基本工作原理

    Kestrel是进程内服务器,以一个包形式提供,自身不能单独运行,必须HOST在一个.NET的WEB应用程序中。它内部封装了对libuv的调用,但不是libuv库简单的封装库。Kestrel是个精简的,高效的Http Server。

    1.2.1. Kestrel的基本架构

    Kestrel遵循以下架构原则:

    • libuv中使用单线程的事件循环模型。

    • Kestrel支持多事件循环以支持更多的I/O。

    • Kestrel仅在libuv的事件循环中做I/O工作。

    • 所有非I/O工作,包括HTTP解析,请求帧处理等等都在标准的托管线程中进行。

    • 更少的系统调用。

    对应的架构图如下:

    2017-09-13-23-07-16

    • Libuv

      作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

    • I/O事件队列

      对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

    • Kestrel线程

      事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

    • 非托管内存池

      这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

    • TCP监听器

      这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

    • 连接管理

      负责异步结束连接对象。

    • HTTP协议模块

      该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

    更为详细的结构视图如下:

    2017-09-13-23-23-55

    1.2.2. Kestrel的工作原理

    1.2.2.1. 处理Request和Response

    2017-09-14-21-21-30

    按照请求流转方向会有以下处理过程:

    1. 请求进入libuv

    将请求事件放入事件队列,随后的事件循环中,监听器回调函数执行。

    2. 监听器创建连接

    根据请求信息创建一个连接对象,此时Http帧工厂被调用,产生一个Http帧对象;用于读取Request的SocketInput、用于返回Response的SocketOutput对象被创建,二者会被Http帧使用。

    3. 连接管理监控连接

    连接管理器跟踪连接的状态,收集待关闭连接,然后异步关闭。

    4. Http帧处理

    一个Http负责构建Http上下文的Request对象和Response对象。读取Request数据和返回Response数据都要经过内存池。高效的内存读写和与和Libuv的读写事件协调,确保Request数据到达就能读到内存池,到达内存池就能及时被读;Response数据写入内存池就能被套接字及时发出去,体现了Kestreld强大的异步处理能力。

    1.2.2.2. 内存池读写

    读取内存池数据时可读取后续到达的数据,不需要重新等待事件,此时对应读取Request数据情形:

    2017-09-14-23-42-10

    写数据到内存池时,libuv连续读出并发送数据,也不需要重新等待时间,此时对应发送Response数据情形:

    2017-09-14-23-42-58

    1.2.2.3. Libuv线程和托管线程通信

    二者的通信机制保证Libuv线程永远不会被阻塞:比如libuv线程在通知事件时会很小心尝试获取队线程私有锁,如果成功获取就这在事件队列线程上异步处理,否则这一通信过程在线程池里重复执行直到成功,如图:

    2017-09-14-23-28-33

    1.3. Http.sys基本工作原理

    1.3.1. Http.sys基本构成

    2017-09-10-12-25-14

    1. 监听器

    监听TCP请求,允许端口共享。TCP携带的HTTP报文会被Http Parser解析,名称映射首先会根据url确定对应的web app,然后把请求放入该app的消息队列中。

    2. 消息队列

    Http.sys给每个注册的web app一个消息队列。

    3. 响应缓存

    请求的静态资源和GET请求会缓存起来一段时间,如果请求url能匹配这直接返回缓存数据。

    4. 响应模块

    将数据返回给用户代理,如果返回的是可以缓存的资源,则会放入响应缓存中。

    1.3.2. Http.sys工作原理

    下图表示在ASP.NET Core应用中接受一个http请求到返回数据的过程:

    2017-09-10-11-29-05

    1. 这里的TCPIP.sys也是windows内核驱动,提供了TCPIP协议栈。

    2. Http.sys的处理如在“基本构成”做所述。

    3. ASP.NET Core应用程序里面HttpSys模块代表了Http.sys,它与应用程序代码交流,交流的载体是HTTP上下文。

    1.3.3. 总结

    Kestrel服务器运行在Asp.net core应用程序中,能高效的处理网络请求,且跨平台。Http.sys运行在内核态中,极大减少了系统调用次数,运行效率很高;自带生存环境的安全,鲁棒性等特点;它也可以作为反向代理,因此它的功能更加强大,主要问题是只能运行在windows下。Kestrel应用在生产环境中需要运行在代理服务器后面,以获取安全性,负载均衡等能力。

    功能Http.sysKerstrel
    平台支持WindowsWindows/Linux/Mac
    静态文件YesYes
    HTTP访问日志YesNo
    端口共享/多应用程序YesNo
    SSL证书YesInternal*
    Windows 授权YesNo
    过滤请求&限制YesNo
    IP&域名约束YesNo
    HTTP重定向规则YesNo
    WebSocket 协议YesMiddleware
    缓存ResponseYesNo
    压缩YesYes
    FTP服务器YesNo
    运行态内核态用户态

    * Internal:https通信仅仅工作在反向代理服务器后面与ASP.NET程序之间,如果要想外暴露https服务这需要用到反向代理,比如IIS,nginx,apached。

    参考文章

    http://www.cnblogs.com/yxmx/articles/1652128.html

    http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html

    https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/


    quot;{DateTime.Now}: 5. 所有业务处理完毕");18                 System.Threading.Thread.Sleep(2000);19             }20         }21     }

    复制代码

        

          TestService的while循环里面,在周期轮训的开头,加上一个IsCancellationRequested的判断,如果Cancel()方法被调用,IsCancellationRequested就会变

    成true,从而让本方法感知到外界让我结束,所以本逻辑就不再进行下一个周期了,从而保证业务逻辑的完整。

     

    五:部署

     

          为了更好的表达效果,我加了很多的日志,还是采用nohup的模式来观察一下程序的流转过程。

    复制代码

     1 [root@localhost netcore]# nohup dotnet ConsoleApp1.dll & 2 [2] 4487 3 [root@localhost netcore]# nohup: ignoring input and appending output to ‘nohup.out’ 4  5 [root@localhost netcore]# ps -ef | grep dotnet 6 root       4487   2865  1 17:11 pts/0    00:00:00 dotnet ConsoleApp1.dll 7 root       4496   2865  0 17:11 pts/0    00:00:00 grep --color=auto dotnet 8 [1]-  Done                    nohup dotnet ConsoleApp1.dll 9 [root@localhost netcore]# kill 448710 [root@localhost netcore]# tail -100 nohup.out11 9/2/18 5:11:17 PM: 1. 获取mysql12 9/2/18 5:11:17 PM 后端服务程序正常启动!13 9/2/18 5:11:19 PM: 2. 获取redis14 9/2/18 5:11:21 PM: 3. 更新monogdb15 9/2/18 5:11:23 PM: 4. 通知kafka16 9/2/18 5:11:25 PM: 5. 所有业务处理完毕17 9/2/18 5:11:27 PM: 1. 获取mysql18 9/2/18 5:11:29 PM: 2. 获取redis19 9/2/18 5:11:31 PM: 3. 更新monogdb20 9/2/18 5:11:33 PM: 4. 通知kafka21 9/2/18 5:11:35 PM: 5. 所有业务处理完毕22 9/2/18 5:11:37 PM: 1. 获取mysql23 9/2/18 5:11:39 PM: 2. 获取redis24 9/2/18 5:11:41 PM: 3. 更新monogdb25 9/2/18 5:11:43 PM: 4. 通知kafka26 9/2/18 5:11:45 PM: 5. 所有业务处理完毕27 9/2/18 5:11:47 PM: 1. 获取mysql28 9/2/18 5:11:49 PM: 2. 获取redis29 9/2/18 5:11:50 PM 后台测试服务,准备进行资源清理!30 9/2/18 5:11:51 PM: 3. 更新monogdb31 9/2/18 5:11:53 PM: 4. 通知kafka32 9/2/18 5:11:55 PM: 5. 所有业务处理完毕33 9/2/18 5:11:57 PM 恭喜,Test服务程序已正常退出!

    复制代码

     

        大家可以清楚的看到,5:11:49 收到了system给过来的kill通知,但是程序还是等到了5:11:57才真正的结束自己,这样是不是就保证了业务流程免遭破坏呢?

    好了,本篇就说到这里,希望对你有帮助。


    ,220)/}

    数据,退出,一致,优雅,业务
    2018-09-30

    188