HTTP学习二:Web应用中的HTTP
1 HTTP连接
1.1 TCP连接对性能的影响
TCP三次握手如下图:
如上图,建立一次TCP连接要经过三个步骤。HTTP是建立在TCP之上的,因此TCP连接的性能直接影响HTTP的性能。
TCP影响HTTP性能有以下几点:
- TCP连接建立握手
- TCP慢启动拥塞控制
- 数据聚集的Nagle算法
- 用于捎到确认的TCP延迟确认算法
- TIME_WAIT时延和端口耗尽
1.2 HTTP连接
1.2.1 并行连接
HTTP允许客户端打开多条连接,并行地执行多个HTTP事务。
如上图,在请求1没有完成时,客户端可以继续发生请求到服务端。
并行连接理论上可以提高HTTP的性能,但事实上看上去并不是这样的。
- 带宽大小
- 连接数
并发连接的时候将会对带宽产生竞争,而客户端也一般会限制连接数的大小
1.2.2 持久连接
持久化连接,即第一次建立TCP连接后,以后的请求都通过这条TCP连接进行通信。
如上图,持久连接可以不用在每次连接中都重建TCP连接,可以极大的提高HTTP的性能,但也有一些限制:
- 如果主动关闭了,就不能在那条连接上发送更多的请求了
- 如果不想发送其他请求了,就应该关闭连接
- 只有当连接上所有的报文都有正确的、自定义报文长度时连接才能保持持久
1.2.3 管道化连接
管道化连接允许把下一个请求在第一个请求没有响应回来的时候就再次发送,原理如下图
管道化连接,能有效的提供HTTP连接的性能,但也有如下限制:
- 如果HTTP客户端无法确认连接是持久的,就不应该使用管道
- 必须是顺序的
- 要有重发机制
1.3 Web应用中高效的连接
在Web中为了提供性能,都采用长连接(持久连接)来进行通信:
- 并行连接,受限于资源
- 管道化连接,受限于顺序
1.3.1 HTTP1.0
在HTTP1.0中支持keep-alive的长连接。
实现HTTP1.0 keep-alive连接的客户端可以通过包含
Connection:Keep-Alive
首部请求将一条连接保持在打开状态。
Keep-Alive选项:
-
timeout,服务器希望保持在活跃状态的时间
-
max:服务器希望为多少个事务保持此连接的活跃状态
Connection:Keep-Alive
Keep-Alive:max=5,timeout=120
但Keep-Alive连接也有些限制:
- HTTP1.0中keep-alive并不默认使用,必须显示的发送一个Connection:Keep-Alive首部
- 必须所有希望保持长连接的报文都携带Connection:Keep-Alive首部
- 必须有正确的Content-Length
1.3.2 HTTP1.1
HTTP1.1逐渐停止可对keep-alive连接的支持,用一种持久连接的改进型设计取代了它。
HTTP1.1下的持久连接默认是激活的,在事务中显示的添加Connection:Close来关闭连接。
1.4 实时消息
在很多时候,我们需要将数据主动的推送到客户端,以便实时的刷新页面数据。
但限于HTTP的客户-服务端模型,有很大的限制。
我们要实现实时消息,主要有两种技术:
- 实时推送
- 定时轮询
在不要求性能的系统,定时轮询是一种简单的实现方式,它每隔一定时间主动的去服务器拉取数据,如果数据有变化,就主动的刷新相关数据。
这种方法简单,但很耗费资源,但利用HTTP的长连接特性,可以变相的实现实时推送技术,如下图
如上图,客户端同服务端建立一条长连接后,阻塞该连接不结束,如果有数据发送则通过该连接发给客户端,客户端接收到数据后,也不主动关闭连接,继续接收数据。
2 缓存
缓存是可以自动保存常见文档副本的HTTP设备。当请求抵达缓存时,如果本地有已缓存的副本,就可以从本地存储设备而不是原始服务器中提取这个文档。
使用缓存有下列优点:
- 减少冗余的数据传输
- 缓解网络瓶颈
- 降低服务器压力
- 降低距离延时
HTTP缓存的处理步骤
- 1.接收:缓存从网络中读取抵达的请求报文
- 2.解析:解析报文,提前出URL和各种首部
- 3.查询:查询本地是否有副本可用
- 4.新鲜度检测:查看副本是否足够新鲜
- 5.创建响应:创建响应数据
- 6.发送:缓存通过网络将响应发回给客户端
- 7.日志:创建日志
2.1 HTTP缓存头部
通过HTTP的Cache-Control首部和Expirse首部来标明缓存信息。
- Expires HTTP1.0+的过期时间
- Cache-Control:max-age HTTP1.1的过期时间
- If-Modified-Since 如果在指定时间内改变了,就执行请求
- If-None-Match 如果标签不同就执行请求,需要与ETag首部联合使用
- If-Unmodified-Since 如果没有改变就执行
- If-Range 如果在时间范围内请求
- If-Match 如果标签相同就执行请求
Cache-Control
- no-store 不存储
- no-cache 不缓存
- max-age 最大生命周期
2.2 设置缓存
2.2.1 Nginx缓存设置
expires max;
2.2.2 Apache缓存设置
Header set Cache-Control "no-cache"
ExpirseDefault A3600
2.2.3 Java服务器缓存设置
response.addHeader( "Cache-Control", "must-revalidate" );
response.addHeader( "Cache-Control", "no-cache" );
response.addHeader( "Cache-Control", "no-store" );
response.setDateHeader("Expires", 0);
2.2.4 HTML缓存设置
<META HTTP-EQUIV="Cache-control" CONTENT="no-cache">
3 客户端与Cookie机制
3.1 客户端
服务器可以从HTTP首部中获取客户端信息:
- From 用户的email地址
- User-Agent 用户的浏览器软件信息
- Referer 原始链接
- Clinet-IP 客户端的IP地址
- X-Forwarded-For 客户端的IP地址
3.2 Cookie
Cookie是指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。
它是一组key-value键值对,它有expires、path、domain等属性,以便标识不同服务端的信息。
4 REST
REST是一种风格,而不是标准和实现。
REST通过重新对系统的资源进行重新定义,通过HTTP对系统的资源进行操作:
-
GET 获取一个资源
-
POST 提交资源数据到服务端
-
PUT 提交客户端数据到服务器
-
DELETE 删除资源
POST和PUT的区别是PUT只是提交数据,而不在服务端生成ID,POST提交数据并创建ID
5 编码与国际化
5.1 中文内容处理
在HTTP数据传输中,都需要进行编码处理才能在服务端和客户端之间正确的进行转换和处理。
中文的传输过程具体可能是:内存中unicode -> 编码阶段gbk, gb18030, utf8 -> 到urlencode ->最后到可能的base64编码。
Java中文内容的处理:
- 所有文件都是UTF-8编码
- HTML页面加入
- tomcat的server.xml文件中connector设置编码为utf-8
- spingmvc的CharacterEncodingFilter设置为utf-8
5.2 URI的国际化
URI是以ASCII编码的,但为了各个国家的通用性,须要进行国际化字符转义操作。