浅谈一次URL请求过程

一、前言

之前对浏览器到服务器端的过程不是很清晰,后来浏览了一些大牛的博客,有一些感悟,怕自己忘记,所以记录在自己的博客中。也希望能够给看到这篇博客的人一些帮助。

二、过程

1、当我们在浏览器中输入URL时,发生了什么?
浏览器会有自己的缓存。当我们在浏览器中输入内容的同时浏览器也会通过浏览器自身的搜索引擎根据用户输入的字符将匹配到的自己缓存中的内容显示在下拉框中,甚至能够将缓存在浏览器中的页面直接显示出来而不需要按下回车,这些是浏览器内核进行加工渲染的。浏览器缓存的内容通常都是用户经常访问的数据或者近期访问的数据且没有失效以及书签中的内容。
URL

而在输入过程中会发生两种情况:

  • 用户输入的是正常的能够访问的域名,也就是以字母、数字、标点符号组成的URL
  • 用户输入的是不能正常访问的域名,也就是不遵守规范随意输入的字符串

如果是是第一种情况,会进行 2 步骤。如果是第二种情况,那么浏览器就会提取出用户输入的某些关键字交给默认搜索引擎,根据默认搜索引擎直接搜索这些关键字。

2、当我们输入URL并按下回车后,发生了什么?
这里以用户输入正常URL并且没有被浏览器缓存命中来说。这时,浏览器就会获取以下信息:

  • 请求协议,http/https
  • 请求资源主页,如:www.baidu.com

浏览器默认为http协议,而且如果服务器端开启了ssl协议,那么通过重定向,整个连接过程也会自动跳转到https协议上,而如果服务器端没有开启ssl协议,那么就算用户专门输入了https也没用。更何况,用户也通常不会专门在URL前面加上https前缀。所以这里以http为例。

DNS查询

  • 当浏览器得到URL后,会检索自身DNS缓存。如果有,会通过该URL所对应的IP直接向该IP发起请求。
  • 如果没有,会检索操作系统的缓存。这一过程是通过调用库函数完成的,不同的操作系统调用的也是不同的库函数。
  • 如果操作系统中的缓存也没有,那么该库函数会检索在本地磁盘中的hosts文件。(不论是windows还是Linux,都是hosts文件)。
  • 如果本地磁盘中的hosts文件中也没有,则发起DNS请求

DNS请求
在操作系统中,如果以动态方式获取的IP,那么DHCP服务器不仅会给你分配IP,子网掩码,网关,还会给你分配DNS服务器并缓存在操作系统磁盘中。这里以CentOS为例。

  • 如果动态获取IP,那么DNS服务器列表会缓存在/etc/resolv.conf
  • 如果静态配置IP,那么则要手动配置DNS服务器地址,不然不能解析URL。也可以将需要解析的URL所对应的IP写在相应的配置文件中。

而查询DNS服务器也分为两部分:

  • DNS服务器与本地主机在同一个网段中,则直接进行ARP查询
  • DNS服务器与本地主机不在同一个网段中,则ARP本地网关,由网关去找寻DNS服务器

ARP 过程
ARP(地址解析协议),能够在本地广播请求所需要的IP对应的MAC地址。当客户端需要向局域网的某一个主机发送报文时,就需要向局域网每一台主机广播 FF:FF:FF:FF:FF:FF (二进制全1)为地址的报文,询问 192.168.38.11 的MAC地址是什么?(来源于维基百科)。如果 192.168.38.11 所在地址的主机收到消息后则会进行响应,但是这个响应是单播的。
当然,如果DNS服务器与本机在同一个网段则广播的是DNS服务器的MAC地址,如果不在本地则广播的网关的MAC地址。

当收到网关的ARP响应后,会将DNS请求直接通过UDP协议进行封装后发送给网关,由网关进行转发发送给DNS服务器。

DNS解析
这里就涉及到DNS: Domain Name System(域名系统)的工作原理了。DNS查询有两种方式:递归和迭代。DNS客户端设置使用的DNS服务器一般都是递归服务器,它负责全权处理客户端的DNS查询请求,直到返回最终结果。而DNS服务器之间一般采用迭代查询方式。

