http协议学习笔记(四)

来源:互联网 发布:梦洁床垫怎么样知乎 编辑:程序博客网 时间:2024/05/19 14:54

本文讨论一个经典的面试题:从输入 url 到页面加载完成的过程中都发生了什么事情。对这个问题的回答可大可小,如果想深入到计算机体系和硬件的层面去理解,可以参考百度fex团队nwind(吴多益)的文章:http://fex.baidu.com/blog/2014/05/what-happen/

这里我主要参考以下两篇文章进行简单的总结

http://www.kuqin.com/shuoit/20150104/344230.html

http://blog.aijc.net/server/2015/11/03/%E4%BB%8E%E8%BE%93%E5%85%A5URL%E5%88%B0%E9%A1%B5%E9%9D%A2%E5%8A%A0%E8%BD%BD%E5%AE%8C%E7%9A%84%E8%BF%87%E7%A8%8B%E4%B8%AD%E9%83%BD%E5%8F%91%E7%94%9F%E4%BA%86%E4%BB%80%E4%B9%88%E4%BA%8B%E6%83%85/


下边直说最简单的通过浏览器发起HTTP请求资源过程,没有代理,通过域名访问的情况。根据http://blog.csdn.net/iaiti/article/details/28339145中相关介绍,将要发生如下事情:

  1. 浏览器查询缓存,如果缓存存在跳到第9步

  2. 浏览器询问操作系统服务器的IP地址

  3. 操作系统做DNS查询,返回IP地址给浏览器

  4. 浏览器打开对服务器的TCP连接

  5. 浏览器通过TCP连接发送HTTP请求

  6. 浏览器接收HTTP响应并且可能关掉TCP连接,或者是重新使用连接处理新请求(也就是keepalive)

  7. 浏览器检查HTTP响应是否为一个重定向(3xx 结果状态码 ),一个验证请求(401),错误(4xx 5xx)等等,这些都是不同响应的正常处理(2xx)

  8. 如果响应可缓存,将存入缓存

  9. 浏览器解码响应(例如:如果它是gziped压缩)

  10. 浏览器决定如何处理这些响应(例如,它是HTML页面,一张图片,一段音乐)

  11. 浏览器展现响应,对未知类型还会弹出下载对话框(现在一般不会弹出了,用户对浏览器设置而定)

一 DNS查询得到IP地址

DNS,英文是Domain Name System,中文叫域名系统,是Internet的一项服务,他将域名和IP地址相互映射的一个分布式数据库,引入域名是为了解决IP地址不便于记忆这个问题的。所以说这时候就需要有DNS这样的服务来解决域名和IP地址是怎么映射的。在DNS的定义中也说了他是一个分布式数据库,更通俗来讲的话就是有对应的域名服务器(装有DNS的主机),利用域名服务器来实对应的名称解析。要理解DNS,首先得知道域名;域名是为了识别主机名称和组织机构名称的一种具有分层的名称。

根域:也就是.,在上图中就是最顶部的那个,而对应的根域服务器,之前会有错误的认为根域名服务器只有13台,但实际上不是13个,而是13组,而根服务器目前则有504台,还会更多,目前是被编号为从A到M13个标号,他们是只有13个IP地址,这么多服务器通过任播Anycast技术,标号相同根服务器使用1个IP。而具体分布情况则可以查看http://root-servers.org/

顶级域:也叫一级域,主要分为四类:国家及地区顶级域(.cn.jp等)、通用顶级域(.com.edu.net等)、基础设施顶级域(.arpa,之前属于通用顶级域)和测试顶级域(例如.测试)。

二级域:可变长度的个体或组织,以便在Internet上使用的注册的名称,这些名称一定会基于相应的顶级域,例如aijc.net

其他还有三级域(子域,也就是从已注册的二级域名自定义派生的),还可以有四级域(主机或资源名称),当然还可以更多级。

域名解析

