计算机网络笔记

HTTP协议:
1.无状态的:是指后一个请求不能依赖前一个请求中的字段等
2.请求/响应方式运行
3.可扩展的语义;例如服务器是1.0,但是浏览器是1.1版本的话,浏览器和服务器是可以正常通信

OSI概念模型


表示层:将网络中的消息转换成应用层可以读取的消息
会话层:是一层完全概念化的一层、负责建立会话,握手维持连接关系的一层。这一层更多的是让我们理解会话这个概念
传输层:更多的是解决进程与进程之间的通讯。当报文到主机上,我们应该把报文分发到哪个进程是由传输层决定的。传输层还做了更多的事情,例如tcp协议还做了报文的可达性、流量的控制
网络层:ip协议

REST架构下的Web

在这里插入图片描述

Chrome的NetWork面板
输入is:from-cache可以查看浏览器缓存资源
is:running可以查看webSocket资源
在这里插入图片描述

浏览器加载时间
触发流程:
1.解析HTML结构
2.加载外部脚本和样式表文件
3.解析并执行脚本代码 //部分脚本会阻塞页面的加载
4.DOM树构建完成 //DOMContentLoaded事件
5.加载图片等外部事件
6.页面加载完毕 //load事件

请求时间详情分布
Queueing: 浏览器在以下情况下对请求排队
存在更高优先级的请求
此源已打开六个TCP连接,达到限值,仅适用于HTTP1.0 和 1.1
浏览器正在短暂分配磁盘缓存中的空间
Stalled:请求可能因为Queueing中描述的任何原因而停止
DNS Lookup:浏览器正在解析请求的ip地址
Proxy Negotiation:浏览器正在与代理服务器协商请求
Request sent:正在发送请求
ServiceWorker Preparation:浏览器正在启动Service Worker
Request to ServiceWorker:正在将请求发送给ServiceWorker
Waiting(TTFB): 浏览器正在等待响应的第一个字节。此时间包括1次往返延迟时间以及服务器准备响应所用时间
Content Download:浏览器正在接收的响应
Receiving Push:浏览器正在通过HTTP/2服务器推送接收此响应的数据
Reading Push:浏览器正在读取之前收到的本地数据

从TCP编程上来看HTTP请求流程
在这里插入图片描述

Connection仅针对当前连接有效
长连接只针对当前连接有效,例如下图中代理服务器如果不支持长连接,则交互的时候无法通过长连接发送。
在这里插入图片描述

两种传输HTTP包体的方式:
1.Content-Length:传输固定长度的包体
2.使用Transfer-Encoding指明使用Chunk传输方式的
含Transfer-Encoding头部后Content-Length头部应忽略
优点:基于长连接持续推送动态内容
压缩体积较大的包体的时候,不必完全压缩完(计算出头部)再发送,可以边发送边压缩
传输必须在包体传输完才能够计算出Trailer头部

Http缓存:为当前请求复用前请求的响应
如果缓存没有过期:就不会发送网络请求
在这里插入图片描述
如果缓存过期了:则继续从服务器验证,如果返回304则代表没有修改,会继续从缓存中获取在这里插入图片描述
缓存还分为:
私有缓存:例如浏览器缓存
共享缓存:可以供多个用户的缓存,存在于网络中负责转发的代理服务器

下图中Cache为代理缓存
在这里插入图片描述

判断缓存是否过期

response_is_fresh = (freshness_lifetime > current_time)
freshness_lifetime: 按优先级取以下响应头部的值
s-maxage > max-age > Expries > 预估过期时间

age头部表示自原服务器发起响应时间(或验证过期缓存),到使用缓存的响应发起时经过的秒数

代理分类

1.匿名代理:完全隐匿了被代理服务器,外界看到的只是代理服务器。
2.透明代理:在传输过程中是“透明开放”的,外界即知道代理,也知道客户端。
3.正向代理:靠近客户端,代表客户端向发送服务器请求。
4.反向代理:靠近服务器,代表服务器响应客户端请求。

