http知识

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
套接字,进程间通信IPC的一种实现,允许位于不同主机(或同一主机)上不同进程之间进行通信和数据交换.
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,
它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
 
 
静态文件:无需服务端做出额外处理, 文件后缀:.html, .txt, .jpg, .js, .css, .mp3, .avi
动态文件:服务端执行程序,返回执行的结果, 文件后缀:.php, .jsp ,.asp
 
 
MIME: Multipurpose Internet Mail Extensions 多用途互联网邮件扩展
    格式:text/plain 、text/html 、text/css、image/jpeg 、image/png、video/mp4  ,在/etc/mime.types(yum install mailcap)
  
串行和并行连接
    串行连接:多个事务多个请求和响应。
    并行连接:多个事务一个请求和响应。(持久连接)
 
提高HTTP连接性能
    并行连接:通过多条TCP连接发起并发的HTTP请求
    持久连接:keep-alive,长连接,重用TCP连接,以消除连接和关闭的时延,以事务个数和时间来决定是否关闭连接
    管道化连接:通过共享TCP连接发起并发的HTTP请求
    复用的连接:交替传送请求和响应报文(实验阶段)
 
KeepAlive的含义  
    KeepAlive配置的含义:对于HTTP/1.1的客户端来说,将会尽量的保持客户的HTTP连接,通过一个连接传送多份HTTP请求响应。
    这样对于客户端来说,可以提高50%左右的响应时间,而于服务器端来说则降低了更多个连接的开销。不过这个依赖于客户端是否想保持连接。
    IE默认是保持连接的,当你打开100个图片的网站时,IE有可能只打开2个连接,通过这两个连接传送数据,而不是开100个连接。
    KeepAliveTimeout 为持久连接保持的时间,也就是说,在这此连接结束后开始计时,多长时间内没有重新发送HTTP请求,就断掉连接。默认设置为5秒,这个值可以大点,但不能太大,否则会出现同时等候过多连接,导致多的内存被占用。
    如何谋求网络带宽与服务器资源之间的平衡。这个要根据具体情况,具体分析。
    那么我们考虑3种情况:
      1。用户浏览一个网页时,除了网页本身外,还引用了多个 javascript 文件,多个 css 文件,多个图片文件,并且这些文件都在同一个 HTTP 服务器上。
      2。用户浏览一个网页时,除了网页本身外,还引用一个 javascript 文件,一个图片文件。
      3。用户浏览的是一个动态网页,由程序即时生成内容,并且不引用其他内容。
  对于上面3中情况,我认为:1 最适合打开 KeepAlive ,2 随意,3 最适合关闭 KeepAlive
 
HTTP协议
 
    http/0.9:1991,原型版本,功能简陋,只有一个命令GET。GET /index.html ,服务器只能回应HTML格式字符串,不能回应别的格式
 
    http/1.0: 1996年5月,支持cache, MIME, method
    每个TCP连接只能发送一个请求,发送数据完毕,连接就关闭,如果还要请求其他资源,就必须再新建一个连接
    引入了POST命令和HEAD命令
    头信息是 ASCII 码,后面数据可为任何格式。服务器回应时会告诉客户端,数据是什么格式,即Content-Type字段的作用。这些数据类型总称为MIME 多用途互联网邮件扩展,
    每个值包括一级类型和二级类型,预定义的类型,也可自定义类型, 常见Content-Type值:text/xml image/jpeg audio/mp3
 
http/1.1:1997年1月 
    引入了持久连接(persistent connection),即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive。对于同一个域名,大多数浏览器允许同时建立6个持久连接
    引入了管道机制(pipelining),即在同一个TCP连接里,客户端可以同时发送多个请求,进一步改进了HTTP协议的效率
    新增方法:PUT、PATCH、OPTIONS、DELETE
    同一个TCP连接里,所有的数据通信是按次序进行的。服务器只能顺序处理回应,前面的回应慢,会有许多请求排队,造成"队头堵塞"(Head-of-line blocking) 
    为避免上述问题,两种方法:一是减少请求数,二是同时多开持久连接。网页优化技巧,如合并脚本和样式表、将图片嵌入CSS代码、域名分片(domain sharding)等
    HTTP 协议不带有状态,每次请求都必须附上所有信息。请求的很多字段都是重复的,浪费带宽,影响速度
 