进行DNS查询的主机或软件叫做DNS解析器,用户使用的工作站或电脑都属于解析器。域名解析就是利用DNS解析器得到对应IP过程,解析器会向域名服务器进行查询处理。解析过程就是一个查询的过程,来一张来自http://xdays.me/dns%E5%8D%8F%E8%AE%AE%E8%AF%A6%E8%A7%A3.html的图:


下边的这几个步骤和上边图上的过程是一一对应的,但是在这之前还有一些步骤:

  1. 从浏览器缓存中查找域名www.google.com的IP地址

  2. 在浏览器缓存中没找到,就在操作系统缓存中查找,这一步中也会查找本机的hosts看看有没有对应的域名映射(当然已经缓存在系统DNS缓存中了)

  3. 在系统中也没有的话,就到你的路由器来查找,因为路由器一般也会有自己的DNS缓存

如果依旧找不到,接着对应图上的步骤继续(http://xdays.me/dns%E5%8D%8F%E8%AE%AE%E8%AF%A6%E8%A7%A3.html)

  1. 用户电脑的解析器向LDNS(也就是Local DNS,互联网服务提供商ISP),发起域名解析请求,查询www.google.com的IP地址,这是一个递归查找过程(所谓递归就是:如果主机所查询的本地域名服务器不知道被查询的IP地址,那么本地域名服务器就以DNS客户的身份,向其它根域名服务器继续发出查询请求报文,即替该主机继续查询,而不是让该主机自己进行下一步的查询)

  2. 在缓存没有命中的情况下,LDNS向根域名服务器.查询www.google.com的IP地址,LDNS的查询过程是一个迭代查询的过程(当然本地域名服务器也可以采用递归查询,这取决于最初的查询请求报文的设置是要求使用哪一种方式)

  3. 根告诉LDNS,我不知道www.google.com对应的IP,但是我知道你可以问com域的授权服务器,这个域归他管

  4. LDNS向com的授权服务器问www.google.com对应的IP地址

  5. com告诉LDNS,我不知道www.google.com对应的IP,但是我知道你可以问google.com域的授权服务器,这个域归他管

  6. LDNS向google.com的授权服务器问www.google.com对应的IP地址

  7. google.com查询自己的ZONE文件(也称区域文件记录),找到了www.google.com对应的IP地址,返回给LDNS

  8. LDNS本地缓存一份记录,把结果返回给用户电脑的解析器

在这之后,用户电脑的解析器拿到结果后,缓存在自己操作系统DNS缓存中,同时返回给浏览器,浏览器依旧会缓存一段时间。

上边有提到域名服务器会查询自己的ZONE文件,其实也就是常说的DNS记录,主要有几种类型:

  • A记录,用来指定域名对应的IPv4地址的记录

  • NS记录,也就是域名服务器的记录,如果需要将域名去指定某个域名服务器去解析的话,就需要NS记录

  • CNAME记录,域名的对应的别名,其实是另一个域名,实现与指向的域名相同访问效果

  • MX记录,邮件交换记录,如果需要建立邮箱服务,将指向的是邮件服务器地址的记录

  • AAAA记录,将主机名(域名)指向一个IPv6地址的记录

  • TXT记录,任意填写文本内容,通常用作SPF记录(反垃圾邮件)使用

  • SRV记录,记录哪台计算机提供了哪个服务的记录,主要用于服务器选择

当然还有一些其他记录类型(SOA、WKS、PTR、HINFO、MINFO、SIG、KEY、GPOS、NXT等),这里不再细说。

在DNS解析这里还涉及到了另外一个技术CDN,下边来介绍下:

CDN

CDN,英文Content Delivery Network,中文翻译是内容分发网络,目的就是通过现有的Internet中增加一新的网络架构,将网站内容发布到离用户最近的网络“边缘”,提高用户访问网站的速度,所以更像是增加了一层CACHE(缓存)层。从技术上全面优化由于网络宽带小、用户访问量大、网点分布不均匀等导致的用户访问网站响应速度慢的情况。那他的实现原理是啥呢?其实主要是通过接管DNS来实现,注意上边DNS域名解析过程的那张图,在倒数第二步中(也就是第7步),可能需要更多过程来完成,这里就举一个例子,例如说上边要访问的域名是img.alicdn.com

依旧是上边的第7步:

7)img.alicdn.com查找自己的ZONE文件,发现了一条CNAME记录,指向的是img.alicdn.com.danuoyi.alicdn.com.,通过dig img.alicdn.com可以得到这样的结果:

