HTTP协议 & DNS协议

博客主页编程

http://restapi.amap.com 是个URL,叫做统一资源定位符。HTTP称为协议,restapi.amap.com是一个域名,表示互联网上的一个位置。json

HTTP版本区别

HTTP/0.9 只支持get请求segmentfault

HTTP/1.0 增长版本号,请求头,MIME,代理链接api

HTTP/1.1 默认持久链接,支持缓存,执行管道方式发送多个请求浏览器

HTTP请求的准备

浏览器会将restapi.amap.com这个域名发送给DNS服务器,让它解析为IP地址。那接下来是发送HTTP请求吗?缓存

不是的,HTTP是基于TCP协议的,固然是要先创建TCP链接了,怎么创建呢?Socket网络编程 已经详细讲解了。服务器

目前使用的HTTP协议大部分都是1.1。在1.1的协议里面,默认持久链接,也就是默认开启了Keep-Alive的,这样创建的TCP链接,就能够在屡次请求中复用。网络

学习了TCP以后,你应该知道,TCP的三次握手和四次挥手,仍是挺费劲的。若是好不容易创建了链接,而后就作了一点儿事情就结束了,有点儿浪费人力和物力。并发

HTTP请求的构建

创建了链接之后,浏览器就要发送HTTP的请求。app

请求的格式以下:

HTTP的报文大概分为三大部分。第一部分是请求行,第二部分是请求的首部,第三部分才是请求的正文实体

GET /v3/weather/weatherInfo?city=110101&key=13cb58f5884f9749287abbead9c658f2 HTTP/1.1
Host: restapi.amap.com

第一部分:请求行

在请求行中,URL就是请求的地址 ,版本为HTTP 1.1。方法有几种类型,最经常使用的类型就是GET。

GET就是去服务器获取一些资源。另一种类型是POST,它须要主动告诉服务端一些信息,而非获取,通常会将信息放在正文里面,正文能够有各类各样的格式,常见的格式也是JSON。

还有一种类型叫PUT,就是向指定资源位置上传最新内容。可是,HTTP的服务器每每是不容许上传文件的,因此PUT和POST就都变成了要传给服务器东西的方法。

再有一种常见的就是DELETE这个顾名思义就是用来删除资源的。

第二部分:首部字段

首部是key: value,经过冒号分隔。这里面,每每保存了一些很是重要的字段。

如,Accept-Charset,表示客户端能够接受的字符集。防止传过来的是另外的字符集,从而致使出现乱码。

如,Content-Type是指正文的格式。咱们进行POST的请求,若是正文是JSON,那么咱们就应该将这个值设置为JSON。

Content-Type: application/json

如,Content-Length是指正文的长度

Content-Length: 0

接下俩重点说一下的就是缓存

为何要有缓存呢? 使用缓存能够减小冗余的数据传输,节省了网络费用;还能够缓解网络瓶颈的问题,不须要更多的网络宽带就能更快的加载页面,同时下降了对原始服务器的要求,服务器能够更快的响应。

例如,我浏览一个商品的详情,里面有这个商品的价格、库存、展现图片、使用手册等等。商品的展现图片会保持较长时间不变,而库存会根据用户购买的状况常常改变。若是图片很是大,而库存数很是小,若是咱们每次要更新数据的时候都要刷新整个页面,对于服务器的压力就会很大。

对于这种高并发场景下的系统,在真正的业务逻辑以前,都须要有个接入层,将这些静态资源的请求拦在最外面。


对于静态资源,有Vanish缓存层。当缓存过时的时候,才会访问真正的Tomcat应用集群。

在HTTP头里面,Cache-control是用来控制缓存的。当客户端发送的请求中包含max-age指令时,若是断定缓存层中,资源的缓存时间数值比指定时间的数值小,那么客户端能够接受缓存的资源;当指定max-age值为0,那么缓存层一般须要将请求转发给应用集群。包含no-cache指令时,无缓存指令(Cache-control: no-cache)。