HTTP1.0和HTTP1.1的区别
    缓存处理,在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,
If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略
    带宽优化及网络连接的使用,HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在
请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),方便了开发者自由的选择以便于充分利用带宽和连接
    错误通知的管理,在HTTP1.1中新增24个状态响应码,如409(Conflict)表示请求的资源与资源当前状态冲突;410(Gone)表示服务器上的某个资源被永久性的删除
    Host头处理,在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),
并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request) 
    长连接,HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,
在HTTP1.1中默认开启Connection: keep-alive,弥补了HTTP1.0每次请求都要创建连接的缺点
 
HTTP1.0和1.1现存的问题
    HTTP1.x在传输数据时,每次都需要重新建立连接,无疑增加了大量的延迟时间,特别是在移动端更为突出
  HTTP1.x在传输数据时,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份,无法保证数据的安全性
  HTTP1.x在使用时,header里携带的内容过大,增加了传输的成本,并且每次请求header基本不怎么变化,尤其在移动端增加用户流量
 虽然HTTP1.x支持了keep-alive,来弥补多次创建连接产生的延迟,但是keepalive使用多了同样会给服务端带来大量的性能压力,并且对于单个文件被不断请求的服务(例如图片存放网站),
keep-alive可能会极大的影响性能,因为它在文件被请求之后还保持了不必要的连接很长时间
 
 
 
SPDY
SPDY:2009年,谷歌研发,综合HTTPS和HTTP两者有点于一体的传输协议,主要特点:
    降低延迟,针对HTTP高延迟的问题,SPDY优雅的采取了多路复用(multiplexing)。多路复用通过多个请求stream共享一个tcp连接的方式,解决了HOL blocking的问题,降低了延迟同时提高了带宽的利用率
  请求优先级(request prioritization)。多路复用带来一个新的问题是,在连接共享的基础之上有可能会导致关键请求被阻塞。SPDY允许给每个request设置优先级,重要的请求就会优先得到响应。比如浏览器加载首页,
首页的html内容应该优先展示,之后才是各种静态资源文件,脚本文件等加载,可以保证用户能第一时间看到网页内容
 header压缩。HTTP1.x的header很多时候都是重复多余的。选择合适的压缩算法可以减小包的大小和数量
 基于HTTPS的加密协议传输,大大提高了传输数据的可靠性
 服务端推送(server push),采用了SPDY的网页,例如网页有一个sytle.css的请求,在客户端收到sytle.css数据的同时,服务端会将sytle.js的文件推送给客户端,当客户端再次尝试获取sytle.js时就可以直接从缓存中获取到,不用再发请求了
 
 
http/2.0:2015年 
    HTTP2.0是SPDY的升级版
  头信息和数据体都是二进制,称为头信息帧和数据帧
  复用TCP连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,且不用按顺序一一对应,避免了“队头堵塞“,此双向的实时通信称为多工(Multiplexing) 
    引入头信息压缩机制(header compression),头信息使用gzip或compress压缩后再发送;客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,不发送同样字段,只发送索引号,提高速度
  HTTP/2 允许服务器未经请求,主动向客户端发送资源,即服务器推送(server push) 
HTTP2.0和SPDY区别:
  HTTP2.0 支持明文 HTTP 传输,而 SPDY 强制使用 HTTPS
  HTTP2.0 消息头的压缩算法采用 HPACK,而非 SPDY 采用的 DEFLATE
 
 
 
 
URI: Uniform Resource Identifier 统一资源标识,分为URL和URN
 URN: Uniform Resource Naming,统一资源命名    示例: P2P下载使用的磁力链接是URN的一种实现
 URL: Uniform Resorce Locator,统一资源定位符,用于描述某服务器某特定资源位置
 两者区别:URN如同一个人的名称,而URL代表一个人的住址。换言之,URN定义某事物的身份,而URL提供查找该事物的方法。URN仅用于命名,而不指定地址