响应状态码
3xx:
3xx表示客户端请求的资源发生了改动,客户端必须用新的URI重新发送请求获取资源,也就是通常所说的“重定向”
“301 Moved Permanently”俗称“永久重定向”,含义是此次请求的资源已经不存在了,需要改用新的 URI 再次访问。
与它类似的是“302 Found”,曾经的描述短语是“Moved Temporarily”,俗称“临时重定向”,意思是请求的资源还在,但需要暂时用另一个 URI 来访问。
301 和 302 都会在响应头里使用字段 Location 指明后续要跳转的 URI,最终的效果很相似,浏览器都会重定向到新的 URI。两者的根本区别在于语义,一个是“永久”,一个是“临时”,所以在场景、用法上差距很大。
比如,你的网站升级到了 HTTPS,原来的 HTTP 不打算用了,这就是“永久”的,所以要配置 301 跳转,把所有的 HTTP 流量都切换到 HTTPS。再比如,今天夜里网站后台要系统维护,服务暂时不可用,这就属于“临时”的,可以配置成 302 跳转,把流量临时切换到一个静态通知页面,浏览器看到这个 302 就知道这只是暂时的情况,不会做缓存优化,第二天还会访问原来的地址。

Http的特点:
如何理解无状态:
“状态”其实就是客户端或者服务器保存的一些数据或者标志,记录通信过程中的一些变化信息。
你一定知道,TCP 协议是有状态的,一开始处于 CLOSED 状态,连接成功后是 ESTABLISHED 状态,断开连接后是 FIN-WAIT 状态,最后又是 CLOSED 状态。
这些“状态”就需要 TCP 在内部用一些数据结构去维护,可以简单地想象成是个标志量,标记当前所处的状态,例如 0 是 CLOSED,2 是 ESTABLISHED 等等。

再来看 HTTP,那么对比一下 TCP 就看出来了,在整个协议里没有规定任何的“状态”,客户端和服务器永远是处在一种“无知”的状态。建立连接前两者互不知情,每次收发的报文也都是互相独立的,没有任何的联系。收发报文也不会对客户端或服务器产生任何影响,连接后也不会要求保存任何信息。
“无状态”形象来说就是没有记忆能力。比如浏览器发送一个请求,说“我是小明,请给我A文件”。服务器收到报文后就会检查一下权限,看小明确实可以访问 A 文件,于是把文件发回给浏览器。接着浏览器还想要 B 文件,但服务器不会记录刚才的请求状态,不知道第二个请求和第一个请求是同一个浏览器发来的,所以浏览器必须还得重复一次自己的身份才行:“我是刚才的小明,请再给我 B 文件。”

队头阻塞导致的问题以及解决办法
如果队首请求因为处理的太慢耽误了时间,就会导致队列里后面的请求也不得不跟着一起等待,就导致其他请求承担了不应有的时间成本。
在这里插入图片描述
优化方法:
HTTP里就使用并发连接,也就是对同一个域名发起多个长连接,用数量解决质量的问题。
但是这就存在一个缺陷,如果每个客户端都想自己快,用户数×并发数就会是个天文数字。服务器的资源根本就扛不住,或者被服务器认为是恶意攻击,反而会造成“拒绝服务”。

所以,Http协议建议客户端使用并发,但并不能滥用并发。RFC2616里明确限制每个客户端最多并发两个连接。不过实践证明这个数字实在是太小了,众多浏览器都“无视”标准,把这个上限提高到了 6~8。后来修订的 RFC7230 也就“顺水推舟”,取消了这个“2”的限制。

但是“并发连接”所压榨的性能跟不上高速发展的互联网无止境的需求,还有什么别的办法吗?
“域名分片”技术:HTTP 协议和浏览器不是限制并发连接数量吗?好,那我就多开几个域名,比如 shard1.chrono.com、shard2.chrono.com,而这些域名都指向同一台服务器 www.chrono.com,这样实际长连接的数量就又上去了,真是“美滋滋”。不过实在是有点“上有政策,下有对策”的味道。