另外,If-Modified-Since也是一个关于缓存的。也就是说,若是服务器的资源在某个时间以后更新了,那么客户端就应该下载最新的资源;若是没有更新,服务端会返回“304 Not Modified”的响应,那客户端就不用下载了,也会节省带宽。同Last-Modified

If-None-Match 客户端存取的该资源的检验值,在服务器上某个时段是惟一标识的。同ETag

到此为止,咱们仅仅是拼凑起了HTTP请求的报文格式,接下来,浏览器会把它交给下一层传输层。怎么交给传输层呢?其实也无非是用Socket这些东西,只不过用的浏览器里,这些程序不须要你本身写,有人已经帮你写好了。

HTTP请求的发送

HTTP协议是基于TCP协议的,因此它使用面向链接的方式发送请求,经过stream二进制流的方式传给对方。固然,到了TCP层,它会把二进制流变成一个的报文段发送给服务器。

在发送给每一个报文段的时候,都须要对方有一个回应ACK,来保证报文可靠地到达了对方。若是没有回应,那么TCP这一层会进行从新传输,直到能够到达。同一个包有可能被传了好屡次,可是HTTP这一层不须要知道这一点,由于是TCP这一层在埋头苦干。

TCP层发送每个报文的时候,都须要加上本身的地址(即源地址)和它想要去的地方(即目标地址),将这两个信息放到IP头里面,交给IP层进行传输。

IP层须要查看目标地址和本身是不是在同一个局域网。若是是,就发送ARP协议来请求这个目标地址对应的MAC地址,而后将源MAC和目标MAC放入MAC头,发送出去便可;若是不在同一个局域网,就须要发送到网关,还要须要发送ARP协议,来获取网关的MAC地址,而后将源MAC和网关MAC放入MAC头,发送出去。

网关收到包发现MAC符合,取出目标IP地址,根据路由协议找到下一跳的路由器,获取下一跳路由器的MAC地址,将包发给下一跳路由器。

这样路由器一跳一跳终于到达目标的局域网。这个时候,最后一跳的路由器可以发现,目标地址就在本身的某一个出口的局域网上。因而,在这个局域网上发送ARP,得到这个目标地址的MAC地址,将包发出去。

目标的机器发现MAC地址符合,就将包收起来;发现IP地址符合,根据IP头中协议项,知道本身上一层是TCP协议,因而解析TCP的头,里面有序列号,须要看一看这个序列包是否是我要的,若是是就放入缓存中而后返回一个ACK,若是不是就丢弃。

TCP头里面还有端口号,HTTP的服务器正在监听这个端口号。因而,目标机器天然知道是HTTP服务器这个进程想要这个包,因而将包发给HTTP服务器。HTTP服务器的进程看到,原来这个请求是要访问一个网页,因而就把这个网页发给客户端。

HTTP返回的构建

HTTP的返回报文也是有必定格式的。这也是基于HTTP 1.1的。

HTTP/1.1 200 OK
Server: Tengine
Date: Thu, 26 Dec 2019 06:52:14 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 252
Connection: close
X-Powered-By: ring/1.0.0
gsid: 011025248187157734313415200030229349471
sc: 0.006
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,key,x-biz,x-info,platinfo,encr,enginever,gzipped,poiid

{"status":"1","count":"1","info":"OK","infocode":"10000","lives":[{"province":"北京","city":"东城区","adcode":"110101","weather":"晴","temperature":"2","winddirection":"西","windpower":"≤3","humidity":"23","reporttime":"2019-12-26 14:36:44"}]}

状态码会反应HTTP请求的结果。“200”意味着请求成功;而“404”,也就是“服务端没法响应这个请求”

而后就是返回首部的key: value
其中Retry-After表示,告诉客户端应该在多长时间之后再次尝试一下。“503错误”是说“服务暂时再也不和这个值配合使用”。

