当你在浏览器输入一个网址,回车后究竟发生了什么?

当你在浏览器输入一个网址回车后究竟发生了什么?其实这可以作为一个面试题来考察候选人了,我也被问过类似的问题,这里书面化下,方便记忆。

首先分析下这个问题想要问的是什么,其实这个问题可以回答的很深,也可以回答的很浅,这里按我个人的思路来回答,结合图表方便理解。
当你在浏览器输入一个网址,回车后究竟发生了什么?

  • 1、浏览器做了什么?
浏览器接收到用户输入的地址后做了什么,可以通过chrome的一个工具timing来看,往往这也是分析一个页面的性能的一个辅助工具,以我在浏览器输入的网址为:http://cxf.apache.org/docs/cxf-architecture.html为例,timing结果如图:
当你在浏览器输入一个网址,回车后究竟发生了什么?
第一步Resource Scheduling,也就是资源调度,可以把这个操作看成一个JOB,浏览器有个任务队列,要先将这个JOB放到Queue里,图中可以看出从放入队列到被调度执行中间隔了23.56毫秒。

第二步Connection Start,也就是建立连接,其中又分为好几步,Stalled里是检查浏览器有没有设置网络代理,有没有可以用的连接,DNS Lookup是DNS查询,而Initial connection则显示了从开始检查代理,获取连接,DNS查询,TCP握手,到建立好TCP连接的总时间。

第三步Request/Response,这个就是我们最关心的了,这里包括请求的发送,等待后端的响应,下载当前资源文件。Request sent就是上传请求,这里有很多可以再细讲的东西,但这些想想其实都是HTTP协议里的内容了,就不在这里多说了,后面再单独写篇谈谈。接下来详细猜下Waiting(TTFB)里做了什么。

  • 2、服务器做了什么?
服务器做了什么也是因情况而定的,有的很简单,有的则比较复杂,这里常规的谈谈。

1)服务器防火墙,这里是为了保护服务而设置的,这里可以有效的拒觉不合理的请求,让服务可以正常地给需要的人使用,但并不是所有的网站都存在。

2)域名服务器,还以上面我在浏览器中输入的地址为例,cxf是apache.org的子域名,请求先到apache.org,再通过域名服务器查找cxf.apache.org的真正IP,再根据IP找到对应的服务器。

3)负载均衡器,一般为了能够为更多的用户服务,一个域名背后可能是多个服务器,那么一次请求最终由谁来处理,这就由负载均衡来决定。负载均衡其实也有好多可以聊的,这个也后面单独写文章聊吧,比方如何处理带session的,各种负载均衡算法的适用场景,常用的负载均衡工具(硬件负载均衡与软件负载均衡)。

4)Servlet容器/Web容器,有些应用是直接使用的Servlet容器,把页面用类似velocity的模板引擎来转换,这就带来一个问题,一次请求这些Document就要经过Servlet容器来传输,可想servlet的负担就重了。一些聪明点的应用就会在Servlet容器前再放一个Web容器,比如Apache或Nginx或者Node,把不变的Document放在Apache上,把只需要变化的数据让Servlet来处理。

5)缓存服务,主要因为磁盘和内存的读写速度相差太多数量级,所以将数据区分冷热,冷的放磁盘,热的放内存。但缓存设计的好与不好起决定性作用,命中率高则可以改善系统的响应速度,命中率低则形同虚设。

6)数据库,负责数据的持久化,用户的一些数据有些时候是需要保存下来,这里就要有可用性的设计了,讲白了就是一个专门保存文件的机器,同时还提供查询和更新文件的功能,为了有效的管理,形成了专门的应用:数据库。

7)搜索引擎,这其实也算是“数据库”的一种形态了,只不过它的专长是查询,查找文件特别快,主要还是因为最开始设计的管理文件的应用在数据量大了以后各种问题都出来了,这才有了搜索引擎,搜索引擎的索引设计和数据库的索引设计比起来明显简单很多。

  • 3、浏览器接收到Respone后又做了什么?