img.alicdn.com.     51969   IN  CNAME   img.alicdn.com.danuoyi.alicdn.com.

8)LDNS得到的不是具体的IP地址,即不是A记录,而是一条CNAME记录,别名地址是img.alicdn.com.danuoyi.alicdn.com.,所以LDNS重复上边的几步,不再细说,最终得到img.alicdn.com.danuoyi.alicdn.com.对应的其中一个IP地址返回给LDNS

这里需要细说的就是CDN的核心原理部分,也就是怎么从img.alibaba.com.danuoyi.tbcache.com.得到真正的离用户“近”的CDN节点的IP地址。

这路里拿一张来自http://www.51know.info/system_performance/cdn/cdn.html的图来看:


阿里是自建CDN的,然后就可以说阿里自己的CDN智能调度器返回了一个合适的IP地址给LDNS(CDN选择优质节点的过程,不一定说一定是最近的,更多的是一个综合策略,例如还会考虑网络成本、流量、源站负载等)。这个IP地址对应的是阿里CDN的其中一个CDN节点,可以说每个节点都可以认为是一个服务器。

CDN网络架构主要有两大部分组成:中心和边缘两部分。中心的话其实也就是CDN网管中心和DNS重定向解析中心,主要负责全局负载均衡;而边缘只要是指的分布在全球各地的节点,主要包含缓存服务器以及负载均衡器等组成。

当用户访问加入CDN服务的网站时,域名解析请求将最终交给全局负载均衡DNS进行处理。全局负载均衡DNS通过一组预先定义好的策略,将当时最接近用户的节点地址提供给用户,使用户能够得到快速的服务。同时,它还与分布在世界各地的所有CDN节点保持通信,搜集各节点的通信状态,确保不将用户的请求分配到不可用的CDN节点上,实际上是通过DNS做全局负载均衡。

对于普通的Internet用户来讲,每个CDN节点就相当于一个放置在它周围的WEB。通过全局负载均衡DNS的控制,用户的请求被透明地指向离他最近的节点,节点中CDN服务器会像网站的原始服务器一样,响应用户的请求。由于它离用户更近,因而响应时间必然更快。

每个CDN节点由两部分组成:负载均衡设备和高速缓存服务器

负载均衡设备负责每个节点中各个Cache的负载均衡,保证节点的工作效率;同时,负载均衡设备还负责收集节点与周围环境的信息,保持与全局负载DNS的通信,实现整个系统的负载均衡。

高速缓存服务器(Cache)负责存储客户网站的大量信息,就像一个靠近用户的网站服务器一样响应本地用户的访问请求。

CDN的管理系统是整个系统能够正常运转的保证。它不仅能对系统中的各个子系统和设备进行实时监控,对各种故障产生相应的告警,还可以实时监测到系统中总的流量和各节点的流量,并保存在系统的数据库中,使网管人员能够方便地进行进一步分析。通过完善的网管系统,用户可以对系统配置进行修改。

总结本章

从上边的分析可以知道,DNS查询得到IP地址还是一个复杂的过程的。主要过程就是通过设备的解析器将要访问的域名发送给各个级别的域名服务器,得到最终的IP地址(这中间可能还会涉及到CDN技术)。

参考:

  • https://zh.wikipedia.org/wiki/%E5%9F%9F%E5%90%8D%E7%B3%BB%E7%BB%9F

  • http://blog.csdn.net/crazw/article/details/8986504

  • http://xdays.me/dns%E5%8D%8F%E8%AE%AE%E8%AF%A6%E8%A7%A3.html

  • http://www.51know.info/system_performance/cdn/cdn.html

  • http://cstdlib.com/tech/2015/08/18/what-is-cdn/

  • http://kb.cnblogs.com/page/121664/

二 建立TCP连接

