我正在努力深入了解IIS的工作原理.
我理解的http.sys是其主要组成部分之一.但是,我一直无法找到容易消化的信息.在听说WSK之前,我无法获得良好的心理模型,然后我认为这一切都已落实到位.
从大量随机谷歌搜索一点点实验,这是我目前对其存在的原因及其如何实现的高层次理解.
为什么:
端口共享和更高性能的缓存.
怎么样:
用户模式进程使用WinSock api打开侦听端口的套接字以访问网络子系统,例如tcp/ip.像http.sys驱动程序这样的Kernal模式软件使用Winsock Kernal套接字(WSK)API来使用与WinSock api相同的TCP端口号池来实现相同的目的.
IIS,Web服务或任何想要使用http的内容都使用唯一的URL /端口组合向http.sys注册.http.sys使用WSK在此端口上打开一个套接字(如果它还没有用于具有相同端口的另一个url/port组合)并监听.
当传输层(tcpip.sys)重新构建一个ip数据包负载回到客户端发送的http请求时,它会通过请求中的端口将其提供给http.sys.Http.sys使用url/port编号向它发送适当的进程,然后解析它.
我知道好像我正在回答我自己的问题,但我真的不确定自己这个并且想要一些关闭,所以我可以继续处理更多有趣的事情.
我接近了吗?
当使用HTTP的WCF绑定,我需要授予自己特殊的权限,以便能够绑定到该端口/路径.我理解这是因为WCF通过http.sys驱动程序接受HTTP流量.
在古时,我们可以新的插座,并绑定到任何老港,这是不使用的,没有被管理员.NetTcpBinding仍然能够做到这一点.
如果我不关心http.sys,有没有办法告诉WCF不要使用它,而只是在仍然使用HTTP绑定时打开一个普通的旧套接字?
我目前正在阅读很多关于node.js.的内容.使用传统线程每个请求模型(Apache)的服务器与使用事件循环(Nginx,节点,Tornado)的服务器之间经常进行比较.
我想详细了解如何在ASP.NET中处理请求 - 从http.sys中一直收到它直到在ASP.NET本身处理它.我发现http.sys和IIS上的MSDN文档有点缺乏,但也许我的google-fu今天很弱.到目前为止,我找到的最好的资源是Thomas Marquardt博客上的帖子.
任何人都可以对这个话题有更多的了解,或者指出任何其他资源?
(出于这个问题的目的,我只对具有典型集成管道的IIS7感兴趣)
我正在构建一个工具,可以从一台服务器向另一台服务器传输非常大的流数据集(可能在单个流中的数量级为TB,通常为几十千兆字节).该工具的客户端部分将从源磁盘读取块,并通过网络发送它们.服务器端将从网络中读取这些块并将其写入服务器磁盘上的文件.
现在我正在尝试决定使用哪种传输方式.选项是原始TCP和HTTP.
我真的,真的希望能够使用HTTP.HttpListener(或WCF,如果我想去那条路线)可以很容易地插入HTTP Server API(http.sys),我可以免费获得身份验证和SSL之类的东西.现在的问题是表现.
我编写了一个简单的测试工具,使用BeginWrite/EndWrite异步I/O惯用法,在服务器端使用异步BeginRead/EndRead发送128K块空字节.我已经修改了这个测试工具,所以我可以通过HttpWebRequest
/ 使用HTTP PUT操作HttpListener
,或使用TcpClient
/进行普通的旧套接字写操作TcpListener
.要排除网卡或网络路径的问题,客户端和服务器都在一台计算机上并通过localhost进行通信.
在我的12核Windows 2008 R2测试服务器上,此测试工具的TCP版本可以以450MB/s的速度推送字节,并且CPU使用率最低.在同一个盒子上,测试工具的HTTP版本在130MB/s和200MB/s之间运行,具体取决于我如何调整它.
在这两种情况下,CPU使用率都很低,并且CPU使用的绝大部分是内核时间,所以我很确定我对C#和.NET运行时的使用不是瓶颈.这个盒子有两个6核Xeon X5650处理器,24GB单排DDR3内存,我自己专门用于自己的性能测试.
我已经知道HTTP客户端的调整一样ServicePointManager.MaxServicePointIdleTime
,ServicePointManager.DefaultConnectionLimit
,ServicePointManager.Expect100Continue
,和HttpWebRequest.AllowWriteStreamBuffering
.
有没有人对如何使HTTP.sys性能超过200MB/s有任何想法?有没有人看到它在任何环境下表现都很好?
更新:
下面是关于我与看到的表现更多的细节TcpListener
VS HttpListener
:
首先,我写了一个TcpClient/TcpListener测试.在我的测试盒上,能够推动450MB/s.
然后使用反射器我想出了如何获取HttpWebRequest底层的原始Socket对象,并修改了我的HTTP客户端测试以使用它.仍然没有快乐; 差不多200MB/s.
我目前的理论是http.sys针对典型的IIS用例进行了优化,这是一个很多并发的小请求,以及大量并发和可能很大的响应.我假设为了实现这种优化,MSFT必须以牺牲我正在努力实现的目标为代价,这是一个非常大的请求的非常高的吞吐量,响应非常小.
为了它的价值,我还尝试了多达32个并发HTTP PUT操作,看它是否可以扩展,但仍然没有乐趣; 大约200MB/s.
有趣的是,在我的开发工作站上,运行64位Windows 7的四核Xeon Precision T7400,我的TcpClient实现大约200MB/s,HTTP版本也大约200MB/s.一旦我将它带到运行Server 2008 R2的高端服务器级机器,TcpClient代码就会达到450MB/s,而HTTP.sys代码则保持在200左右.
在这一点上,我遗憾地得出结论,HTTP.sys不是我需要完成的工作的正确工具,并且将不得不继续使用我们一直使用的手动插槽协议.
在Windows 10上进行测试时,我们看到许多浏览器不兼容,这是我以前在Windows版本中没有见到的.有些浏览器可以使用,但其他浏览器会报告ERR_SPDY_PROTOCOL_ERROR.我对这个问题的快速搜索表明我并不孤单.
我的应用程序使用WWSAPI和HTTP.SYS与HTTPS(TLS).有谁知道如何在Windows 10上的WWSAPI(使用HTTP.SYS)中禁用SPDY/HTTP/2?
我还想获得HTTP.SYS的最新Windows 10注册表设置列表.
请参阅下面的我对此的回答.希望这也有助于其他人.
标记
内核模式缓存和用户模式缓存之间有什么区别以及如何跟踪它们?
我正在构建一个Web服务器并尝试测试.服务器正在运行localhost:888
,第一次加载Web应用程序时,一切正常.但是如果我尝试重新加载页面,那么一堆XmlHttpRequest
请求就会失败net::ERR_FAILED
.通过在服务器代码中放置断点,我可以验证请求是否实际上从未进入.
这不是连接失败,因为连接第一次成功.它成功一次然后失败的事实意味着它可能与缓存相关,但服务器代码中没有设置cache-control
头的任何内容.所以我通过将服务器放在实际的Web服务器上来测试它.第一次,一切都要花时间加载; 第二次,它立即加载,所以这肯定是缓存相关的
这是一个运行在http.sys
(没有IIS)之上的自定义服务器,看起来默认情况下会缓存一些内容,然后在后续运行时无法从中加载,但只有当我的服务器在localhost上运行时才会运行.在网上,它工作正常.就像我所知道的那样,net::ERR_FAILED
Chrome中有一个通用的"出错了,我们没有任何有用的信息",所以我有点卡在这里.有谁知道是什么原因引起的?
我只需要创建一个非常基本的Web服务器,基本上允许我访问http://1.2.3.4:8080并浏览C:\ web或其他文件列表.
我发现这个http://mikehadlow.blogspot.com/2006/07/playing-with-httpsys.html看起来很完美,但我遇到了几个问题.
1)当我用文件中的*或+替换IP时,我在system.dll中获得访问被拒绝的错误.当我使用localhost或我的本地IP时,它工作正常.为什么是这样?我希望能够将它绑定到具有多个计算机的特定IP地址.
2)我可能遗漏了一些东西,但是你如何指定它使用这段代码服务的文件的核心目录?
我有一个自托管的WCF服务侦听端口80.当我尝试连接到它时,我得到了一个503 Service Unavailable
.
我的WCF进程正在运行,IIS正在运行.我的URL ACL是正确的.控制永远不会到达我的WCF流程.
WCF跟踪只显示:
Listen at 'http://localhost/Foo/Bar/'.
Run Code Online (Sandbox Code Playgroud)
" 失败请求跟踪 "中未显示任何内容,该信息已正确启用 - 将显示其他跟踪.该503 Service Unavailable
消息是坚决平原,这意味着它从内核模式的到来,而不是用户模式.
我打开了HTTP.SYS跟踪,这表明命名空间是正确保留的:
Attempted to add URL (http://localhost:80/Foo/Bar/) to URL
group (0xFD0000014000002E). Status: 0x0.
Run Code Online (Sandbox Code Playgroud)
但后来,在同样的痕迹中,我看到:
Request (request ID 0xF600000580000006) rejected
due to reason: UrlGroupLookupFailed.
Run Code Online (Sandbox Code Playgroud)
我尝试iisreset
了几次,但没有用.我也重新启动了PC; 同样的问题.
出了什么问题?我还能做些什么来进一步调试这个问题?
如果我重命名URL(例如,将"Foo"更改为"Fizz"),那么它可以正常工作.在某处看起来像是损坏的配置.
我有其他服务托管在同一个进程中https://localhost/Foo/Bar/
,并且它们似乎正常工作.
我在自托管的Nancy服务中遇到了同样的问题,下面的一位评论者用自托管的ServiceStack服务报告了同样的事情.