URL组成
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
    scheme:方案,访问服务器以获取资源时要使用哪种协议
    user:用户,某些方案访问资源时需要的用户名
    password:密码,用户对应的密码,中间用:分隔
    Host:主机,资源宿主服务器的主机名或IP地址
    port:端口,资源宿主服务器正在监听的端口号,很多方案有默认端口号
    path:路径,服务器资源的本地名,由一个/将其与前面的URL组件分隔
    params:参数,指定输入的参数,参数为名/值对,多个参数,用;分隔
    query:查询,传递参数给程序,如数据库,用?分隔,多个查询用&分隔
    frag:片段,一小片或一部分资源的名字,此组件在客户端使用,用#分隔
 
 
 
 
一次完整的http请求处理过程
1、建立连接:接收或拒绝连接请求
2、接收请求:接收客户端请求报文中对某资源的一次请求的过程
    Web访问响应模型(Web I/O)
    单进程I/O模型:启动一个进程处理用户请求,而且一次只处理一个,多个请求被串行响应
    多进程I/O模型:并行启动多个进程,每个进程响应一个连接请求
    复用I/O结构:启动一个进程,同时响应N个连接请求
    复用的多进程I/O模型:启动M个进程,每个进程响应N个连接请求,同时接收M*N个请求
3、处理请求:服务器对请求报文进行解析,并获取请求的资源及请求方法等相关信息,根据方法,资源,首部和可选的主体部分对请求进行处理
    元数据:请求报文首部
    Host: 请求的主机名称
    Server: Apache/2.4.7
    HTTP常用请求方式Method  :GET、POST、HEAD、PUT、DELETE、TRACE、OPTIONS、
    curl -I www.baidu.com查看
4、访问资源:服务器获取请求报文中请求的资源web服务器,即存放了web资源的服务器,负责向请求者提供对方请求的静态资源,或动态运行后生成的资源   
    资源放置于本地文件系统特定的路径:
    DocRoot  /var/www/html
    /var/www/html/images/logo.jpg
    http://www.magedu.com/images/logo.jpg
  web服务器资源路径映射方式:
    (a) docroot
    (b) alias
    (c) 虚拟主机docroot
     
     
5、构建响应报文:
一旦Web服务器识别除了资源,就执行请求方法中描述的动作,并返回响应报文。响应报文中 包含有响应状态码、响应首部,如果生成了响应主体的话,还包括响应主体
    1)响应实体:如果事务处理产生了响应主体,就将内容放在响应报文中回送过去。响应报文中通常包括:
       描述了响应主体MIME类型的Content-Type首部
       描述了响应主体长度的Content-Length
       实际报文的主体内容
    2)URL重定向:web服务构建的响应并非客户端请求的资源,而是资源另外一个访问路径
       永久重定向
       临时重定向
    3)MIME类型:
       Web服务器要负责确定响应主体的MIME类型。多种配置服务器的方法可将MIME类型与资源管理起来
       魔法分类:Apache web服务器可以扫描每个资源的内容,并将其与一个已知模式表(被称为魔法文件)进行匹配,以决定每个文件的MIME类型。这样做可能比较慢,但很方便,尤其是文件没有标准扩展名时
       显式分类:可以对Web服务器进行配置,使其不考虑文件的扩展名或内容,强制特定文件或目录内容拥有某个MIME类型
       类型协商: 有些Web服务器经过配置,可以以多种文档格式来存储资源。在这种情况下,可以配置Web服务器,使其可以通过与用户的协商来决定使用哪种格式(及相关的MIME类型)"最好"  
 
6、发送响应报文
      Web服务器通过连接发送数据时也会面临与接收数据一样的问题。服务器可能有很多条到各个客户端的连接,有些是空闲的,有些在向服务器发送数据,还有一些在向客户端回送响应数据。服务器要记录连接的状态,还要特别注意对持久
连接的处理。对非持久连接而言,服务器应该在发送了整条报文之后,关闭自己这一端的连接。对持久连接来说,连接可能仍保持打开状态,在这种情况下,服务器要正确地计算Content-Length首部,不然客户端就无法知道响应什么时候结束了
 