TCP是一种面向有连接的传输层协议。他可以保证两端(发送端和接收端)通信主机之间的通信可达。他能够处理在传输过程中丢包、传输顺序乱掉等异常情况;此外他还能有效利用宽带,缓解网络拥堵。

建立TCP连接一开始都要经过三次握手,建立连接过程中会涉及TCP的标志位Flag,一共有6种标志:SYN(synchronize同步序号) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急)。还有额外的两个号码:Sequence number(顺序号码) Acknowledge number(确认号码)

三次握手过程:

  1. 第一次握手,请求建立连接,发送端发送连接请求报文,将SYN置为1,产生随机的顺序号seq=x

  2. 第二次握手,接收端收到发送端发过来的报文,由SYN为1可知发送端现在要建立联机。然后接收端会向发送端发送一个SYN为1和ACK为x+1的报文,同时设置了自己随机产生的一个随机的顺序号seq=y

  3. 第三次握手,发送端收到了发送过来的报文,需要检查一下返回的ACK是否是正确的(x+1);若正确的话,发送端再次发送确认包,ACK为y+1,设置顺序号seq=x+1。

发送端在收到接收端返回的ACK,确认后也就意味着连接成功了,就可以发送数据了;而接收端则必须等到发送端发送的ACK确认后才可以发送数据。

在TCP连接建立完成之后就可以发送HTTP请求了。

参考:

  • http://www.seanyxie.com/wireshark%E6%8A%93%E5%8C%85%E5%9B%BE%E8%A7%A3-tcp%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B%E8%AF%A6%E8%A7%A3/

  • http://baike.baidu.com/view/1003841.htm

  • http://www.jellythink.com/archives/705

发送HTTP请求报文和接受HTTP响应报文的过程这里不做描述,接下来看下浏览器缓存的知识

浏览器缓存

根据服务器响应的消息报头,来决定响应的内容是如何缓存的,这里呢就需要探讨下浏览器的缓存机制了。

首先一个要点,为啥要缓存,也就是说缓存有啥好处呢:

  • 减少了数据传输,也就意味着减少网络带宽消耗,省钱

  • 降低服务器压力,大大提高服务器性能

  • 减少网络延迟,加快页面打开速度

有了好处就要看看浏览器是如何缓存的。

浏览器缓存规则

对于浏览器缓存而言,规则主要是在HTTP的消息报头和HTML页面的Meta标签中定义的。有新鲜度校验值两个维度来定义缓存的具体细则的。

  • 新鲜度,其实也就是过期机制,指定一个有效期。

  • 校验值,主要是当发现不再新鲜的时候,用于再次请求的时候的校验机制,发现校验的结果不匹配的话就说明需要更新了,匹配的话就直接返回304状态码,代表没有修改。

浏览器缓存控制

之前在规则中说过,对于控制可以写在HTML页面的Meta标签中,例如:

<META HTTP-EQUIV="Pragma" CONTENT="no-cache">

上边的代码就是告诉浏览器页面不缓存,但是这个支持情况不佳,而且缓存代理服务器肯定不支持,所以说不推荐。

下边重点来看和缓存相关的HTTP消息报头:

HTTP缓存相关消息报头

从上图可以看出两种不同的规则都对应的会有哪些消息报头,以及对应的类型和作用。这里主要细说的就是两组:

  1. Cache-Control与Expires

  2. Last-Modified与ETag

来看第一组,Cache-Control与Expires,他们的作用是一致的,都是控制有效期的。Expires的值是一个确定的日期时间,这个时间是格林威治时间(GMT),表明在这个日期时间之前都是可以使用缓存内容的,容易产生日期时间不一致(不同步)问题;而Cache-Control则可以控制更多优先级高于Expires。