在返回的头部里面也会有Content-Type,表示返回的是HTML,仍是JSON。

构造好了返回的HTTP报文,接下来就是把这个报文发送出去。仍是交给Socket去发送,仍是交给TCP层,让TCP层将返回的HTML,也分红一个个小的段,而且保证每一个段均可靠到达。

这些段加上TCP头后会交给IP层,而后把刚才的发送过程反向走一遍。虽然两次不必定走相同的路径,可是逻辑过程是同样的,一直到达客户端。

客户端发现MAC地址符合、IP地址符合,因而就会交给TCP层。根据序列号看是否是本身要的报文段,若是是,则会根据TCP头中的端口号,发给相应的进程。这个进程就是浏览器,浏览器做为客户端也在监听某个端口。

当浏览器拿到了HTTP的报文。发现返回“200”,一切正常,因而就从正文中将HTML拿出来。HTML是一个标准的网页格式。浏览器只要根据这个格式,展现出一个绚丽多彩的网页。

这就是一个正常的HTTP请求和返回的完整过程。

DNS协议

若是要记得住网站的名称,可是很难记住网站的IP地址,于是也须要一个地址簿,就是DNS服务器

因而可知,DNS在平常生活中多么重要。每一个人上网,都须要访问它,可是同时,这对它来说也是很是大的挑战。一旦它出了故障,整个互联网都将瘫痪。另外,上网的人分布在全世界各地,若是你们都去同一个地方访问某一台服务器,时延将会很是大。于是,DNS服务器,必定要设置成高可用、高并发和分布式的

  • 根DNS服务器 :返回顶级域DNS服务器的IP地址
  • 顶级域DNS服务器:返回权威DNS服务器的IP地址
  • 权威DNS服务器 :返回相应主机的IP地址

DNS解析流程

为了提升DNS的解析性能,不少网络都会就近部署DNS缓存服务器。因而,就有了如下的DNS解析流程。

  1. 电脑客户端会发出一个DNS请求,问www.163.com的IP是啥啊,并发给本地域名服务器 (本地DNS)。那本地域名服务器 (本地DNS) 是什么呢?若是是经过DHCP配置,本地DNS由你的网络服务商(ISP),如电信、移动等自动分配,它一般就在你网络服务商的某个机房。
  2. 本地DNS收到来自客户端的请求。你能够想象这台服务器上缓存了一张域名与之对应IP地址的大表格。若是能找到 www.163.com,它直接就返回IP地址。若是没有,本地DNS会去问它的根域名服务器:“老大,能告诉我www.163.com的IP地址吗?”根域名服务器是最高层次的,全球共有13套。它不直接用于域名解析,但能指明一条道路。
  3. 根DNS收到来自本地DNS的请求,发现后缀是 .com,说:“哦,www.163.com啊,这个域名是由.com区域管理,我给你它的顶级域名服务器的地址,你去问问它吧。”
  4. 本地DNS转向问顶级域名服务器:“老二,你能告诉我www.163.com的IP地址吗?”顶级域名服务器就是大名鼎鼎的好比 .com、.net、 .org这些一级域名,它负责管理二级域名,好比 163.com,因此它能提供一条更清晰的方向。
  5. 顶级域名服务器说:“我给你负责 www.163.com 区域的权威DNS服务器的地址,你去问它应该能问到。”
  6. 本地DNS转向问权威DNS服务器:“您好,www.163.com 对应的IP是啥呀?”163.com的权威DNS服务器,它是域名解析结果的原出处。为啥叫权威呢?就是个人域名我作主。
  7. 权限DNS服务器查询后将对应的IP地址X.X.X.X告诉本地DNS。
  8. 本地DNS再将IP地址返回客户端,客户端和目标创建链接。

若是个人文章对您有帮助,不妨点个赞鼓励一下(^_^)

相关文章
相关标签/搜索