前言
关于《http权威指南》
,很早以前就想抱着啃了,由于时间段太零碎了,一直没能好好看过。近来公司业务不是很重,同时找暑期实习的时候面试官也聊到了关于http
的一些问题,抽空把《http权威指南》
前五章看了一下。整理了一些知识点,写成笔记作为备忘的同时也分享给大家。
正文
HTTP协议
HTTP协议是超文本传输协议(HTTP,HyperText Transfer Protocol)的缩写,简单来讲就是对传输数据的文本格式的一种规范。遵循过HTTP协议的文本称之为报文
,按照发送方与接受收方的不同分为两种,客户端发送给服务器端的为请求报文
,服务器端发送给客户端的为相应报文
。同时HTTP报文是纯文本的形式,不是二进制代码,开发者可以非常方便地进行读写。如下图就是一个GET事务实例中请求报文和响应报文:
报文由三部门组成,分别是起始行、首部、主体。
请求报文中的请求起始行: GET /tools.html HTTP/1.0
,意思为发起向host
主机发起GET
请求,请求tools.html
文件,使用的是HTTP1.0
协议。请求首部意思为,客户端的代理是Mozilla/4.75 [en] (Win98;U)
,请求的对象(服务端)主机地址为www.joes-hardware.com
,同时表明客户端只接受文本格式为html
的文本文件,图片格式为git
或者jpeg
的图片,告诉服务器浏览器支持的语言为en
。
响应报文中的请求起始行: HTTP/1.0 200 OK
,意思为HTTP/1.0
请求响应成功,200
是状态码,OK
是200
状态码对应原因短语
。响应首部中,Date
对应报文的响应时间,Server
是指服务器端的服务器配置,Last-modified
代表请求的数据的最后一次的修改日期,Content-length
是指响应主体的长度,Content-type
代表响应主题的文件格式。响应主体就是客户端所请求的内容。
URL
URL是统一资源定位符(Uniform Resource Locator)的缩写,对于URL的认识大多停留在所谓的网址
的层面上。实际上URL并不只是应用在http
中,ftp://user:password@ftp.prep.ai.edu.cn/pub/gnu
也是URL
,大多数的URL方案的语法都建立在这个由9部分构成的通用格式上
<scheme>://<user>:<password>@<host>:<port>/path;<params>?<query>#<frag>
但是并非一定会包含上面所有组件。URL中常使用的起始也就三个组件,即方案(scheme)、主机(host)和路径(path),例如http://www.myhost.com/file/test.html
,http
=> 方案,www.myhost.com
=> 主机,/file/test.html
=> 路径。
当然www.myhost.com
并不是我们真正的主机地址,它只是一个域名,通过DNS解析以后会得到主机的真正IP地址。
通用组件中各自的对应关系如下表:
HTTP、TCP与IP
计算机网络协议按照不同分法有不同层数,这里以五层模型举例,HTTP、TCP、IP的关系如下图。
这张图说明了层次关系,但并没有说明他们之间相互的联系,这里我画了一个示意图大致解释一下。
三者关系大致可以通过货物的运送来解释,我需要发送的内容称之为content
,可以看作一个物品,在运输货物的时候会对货物进行打包,这层包装我们可以理解为http
。物品包装好了肯定需要货车进行运送,而货车可以看作TCP
传输协议。货车行驶在高速路上,我们可以把高速路看作IP
,而各个收费站我们可以理解为特定的IP地址
。
HTTP的方法
值得一提的是HTTP的方法并非只有GET
与POST
,事实上只是因为这两种方法被使用得广泛,导致大家只知道这两种。
实际上,HTTP的方法有:
- GET
- POST
- PUT
- HEAD
- DELETE
- TRACE
- OPTIONS
同时由于HTTP本身是被设计成字段可扩展的,所以新的特性并不会使老的软件失效。而所谓的扩展方法就是指没有在HTTP/1.1规范中定义的方法,而这些方法有助于通过HTTP将web内容发布到web服务器上。
HTTP性能
在不考虑的持久连接的情况,我们每次的http请求都会产生一次TCP连接,而每次TCP的连接与关闭都会经历三次握手
与四次挥手
的过程,当产生大量的http请求的时候,大量的时间会浪费在TCP的连接与关闭上,造成性能损耗,当按最坏的情况考虑的时候甚至会出现端口耗尽
的情况。
因为客户端每次连接服务端的时候,都会获得一个新的端口,以实现连接的唯一性,但是由于可用端口有限(一个IP地址的端口可以有65536,其中注册端是口1024到49151,分配给用户进程或应用程序。这些进程主要是用户选择安装的一些应用程序,而不是已经分配好了公认端口的常用程序。这些端口在没有被服务器资源占用的时候,可以用用户端动态选用为源端口)。同时TCP端点在关闭TCP连接的时候,会在内存中维护一个小的控制块,用来记录最近关闭连接的IP地址后端口号,而在这段时间内,该端口号无法被重用。一旦TCP的连接频率超过了某个值,会出现无法连接的问题,也就是TIMEM_WAIT
端口耗尽。
当然,使用持久连接,可以减少端口耗尽出现的可能,但是对于持久连接也应该进行合理的维护,当不再使用的时候应该关闭,避免长时间的无意义占用,否则长时间的堆积依然可能会出现端口耗尽的状况。
同时即使没有遇到端口耗尽的问题,也要特别小心有大量连接打开或为处于等待状态的连接分配了大量控制块的情况。因为在有大量打开连接或控制块的情况下,有些操作系统的速度会严重减缓。