这里仔细看下Cache-Control有用的响应头:

  • max-age=[秒]:表示在这个时间范围内缓存是新鲜的无需更新。类似Expires时间,不过这个时间是相对的,而不是绝对的。也就是某次请求成功后多少秒内缓存是新鲜的。

  • s-maxage=[秒]:类似max-age, 除了仅应用于共享缓存(如代理)。

  • public:标记认证的响应才能够被缓存。一般而言,需要认证的HTTP请求内容会自动私有化(不会被缓存)。

  • private:允许缓存专门为某一个用户存储响应,比方说在浏览器中;共享缓存一般不会,例如在代理中。

  • no-cache:每次在释放缓存副本之前都强制发送请求给源服务器进行验证,这在确保认证有效性上很管用(和public结合使用)或者保证内容必须是即时的,不得无视缓存的所有优点,如国内的微博、twitter等的刷新显示内容,必须不能有缓存啊。

  • no-store:强制缓存在任何情况下都不要保留任何副本。

  • must-revalidate:告诉缓存,我给你准备了一些关于新鲜度的信息,在表现的时候要严格遵循之。HTTP允许缓存在某些特定情况下返回过期数据,指定了这个属性,相对于告诉缓存,你丫必须严格遵循我的规则。

  • proxy-revalidate:类似must-revalidate,除了只能应用于代理缓存。

来一张公有缓存和私有缓存的区别图:


然后再看另一组Last-Modified与ETag,Last-Modified表明服务器该资源最后的修改时间,用于让浏览器知道本地缓存中副本是否是新鲜的,那为啥还需要ETag呢,主要是为了解决这几个问题:

  1. 某些服务器不能精确得到文件的最后修改时间,这样就无法通过最后修改时间来判断文件是否更新了。

  2. 某些文件的修改非常频繁,在秒以下的时间内进行修改,Last-Modified只能精确到秒。

  3. 一些文件的最后修改时间改变了,但是内容并未改变,此时该文件的缓存就无法被使用。

所以在HTTP1.1中加入了ETag,实体标识,他是服务器自动生成或者由开发者生成的对应的资源在服务器端的唯一标识。只有内容发生了改变这个值才会改变,这个值是类似于对文件进行MD5或者SHA1之后的结果。

那他们两组又会有啥子区别呢?下边请看:

  • 配置Last-Modified/ETag的情况下,浏览器再次访问统一URI的资源,还是会发送请求到服务器询问文件是否已经修改,如果没有,服务器会只发送一个304回给浏览器,告诉浏览器直接从自己本地的缓存取数据;如果修改过那就整个数据重新发给浏览器;

  • Cache-Control/Expires则不同,如果检测到本地的缓存还是有效的时间范围内,浏览器直接使用本地副本,不会发送任何请求。

两组一起使用时,Cache-Control/Expires的优先级要高于Last-Modified/ETag。即当本地副本根据Cache-Control/Expires发现还在有效期内时,则不会再次发送请求去服务器询问修改时间(Last-Modified)或实体标识(Etag)了。一般情况下,使用Cache-Control/Expires会配合Last-Modified/ETag一起使用,因为即使服务器设置缓存时间,当用户点击“刷新”按钮时,浏览器会忽略缓存继续向服务器发送请求,这时Last-Modified/ETag将能够很好利用304,从而减少响应开销。

而对于浏览器缓存如何才能命中呢?这个根据不同的行为还有不同的结果,请看下图:



如果之前对两组的对比中说的那样,当按F5或者点击刷新的时候,会忽略Cache-Control/Expires的设置,也就是说会再次去向服务端请求,而Last-Modified/Etag还是有效的,服务器会根据情况判断返回304还是200,但是如果只有Cache-Control/Expires的话,服务端就不知道如何check,所以会返回完整资源了;而当用户使用Ctrl+F5进行强制刷新的时候,只是所有的缓存机制都将失效,重新从服务器拉去资源。

需要注意的是上边说的控制缓存的那些方法规则对于POST请求则无效的,因为POST请求是无法被缓存的;如果说HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的话,请求也无法被缓存。

参考:

  • http://www.alloyteam.com/2012/03/web-cache-2-browser-cache/

  • http://www.cnblogs.com/TankXiao/archive/2012/11/28/2793365.html

  • http://www.path8.net/tn/archives/2745

  • http://www.zhangxinxu.com/wordpress/2013/05/caching-tutorial-for-web-authors-and-webmasters/