重定向
什么时候需要重定向呢?
1.资源不可以,需要用另一个新的uri来代替
至于不可用的原因就很多了,例如域名变更、服务器变更、网站改版、系统维护,这些都会导致原uri指向的资源无法访问,为了避免出现404,就需要用重定向跳转到新的uri
2.避免重复,让多个网址都跳转到一个 URI,增加访问入口的同时还不会增加额外的工作量。

Http的缓存控制
响应报文中的一些属性来控制缓存策略:
no-store: 不允许缓存,用于某些变化非常频繁的数据,例如秒杀页面
no-cache:它的意思并不是不允许缓存,而是可以缓存,但是在使用之前必须去服务器上验证是否过期,是否有最新版本
no-revalidate:表示的是如果缓存不过期的话,就可以继续使用,否则如果过期的话,就必须去服务器上进行验证

缓存代理的控制策略
private:代表缓存只能在客户端保存,是用户私有的,不能在代理上与别人共享
public:缓存完全开放,谁都可以取,谁都可以用
must-revalidate:只要过期了必须回源服务器去验证
proxy-revalidate:只要求代理的缓存过期后必须验证,客户端不必回源,只验证到代理这一环节就可以了
s-maxage:只限定在代理上能存多久,而客户端仍然使用max-age。
no-transform:代理有时候对缓存下来的数据做了一些优化,比如把图片生成 png、webp 等几种格式,方便今后的请求处理,而“no-transform”就会禁止这样做,不许“偷偷摸摸搞小动作”

用便利店冷柜举例:
水果上贴着标签“private, max-age=5”。这就是说水果不能放进冷柜,必须直接给顾客,保鲜期 5 天,过期了还得去超市重新进货。
冻鱼上贴着标签“public, max-age=5, s-maxage=10”。这个的意思就是可以在冰柜里存 10 天,但顾客那里只能存 5 天,过期了可以来便利店取,只要在 10 天之内就不必再找超市。
排骨上贴着标签“max-age=30, proxy-revalidate, no-transform”。因为缓存默认是 public 的,那么它在便利店和顾客的冰箱里就都可以存 30 天,过期后便利店必须去超市进新货,而且不能擅自把“大排”改成“小排”

客户端的缓存控制策略
max-stale:代表如果缓存过期了也可以接受,但是不能过期太多,超过x秒也不要
min-fresh:代表缓存必须有效,并且在x秒之后仍然有效
比如:草莓上贴着标签“max-age=5”,现在已经在冰柜里存了 7 天。如果有请求“max-stale=2”,意思是过期两天也能接受,所以刚好能卖出去。
但要是“min-fresh=1”,这是绝对不允许过期的,就不会买走。这时如果有另外一个菠萝是“max-age=10”,那么“7+1<10”,在一天之后还是新鲜的,所以就能卖出去。

有的时候客户端还会发出一个特别的“only-if-cached”属性,表示只接受代理缓存的数据,不接受源服务器的响应。如果代理上没有缓存或者缓存过期,就应该给客户端返回一个 504(Gateway Timeout)。

HTTPS介绍

HTTP下层的传输协议由原来的TCP/IP变成了SSL/TLS,收发报文不再是Socket API,而是调用专门的安全接口。
在这里插入图片描述

HTTP/2介绍

