一. Web组件
代理: 位于客户端和服务器之间的HTTP中间实体
缓存: 存储常用页面的副本,比起服务器里客户端要近很多
网关: 链接其他应用程序的特殊web服务器。通常可以将其他的uri请求包装成HTTP请求转发。
隧道: 对HTTP报文忙转发
Agent代理: 自动发起HTTP请求的半智能web客户端,包括平常所说的网络爬虫
二. URI
URI主要分为URL和URN,其中URN还只是停留在理论阶段,所以现阶段投入使用中的URI将会等价于URL。
URL的标准格式(大小写无关)为:
<schema>://<user>:<password>@<host>:<port>/<path>;<parameters>?<query>#<frag>
其中值得注意几点:
1. schema, 包括了http,https,ftp等一系列应用层协议
2. parameters,使用分号(;)同路径分割的
3. query, 用问号(?)分割的我们通常会叫为参数,实际上它是一个查询
URL的快捷方式:使用相对路径
三. HTTP报文
HTTP报文流始终向下游流动,即流动方向决定上下游
报文包含头部(header)和实体(content)两个部分。请求报文和响应报文的Header都有固定的格式。
请求报文
响应报文
HTTP状态码分类:
四. 连接管理
TCP链接基础,包括TCP传输机制和可靠性,以及nagle算法。
HTTP时延的原因:
1. DNS找域名(尤其是不常用的)
2. TCP三次握手建立链接
3. 内嵌链接的串行执行
1. 并行链接
并不一定能使网页加载变快,因为多个链接会占用带宽,使得整体性能没有提升,甚至下降。但是用户在看到东西加载出来的过程会感觉上并行是快一点的。
2. 保持连接
建立连接后,服务器和客户端保持连接直到某一方关闭。
2.1
HTTP/1.0使用客户端发送connection:keep-alive来请求服务器保持连接,服务器回复connection:keep-alive来确认和客户端保持连接。
在使用代理(盲代理)的时候将会出现问题,盲代理将客户端和服务器的报文盲目转发,导致客户端和服务器误以为连接保持,实际上代理关闭了对客户端的连接,而服务器和代理的连接却一直保持。这样将不断耗费资源。
此外客户端在显示设置代理的情况下,可以使用proxy-connection来取代connection,如果服务器收到的是proxy-connection的报文,将无视其保持连接的请求。
当然存在一些聪明的代理,他们将proxy-connection修改成connection来使得客户端和服务器保持连接。
但是如果客户端到服务器之间存在一个盲代理,而盲代理旁边不幸地存在一个聪明代理,问题又回到了最初connection+盲代理的时代。
2.2
HTTP/1.1使用persistent来保持连接,并且是默认保持的。必须有一方发送connection:close来明确终止连接。
3. 管道连接
管道连接在保持连接的基础上增加了连接的‘cache’,维持即将发出的连接。
使用的前提是必须保证客户端和服务器都是保持连接的。
消息发送接受必须保证顺序,否则cache中的所有连接都必须重置。
如果服务器关闭连接,客户端必须尝试重发。由此,表单提交等非幂等的操作不应该使用管道连接来维护,否则将造成事务(transaction)问题。
连接关闭
TCP的连接是双向的,一条输入一条输出。服务器和客户端都可以关闭连接,如果单方面只关闭输出连接(半关闭)是没有问题,关闭输出后,另一方将收到对方已经关闭输出的信息,此时可以关闭自己的输入。
如果在对方输出未接收完的情况下关闭输入连接,大部分操作系统将会认为这是一个很大的问题。比如在我们进行socket编程时 经常会遇见的reset by peer.
在非正常情况下服务器或客户端也可以关闭连接,客户端在遭遇这种情况通常会选择重新连接。但是如果在处理一些事务工作时,必须询问用户是否重新提交表单。