关于浏览器如何解析渲染页面,可以参考这篇文章
http://blog.aijc.net/server/2015/11/03/%E4%BB%8E%E8%BE%93%E5%85%A5URL%E5%88%B0%E9%A1%B5%E9%9D%A2%E5%8A%A0%E8%BD%BD%E5%AE%8C%E7%9A%84%E8%BF%87%E7%A8%8B%E4%B8%AD%E9%83%BD%E5%8F%91%E7%94%9F%E4%BA%86%E4%BB%80%E4%B9%88%E4%BA%8B%E6%83%85/

下面主要谈谈这些步骤中可能存在的性能问题(http://www.kuqin.com/shuoit/20150104/344230.html)

  1. 如果你对DNS的查询还有印象的话现在反思一下,DNS Lookup就是为了获取一串IP地址要和无数个DNS服务器进行通信,这要消耗多少时间?别忘了你查询完了的时候你还没和那边的服务器通信呢。
  2. TCP连接要三次握手,如果服务器很远的话这三次握手要花多少时间?别忘了建立连接之后你还没发请求呢。(通常到这里0.5秒就出去了)
  3. 发送HTTP请求的时候你要知道一点就是我们的网络带宽上行和下行通常是不一样的,通常上行的带宽会小一些,一个的话还好,但是现在的网页通常都会后续请求很多资源,带宽小的时候上行拥塞怎么办?别忘了已经到第三步了,服务器还没给你发响应呢,现在你的浏览器还什么都画不出来。
  4. 终于到了服务器发响应了,不巧你访问的这个服务器比较忙,好几万个人都要这个资源,服务器的上行带宽也是有限的,怎么办?

我觉得我出了几道还不错的面试题。顺便提一下,前两步的延迟和网络带宽的影响不大;后两步加带宽是能一定程度缓解,不过你要有钱,而且很贵。虽说博主做过Webkit本地渲染的优化,但是深知网页加载的主要时间还是浪费在网络通信上,所以在这些步骤上的优化会比你在浏览器内核的优化省力且效果明显。

网络方面的主要优化手段,博主总结一下不外乎缓存,预取,压缩,并行。以后如果再有面试问性能优化之类的问题,大家都可以照着这个思路去考虑,下面就分阶段介绍一下现有的优化手段。

DNS 优化

对于DNS优化,缓存无疑是最简单粗暴且效果明显的了。说到缓存就一定要提到缓存层级:

  1. 浏览器DNS缓存,chrome可以看 chrome://net-internals/#dns

  2. 系统DNS缓存

  3. hosts文件,墙里的小伙伴们应该有印象

  4. 各个DNS服务器上的缓存

当然DNS缓存失效期通常都比较短,很多情况下都要再去查找,为了降低用户体验到的延迟(注意这里不是网络延时)预取是一个不错的方法。比如说你敲网址的时候还没有敲完,但是浏览器根据你的历史发现你很有可能去访问哪个网站就提前给你做dns预取了,比如你打了一个“w”的时候,chrome已经帮你去找weibo.com的ip地址了。chrome用户可以看一下 chrome://predictors/ 你就知道了。

此外浏览器还会记录你过去的历史知道每个域名下通常还会有哪些其他的链接建立起网站的拓扑结构,当你访问这个域名下的网站他就会预先对其他链接的域名进行DNS解析可以参照 chrome://dns/。

TCP 优化

看到前面的DNS的具体优化这么繁杂,知道这简单的一步没那么简单了吧。结果到TCP这一步优化反而简单了,因为刚才dns已经把ip都预先弄到了那么我们顺着刚才的步骤再建立连接就好了。所以在你敲第一个字母的时候dns解析完了就去建立连接了,这时候你可能网址还没敲完。当你刚访问一个网站的时候浏览器刷刷刷的帮你把到别的服务器的TCP连接给你建好。

HTTP传输优化

写到这里可能有人会想,既然已经把TCP连接建立好了,那我干脆预取更进一步,把所有的链接内容直接预取下来不就好了,这样我网址还没敲完网页就已经加载完成了。这个想法是好的,但现实却是残酷的。因为要记住我们的带宽是有限的,DNS和TCP连接量级都比较轻,对网络带宽不会占据太多,但是HTTP传输就不一样了如果你所有链接都去预取的话你的带宽很快就被占满了,这样你正常的请求无法得到满足,性能反而会严重下降。

缓存就又出现了,提缓存必提层次结构。

  1. PageCache 这个是最快的了,直接在内存中缓存了现有网页的dom结构和渲染结果,这就是你为什么在点前进后退的时候会这么快。

  2. HTTP Cache 文件级别的Cache存在本地的文件系统上按照RFC2616实现。

  3. 代理Cache 如果是通过代理服务器上网的话,代理服务器通常也会按照缓存标准

  4. CDN 一个地理上离你很近的内容服务器,比如说你在北京请求杭州淘宝的一个图片,结果在北京的一个CDN上有这个图片,那么就不用去杭州了。

  5. DMOC(distributed memory object caching system)CDN主要存放的是静态数据,但是网页中通常有很多动态的数据需要查数据库,流量多了压力就会很大,通常服务器外围还会有一层内存缓存服务器,专门缓存这些数据库中的对象,据《淘宝技术这10年》称可以减少99.5%的数据库访问。

  6. Server 其实真正落在服务器上的请求已经不多了。

大家看到这里有没有想到能在什么地方再加一层缓存呢?其实可以在2和3之间加,也就是在路由器上加缓存。小米的路由器和搜狗合作的预取引擎其实就相当于是在路由器上加一层缓存款顺便智能预取一下。博主为什么在这里另起一段专门谈小米呢,难不成是小米的水军?才不是呢,是因为博主看到这个消息的时候心都凉了,和博主的毕设撞车了有木有。去年在360刚出随身WiFi的时候博主想到了这么个点子,还想着把这个东西做出来之后用这个创业和360谈合作。结果最近刚做完,论文也投出去了,幻想着开启人生巅峰,颠覆行业结果就发现小米和搜狗出了这么个一样的东西还都商业化了。说好的人生巅峰就这样没有了,早知道去年就先申请个专利了。

另一个HTTP常用的优化就是压缩了,网络传输时间 = 消息大小/网速 既然网速比较贵那么就压缩一下吧,大部分服务器都会对HTTP消息进行gzip压缩。可以在Http Header中看到,具体的就不细说了。

未来协议 SPDY

上面的都是传统做法,下面讲一个未来的技术。由于HTTP协议是上个世纪制定的协议了,已经不能很好的适应现在Web的发展,所以Google提出了SPDY协议目前是指定中的HTTP2.0标准的一个底版。SPDY主要有下面的特点:

  1. 一个TCP连接上并行多个HTTP连接,减少连接的建立时间

  2. 请求优先级(目前还没看到具体实现)

  3. HTTP头部压缩,上文提到的HTTP压缩是对HTTP body的压缩,并没有对头部压缩。对于小的HTTP消息,头部的比重还是很大的,而现在的web中存在大量小消息。

  4. Server push/hint 服务器主动推送对象(可以想象成服务器帮客户端预取)

业界目前对SPDY是有赞有弹,博主也持谨慎的态度。主要在1和4上,4其实和之前提到的HTTP直接预取的矛盾点一样,万一推送的不需要又占据了带宽怎么办,hint到底该如何实现都有困难。第一条潜在的风险就是TCP连接中途断开,那么所有的连接就全部停掉了,PC互联网这种情况可能会少一些,但是移动互联网中TCP连接断开的情况还是比较常见的。不过作为一个未来的技术还是有必要关注一下。

总结

上面就是博主对”从输入 URL 到页面加载完的过程中都发生了什么事情“两端之间网络连接这块所知道的事情还有优化措施,欢迎大家来拍砖。对于浏览器端到底做了些什么博主其实也很熟,只是这一块已经有很多成熟的资料了比如这里,这里和这里想写点不一样的东西太难了。服务器端的事情博主就不是太清楚了,还请大家多多指教。









0 0
原创粉丝点击