7、记录日志
     最后,当事务结束时,Web服务器会在日志文件中添加一个条目,来描述已执行的事务      
 
 
 
HTTP请求报文:请求报文由请求行、请求头部、空行 和 请求包体 4 个部分组成
    request报文
    <method> <request-URL> <version>
    <headers>
    <entity-body>
        method: 请求方法,标明客户端希望服务器对资源执行的动作
        request-URL:请求的域名路径
        version:HTTP协议版
        headers:(k/v值)请求或响应报文可包含任意个首部;每个首部都有首部名称,后面跟一个冒号,而后跟一个可选空格,接着是一个值  
        entity-body:,请求包体不在 GET 方法中使用,而是在POST 方法中使用。POST 方法适用于需要客户填写表单的场合。与请求包体相关的最常使用的是包体类型 Content-Type 和包体长度 Content-Length
HTTP响应报文:HTTP 响应报文由状态行、响应头部、空行 和 响应包体 4 个部分组成
    response报文
    <version> <status> <reason-phrase>
    <headers>
    <entity-body>
        version:HTTP协议版
        status:三位数字,如200,301, 302, 404, 502; 标记请求处理过程中发生的情况
        reason-phrase:状态码所标记的状态的简要描述
        headers:(k/v值)每个请求或响应报文可包含任意个首部;每个首部都有首部名称,后面跟一个冒号,而后跟一个可选空格,接着是一个值
        entity-body:请求时附加的数据或响应时附加的数据,服务器返回给客户端的文本信息;
 
 
HTTP常用请求方式Method  :
    GET、从服务器获取一个资源
    POST、向服务器输入数据,通常会再由网关程序继续处理
    HEAD、只从服务器获取文档的响应首部
    PUT、将请求的主体部分存储在服务器中,如上传文件
    DELETE、请求删除服务器上指定的文档
    TRACE、追踪请求到达服务器中间经过的代理服务器
    OPTIONS、请求服务器返回对指定资源支持使用的请求方法
 
 
http协议首部headers:
首部的分类:
通用首部: 请求报文和响应报文两方都会使用的首部
请求首部: 从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、请求内容相关优先级等信息
响应首部:从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息
实体首部:针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的的信息
扩展首部
 
通用首部:
    Date: 报文的创建时间
    Connection:连接状态,如keep-alive, close
    Via:显示报文经过的中间节点(代理,网关)
    Cache-Control:控制缓存,如缓存时长
    MIME-Version:发送端使用的MIME版本
    Warning:错误通知
 