二进制格式
它把 TCP 协议的部分特性挪到了应用层,把原来的“Header+Body”的消息“打散”为数个小片的二进制“帧”(Frame),用“HEADERS”帧存放头数据、“DATA”帧存放实体数据。在这里插入图片描述
虚拟的流
HTTP/2 为此定义了一个“流”(Stream)的概念,它是二进制帧的双向传输序列,同一个消息往返的帧会分配一个唯一的流 ID。你可以把它想象成是一个虚拟的“数据流”,在里面流动的是一串有先后顺序的数据帧,这些数据帧按照次序组装起来就是 HTTP/1 里的请求报文和响应报文。
在“流”的层面上看,消息是一些有序的“帧”序列,而在“连接”的层面上看,消息却是乱序收发的“帧”。多个请求 / 响应之间没有了顺序关系,不需要排队等待,也就不会再出现“队头阻塞”问题,降低了延迟,大幅度提高了连接的利用率。
在这里插入图片描述
高效的Lua语言
OpenResty能够高效运行的一大秘技是它的“同步非阻塞”编程范式。
同步非阻塞本质上是一种多路复用。epoll是操作系统级别的“多路复用”,运行在内核空间。而OpenResty的“同步非阻塞”则基于Lua内建的协程,是应用程序级别的多路复用,运行在应用空间,所以它的资源消耗要更少。
OpenResty 里每一段 Lua 程序都由协程来调度运行。和 Linux 的 epoll 一样,每当可能发生阻塞的时候“协程”就会立刻切换出去,执行其他的程序。这样单个处理流程是“阻塞”的,但整个 OpenResty 却是“非阻塞的”,多个程序都“复用”在一个 Lua 虚拟机里运行。
在这里插入图片描述
下面的代码是一个简单的例子,读取 POST 发送的 body 数据,然后再发回客户端:


ngx.req.read_body()                  -- 同步非阻塞(1)

local data = ngx.req.get_body_data()
if data then
    ngx.print("body: ", data)        -- 同步非阻塞(2)
end

代码中的“ngx.req.read_body”和“ngx.print“分别是数据的收发动作,只有收到数据才能发送数据,所以是同步的。
但是即使因为网络原因没有收到或者发不出去,OpenResty也不会在这里阻塞“干等着”,而是做个标记,把等待的这段cpu时间用来处理其他请求,等网络可读或者可写时再回来接着运行。

TCP协议介绍

图中1.1时连接状态为syn_rcvd状态
2.1时连接状态为estab状态
在这里插入图片描述
Fast Open降低时延
在这里插入图片描述
通过net.ipv4.tcp_fastopen开启fastopen功能

防护syn攻击:
在这里插入图片描述

tcp_defer_accept:在报文到达accept队列的时候是否激活应用程序,还是等到data分组到达的时候再激活。
在这里插入图片描述

流分段的依据:如果tcp不分层的话,ip层就一定会分层。ip层分层的效率是非常低的。
在这里插入图片描述
par改进版服务器端需要告诉客户端我还剩几个消息可以发送,因为服务器端资源是有限的,需要限制发送端。
在这里插入图片描述
Sequence序列号/Ack序列号
设计的目的:解决应用层字节流的可靠传输
跟踪应用层的发送端数据是否到达
确认接收端有序的接收到字节流
序列号的值针对的是字节,而不是报文

操作系统缓冲区与滑动窗口的关系

发送端发送360字节,接收端由于应用层没有及时缓存就会导致接收窗口变成了260字节。
同理直到接收窗口为0的时候,导致窗口关闭。
在这里插入图片描述
收缩窗口导致的丢包
步骤二中可能由于线程数增多,导致缓存减小,导致收缩窗口。
所以当收到140字节以后会返回100字节的窗口大小,但是由于延迟导致客户端又发送180字节。
4.但是服务方发现客户端没有180字节窗口,所以会直接丢包。

在这里插入图片描述

如何减小报文提高网络效率?

由于服务端和客户端处理速度的差距,导致发送窗口每次发送大量的报文,但是接收窗口却只能处理一小部分报文。
在这里插入图片描述
SWS避免算法
在这里插入图片描述

在这里插入图片描述
最佳控制点在哪里?
第一个图显示的是RTT(也就是时迟),当路由达到瓶颈的时候,RTT会变大,也就是黄色的部分
第二个图现实的是网络带宽,当路由达到瓶颈的时候,网络带宽会不变。
在这里插入图片描述

关闭连接过程优化

关闭连接:防止数据丢失,与应用层交互。
首先客户端会发送报文,这个报文中的标志位我们会把其中的fin标志为1。然后科幻端就会进入到FIN-WAIT-1状态,而服务器端就会回一个ACK,此时服务器端的状态是CLOSE-WAIT状态。客户端接收到ACK后自动变成FIN-WAIT-2状态。
服务端发送FIN包后就会进入LAST-ACK状态
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值