其实浏览接收到Document内容后还做了一些事情,这些其实是前端可以优化页面的地方,包括资源文件的下载,文档的解析与页面的渲染,还有CDN起到的作用。

1)浏览器的线程,浏览器下载documet会边下载边解析,当然可能不是同一个线程来做,比如document里引入了CSS和JS还有图片这些资源,那么浏览器会起多线程的方式来下载这些资源文件。

2)先下载CSS,由于页面是依赖CSS来渲染出来的,所以如果想要页面早一点被渲染,那就要让CSS早一点下载完,CSS下载完后还要生成样式。

3)减少下载次数,合并下载可以有效地减少网络建立带来的耗时,JS可以合并、CSS可以合并、图片也可以合并。

4)减少下载内容,压缩资源文件可以减少带宽耗时。

5)利用CDN缩短请求链路,静态资源文件和多媒体文件尽量放CDN上,请求优先访问CDN,当然这个是有一定成本的,而且如果内容有更新还要同步推送更新到CDN,但是现在CDN运营商比较多,网络覆盖也比较广。

  • 4、从网络知识的角度分析
1)浏览器与服务器创建TCP请求连接,因为在网络中标识主机的是MAC地址,MAC地址和IP的相互转换是通过ARP和RARP,TCP的报文会由网络中的路由器传递到指定的主机中,每个路由器都有一份路由表。这个有点像寄快递,每个地方的邮编就像是IP(当然现在邮编的用处可能已经在淡化),邮编又对应着具体的地址,邮局的中转站对应的是路由器,包裹就是TCP报文,当包裹到一个中转站时,是中转站会判断这个包裹要发往的下个站点是哪,而路由器判断的标准则是路由表,路由表信息会实时更新,当然,实际路由器中的路由算法还是比我说的要复杂的。服务器接收到TCP报文的字节码后会拆包,将报文组装成对应的协议,这里是需要约定编码方式的,但这在HTTP协议里已经有了,服务器需要按照协议来解码。当然,寄一次快递是单向的数据流,而一次HTTP请求是有Response的,有点像现实生活中快递包裹被拒收退会,再次流转到寄件人手中。当然这个比喻不是很精准,因为计算机网络中要比寄快递流程复杂多的多。

2)Java一般都是将HTTP再转成Servlet对象来处理的,这也是为什么会有Tomcat/Jetty等应用容器了,通常Servlet对应的不是单次的HTTP请求,Servlet中还有Session,这也是为什么要有Servlet的原因。

3)实际中服务器的网络也是比较复杂,尤其在有了云计算和虚拟化技术后,对于虚拟化技术中的网络问题目前还在持续探索中,可能还有很多比当前共享的方式还好的方法,但有时候成本还是很重要的,并不是所有的技术都适合应用,决定能否应用的重要因素是成本在接收范围内。

4)可能的性能瓶颈:带宽、网卡、DNS服务器、负载均衡、磁盘操作、等等

  • 5、在IOT应用中发生了什么?
刚毕业时帮一个同事做了一个毕业设计的demo,大方向是智能家居相关,但实际只做了一个简单的Demo,最终实现的效果就是一个开发板和电脑相连,在电脑的浏览器中输入一个网址,网页上有个按钮,点一下这个按钮,就可以把灯关闭或开启。这里其实就和上面有所不同了,后面其实并没有上面那么复杂的结构,没有服务器,也没有操作系统,开发板还是一个51单片机开发板,这里输入网址后就比较简单,单片机只需要对网络流中的内容进行相应的解析和返回,不存在Servlet,返回页面也是直接拼出来的Document,代码写死的,这里就是单片机直接和网卡交互了,然后就按照网络里的各个协议进行解析和组装,最后响应的其实就是一个PORT口,用高低电平也就是0和1来控制外设,外设用的继电器,从而达到使灯关闭和打开。
上一篇:报名通道开启!原生安全二倍速:探秘基础设施的内生“免疫系统"


下一篇:探秘Java9