请求首部:
    Accept:通知服务器自己可接受的媒体类型列表,星号 “ * ” 用于按范围将类型分组,用 “ */* ” 指示可接受全部类型,用“ type/* ”指示可接受 type 类型的所有子类型;
    Accept-Charset: 客户端可接受的字符集
    Accept-Encoding:客户端可接受编码格式,如gzip
    Accept-Language:客户端可接受的语言
    Client-IP: 请求的客户端IP
    Host: 请求的服务器名称和端口号
    Referer:跳转至当前URI的前一个URL
    User-Agent:客户端代理,浏览器版本 
 
响应首部:
  信息性:
    Age:从最初创建开始,响应持续时长
    Server:服务器程序软件名称和版本
  协商首部:某资源有多种表示方法时使用
    Accept-Ranges:服务器可接受的请求范围类型
    Vary:服务器查看的其它首部列表
  安全响应首部:
    Set-Cookie:向客户端设置cookie
    WWW-Authenticate:来自服务器对客户端的质询列表
 
实体首部:
    Allow: 列出对此资源实体可使用的请求方法
    Location:告诉客户端真正的实体位于何处
    Content-Encoding:对主体执行的编码
    Content-Language:理解主体时最适合的语言
    Content-Length: 主体的长度
    Content-Location: 实体真正所处位置
    Content-Type:主体的对象类型,如text缓存相关:
    ETag:实体的扩展标签
    Expires:实体的过期时间
    Last-Modified:最后一次修改的时间
 
条件式请求首部:
    Expect:允许客户端列出某请求所要求的服务器行为
    If-Modified-Since:自从指定的时间之后,请求的资源是否发生过修改
    If-Unmodified-Since:与上面相反
    If-None-Match:本地缓存中存储的文档的ETag标签是否与服务器文档的Etag不匹配
    If-Match:与上面相反 
安全请求首部:
    Authorization:向服务器发送认证信息,如账号和密码
    Cookie: 客户端向服务器发送cookie,存储于客户端扩展字段,向同一域名的服务端发送属于该域的cookie;
代理请求首部:
    Proxy-Authorization: 向代理服务器认证  
         
 
status(状态码): 
  1xx:100-101 信息提示
2xx:200-206 成功
3xx:300-305 重定向
4xx:400-415 错误类信息,客户端错误
5xx:500-505 错误类信息,服务器端错误
 200: 成功,请求数据通过响应报文的entity-body部分发送;OK
 301: 请求的URL指向的资源已经被删除;但在响应报文中通过首部Location指明了资源现在所处的新位置;Moved Permanently
 302: 响应报文Location指明资源临时新位置 Moved Temporarily
 304: 客户端发出了条件式请求,但服务器上的资源未曾发生改变,则通过响应此响应状态码通知客户端;Not Modified
 401: 需要输入账号和密码认证方能访问资源;Unauthorized
 403: 请求被禁止;Forbidden
 404: 服务器无法找到客户端请求的资源;Not Found
 500: 服务器内部错误;Internal Server Error
 502: 代理服务器从后端服务器收到了一条伪响应,如无法连接到网关;Bad Gateway
 503: 服务不可用,临时服务器维护或过载,服务器无法处理请求
 504: 网关超时
 
 
http协议无状态方法:1.cookie 客户端存放 2.session 服务端存放
    HTTP 是一种无状态协议。协议自身不对请求和响应之间的通信状态进行保存。也就是说在 HTTP 这个级别,协议对于发送过的请求或响应都不做持久化处理。
这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把 HTTP 协议设计成如此简单的。可是随着 Web 的不断发展,很多业务都需要对通信状态进行
保存。于是引入了 Cookie 技术。使用 Cookie 的状态管理Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。Cookie 会根据从服
务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报
文中加入 Cookie 值后发送出去。服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,
最后得到之前的状态信息
  Set-cookie首部字段示例:
    Set-Cookie: status=enable; expires=Fri, 24 Nov 2017 20:30:02 GMT; path=/;
    NAME=VALUE 赋予 Cookie 的名称和其值,此为必需项
    expires=DATE Cookie 的有效期,若不明确指定则默认为浏览器关闭前为止
    path=PATH 将服务器上的文件目录作为Cookie的适用对象,若不指定则默认为文档所在的文件目录
    domain=域名 作为 Cookie 适用对象的域名,若不指定则默认为创建Cookie的服务器的域名
    Secure 仅在 HTTPS 安全通信时才会发送 Cookie
    HttpOnly 加以限制使 Cookie 不能被 JavaScript 脚本访问
 
 
 
MPM(multi processing module多处理模块)工作模式
prefork:多进程I/O模型,每个进程响应一个请求,默认模型
    一个主进程:生成和回收n个子进程,创建套接字,主进程是不响应请求
    多个子进程:工作work进程,每个子进程处理一个请求;系统初始时,预先生成多个空闲进程,等待请求,默认最大不超过1024个 
    Prefork MPM: 预派生模式,有一个主控制进程,然后生成多个子进程,每个子进程有一个独立的线程响应用户请求,相对比较占用内存,但是比较稳定,可以设置最大和最小进程数,是最古老的一种模式,也是最稳定的模式,适用于访问量不是很大的场景 
    优点:稳定
   缺点:慢,占用资源,不适用于高并发场景
     
worker:复用的多进程I/O模型,多进程多线程,IIS使用此模型
    一个主进程:生成m个子进程,每个子进程负责生个n个线程,每个线程响应一个请求,并发响应请求:m*n
    worker MPM:是一种多进程和多线程混合的模型,有一个控制进程,启动多个子进程,每个子进程里面包含固定的线程,使用线程程来处理请求,当线程不够使用的时候会再启动一个新的子进程,然后在进程里面再启动线程处理请求,由于其使用了线程处理请求,因此可以承受更高的并发。
   优点:相比prefork 占用的内存较少,可以同时处理更多的请求
   缺点:使用keep-alive的长连接方式,某个线程会一直被占据,即使没有传输数据,也需要一直等待到超时才会被释放。如果过多的线程,被这样占据,也会导致在高并发场景下的无服务线程可用。(该问题在prefork模式下,同样会发生)
 
event:事件驱动模型(worker模型的变种)
    一个主进程:生成m个子进程,每个子进程负责生个n个线程,每个线程响应一个请求,并发响应请求:m*n,有专门的监控线程来管理这些keep-alive类型的线程,当有真实请求时,将请求传递给服务线程,执行完毕后,又允许释放。这样增强了高并发场景下的请求处理能力
    event MPM:Apache中最新的模式,属于事件驱动模型(epoll),每个进程响应多个请求,在现在版本里的已经是稳定可用的模式。它和worker模式很像,最大的区别在于,它解决了keep-alive场景下,长期被占用的线程的资源浪费问题(某些线程因为被
keep-alive,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)。event MPM中,会有一个专门的线程来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场景下的请求处理能力
event只在有数据发送的时候才开始建立连接,连接请求才会触发工作线程,即使用了TCP的一个选项,叫做延迟接受连接TCP_DEFER_ACCEPT,加了这个选项后,若客户端只进行TCP连接,不发送请求,则不会触发Accept操作,也就不会触发工作线程去干活,进行了简单的防攻击(TCP连接)
 优点:单线程响应多请求,占据更少的内存,高并发下表现更优秀,会有一个专门的线程来管理keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放
 缺点:没有线程安全控制

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Sendfile机制(默认启用)也叫 “零复制”
不用 sendfile 的传统网络传输过程:
 read(file, tmp_buf, len) 
   write(socket, tmp_buf, len) 
   硬盘 >> kernel buffer >> user buffer >> kernel socket buffer >> 协议栈
 一般网络应用通过读硬盘数据,写数据到 socket 来完成网络传输,底层执行过程:
 1 系统调用 read() 产生一个上下文切换:从 user mode 切换到 kernel mode,然后DMA 执行拷贝,把文件数据从硬盘读到一个 kernel buffer 里。
 2 数据从 kernel buffer 拷贝到 user buffer,然后系统调用 read() 返回,这时又产生一个上下文切换:从kernel mode 切换到 user mode
 3 系统调用 write() 产生一个上下文切换:从 user mode 切换到 kernel mode,然后把步骤2读到 user buffer 的数据拷贝到 kernel buffer(数据第2次拷贝到 kernel buffer),不过这次是个不同的 kernel buffer,这个 buffer和 socket 相关联。
 4 系统调用 write() 返回,产生一个上下文切换:从 kernel mode 切换到 user mode(第4次切换),然后DMA从 kernel buffer 拷贝数据到协议栈(第4次拷贝)
 上面4个步骤有4次上下文切换,有4次拷贝,如能减少切换次数和拷贝次数将会有效提升性能
 
在kernel 2.0+ 版本中,系统调用 sendfile() 就是用来简化上面步骤提升性能的。sendfile() 不但能减少切换次数而且还能减少拷贝次数
用 sendfile() 来进行网络传输的过程:
sendfile(socket, file, len);
硬盘 >> kernel buffer (快速拷贝到kernel socket buffer) >> 协议栈
1 系统调用 sendfile() 通过 DMA 把硬盘数据拷贝到 kernel buffer,然后数据被kernel 直接拷贝到另外一个与 socket 相关的 kernel buffer。这里没有 user mode 和 kernel mode 之间的切换,在 kernel 中直接完成了从一个 buffer 到另一个 buffer 的拷贝
2 DMA 把数据从 kernel buffer 直接拷贝给协议栈,没有切换,也不需要数据从user mode 拷贝到 kernel mode,因为数据就在 kernel 里

  

posted @   yuanbangchen  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
点击右上角即可分享
微信分享提示