以查询www.wikipedia.org为例:
http://igoro.com/wordpress/wp-content/uploads/2010/02/500pxAn_example_of_theoretical_DNS_recursion_svg.png

  • 客户端发送查询报文”query www.wikipedia.org”至DNS服务器,DNS服务器首先检查自身缓存,如果存在记录则直接返回结果。
  • 如果记录老化或不存在,则DNS服务器向根域名服务器发送查询报文”query wikipedia.org”,根域名服务器返回.org域的权威域名服务器地址,这一级首先会返回的是顶级域名的权威域名服务器。
  • DNS服务器向 .com 域的权威域名服务器发送查询报文”query www.wikipedia.org”,得到.wikipedia.org域的权威域名服务器地址。
  • DNS服务器向.baidu.com域的权威域名服务器发送查询报文”query www.baidu.com”,得到主机www的A记录,存入自身缓存并返回给客户端。

以上就是域名服务器之间迭代的过程。这是基于504个全球范围的“根域名服务器”(分成13组,分别编号为A至M)。从这504个根服务器开始,余下的Internet DNS命名空间被委托给其他的DNS服务器,这些服务器提供DNS名称空间中的特定部分(来自维基百科)。

内核协议栈
当浏览器得到了目标的IP地址后,会与服务器进行TCP/IP三次握手建立TCP/IP的持久连接。这里不做过多的描述,网上这样的信息太多。以建立TCP/IP连接之后为基础,首先在本地通过HTTP协议生成一个请求报文。
请求报文由方法,URL,HTTP版本和HTTP首部字段等构成;

通用首部

通用首部(General)是请求与响应首部都会用到的首部,如请求方法,请求URL,响应状态码,请求的远程地址,首部用来监管哪些访问来源信息等。

请求首部

在请求首部中,通常都会加上请求的附加内容(浏览器所支持的媒体类型,编码格式),客户端的信息,响应内容相关的优先级等信息。

当请求报文生成后,会发生以下操作:

用户空间:

  • 浏览器进程会调用socket函数对象,创建套接字,通过socket函数绑定套接字
  • 通过调用sendto函数,将用户空间内存中的数据一点一点发送至内核空间

内核:

  • 浏览器将请求报文下发送至传输层,传输层会将报文封装成TCP段,加上目标端口与源端口。源端口是由内核随机选取的一个动态端口。
  • 报文从传输层下发至网络层,会将报文封装成数据包,在外面加上目标IP与源IP。并选择路由。
  • 报文从网络层下发至数据链路层,会将报文封装成帧,在外面加上目标MAC与源MAC
  • 当报文到达链路层之后会通过网卡驱动将数据包发送到网卡的发送队列中,通过中断通知网卡发送数据包

服务器

服务器端的网卡收到报文后,通过网卡驱动将数据包发送至内核中,内核通过一层一层解析,通过socket套接字与端口送达至监听在该端口的进程。

服务器端监听的的程序如果是Linux,则一般为Apache和Nginx,如果是Windows则为IIS。这里以Nginx为例。

  • Nginx接收到客户端的动态请求,会将该请求转发至后端的Perl/PHP/Python/Ruby..中去执行,如果需要调用数据内容则可能去后端的数据库中取数据,执行完成之后将执行结果发送至Nginx。(这里可能不完整,但是这不是讲解的集群,所以不在这里做过多的解释)
  • 如果是静态请求,则会转发至后端的专门的静态服务器中。如果缓存中有数据,则会直接从缓存中取数据。如果缓存中没有数据,那么如果是关系型数据,则会去数据库中取,如果是图片或者其他非关系型数据库,则会去对应的共享存储中取。

服务器端在第一次请求返回的数据一般都是一个整体的html框架,里面的所有数据,包括图片、html文档、txt文档、css样式等等所有的东西都是以链接的形式呈现在浏览器中(当然,网站的logo,或者其他重要数据或者图片可能在第一次就已经发送过来了),浏览器进行分析后再次去向相应的服务器发送请求,当然,这里的服务器可能是一个完整的集群。一般现在的浏览器都是多线程的,可以并发去请求。根据带宽的不同,浏览器的不同以及服务器端的响应速度的不同,一般请求在3-5s就会在浏览器中将请求页面呈现出来。如果有缓存(浏览器或者服务器端)可能会更快。所以,这些过程对于用户来说就是那么几秒钟的事情,但是背后的机制却是无比复杂。

以上便是我所理解的一次URL请求过程,其中有一些不详细或者有误的过程,如函数调用,内核协议栈,中断处理上。以后有充分的认识之后会不断完善。

–end–

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值