网络/IO基础
1. BIO、NIO、AIO的概念
1.1 同步阻塞BIO
Blocking IO是JDK1.4之前的唯一选择,依赖于ServerSocket实现,即一个请求对应一个线程。如果线程数不够则会等待空余线程或者拒绝连接。
在此种方式下,用户进程在发起一个IO操作以后,必须等待IO操作的完成。只有当真正完成了IO操作以后,用户进程才能运行。
1.2 同步非阻塞NIO
Non-Blocking IO是在JDK1.4后提供的,定义在java.nio包下。相比传统的BIO,NIO提供了告诉的面向快的I/O,它加入了Buffer,Channel,Selector等概念。它是基于事件驱动的,采用了Reactor模式。它使用一个线程管理所有的socket通道,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
在此种方式下,用户进程发起一个IO操作后可返回做其他事情,但是用户进程需要时不时的询问IO操作是否就绪。这需要用户进程不停地询问,从而造成了不必要的CPU资源浪费。
1.3 AIO
AIO是NIO2.9,于JDK1.7开始应用,称为异步不阻塞IO。AIO引入异常通道的概念,采用了Proactor模式,简化了程序编写。一个有效的请求才启动一个线程。它的特点是先由操作系统完成后才通知服务器端程序启动线程去处理。
此种方式是指用户进程发起一个IO操作以后不需等待内核IO操作的完成,内核完成以后会通知用户进程。
参考:
《NIo、Bio、aio、 的原理及区别与应用场景》
《高级java必掌握流的几个应用:IO、BIO、NIO、AIO》
2. 什么是长连接和短连接
HTTP的长连接和短连接本质上是TCP长连接和短连接。HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。
IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠地传递数据包,使得网络上接受端收到发送端所发出的所有包,并且顺序与发送顺序一致。TCP协议是可靠地面向连接的。
HTTP协议是无状态的,指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。也就是说,打开一个服务器上的网页和上一次打开这个服务器上的网页之间没有任何联系。HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议。
2.1 TCP短连接
短连接过程:client向server发起连接请求,server接到请求,然后双方建立连接。client向server发送消息,server回应client,然后一次请求就完成了。这时候双方任意都可以发起close操作,不过一般都是client先发起close操作。
短连接一般只会在client/server间传递依次请求操作。短连接管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段。但如果client请求频繁,将在TCP的建立和关闭操作上浪费较多时间和带宽。
2.2 TCP长连接
长连接过程:client向server发起连接,server接受client连接,双方建立连接,client与server完成一次请求后,他们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。
从HTTP/1.1起,默认使用长链接,用于保持连接特性,在响应头加入Connection:keep-alive。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件中设定这个时间。实现长连接需要客户端和服务端都支持长连接。
TCP的保活功能主要为服务器应用提供。保活功能就是试图在服务器端检测这种半开放的连接。
如果一个给定的连接在一定时间内没有任何动作,服务器就向客服发送一个探测报文段,根据客户端主机响应来探测个客户端状态:
- 客户端依然运行正常且服务器可达。此时客户端TCP响应正常,服务器将保活定时器复位。
- 客户主机已经崩溃,并且关闭或者正在重新启动。客户端将无法响应TCP,服务器无法收到客户端对探测的响应,服务器总共发送10个这样的探测,每个间隔75秒。若服务器没有收到任何一个响应,他就认为客户端已经关闭并终止连接。
- 客户端已经崩溃但重新启动。此时服务器将收到一个对其保活探测的响应,这个响应是一个复位,使得服务器终止这个连接。
- 客户机运行正常,但是服务器不可达。这种情况与第二种状态类似。
长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接。不过这里存在一个问题,存活功能的探测周期太长,还有就是它只是探测TCP连接的存活,属于比较斯文的做法,遇到恶意的连接时,保活功能就不够使了。在长连接的应用场景下,client端一般不会主动关闭它们之间的连接,Client与server之间的连接如果一直不关闭的话,会存在一个问题,随着客户端连接越来越多,server早晚有扛不住的时候,这时候server端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可以避免一些恶意连接导致server端服务受损;如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最大长连接数,这样可以完全避免某个蛋疼的客户端连累后端服务。
参考:
《HTTP长连接、短连接究竟是什么?》
《网络连接中的长连接和短链接是什么意思?》
3. Http1.0和2.0相比有什么区别
3.1 多路复用
多路复用允许单一的 HTTP/2 连接同时发起多重的请求-响应消息。
在 HTTP/1.1 协议中 「浏览器客户端在同一时间,针对同一域名下的请求有一定数量限制。超过限制数目的请求会被阻塞」
Http/2在应用层和传输层之间增加了一个二进制分帧层。
在二进制分帧层中, HTTP/2 会将所有传输的信息分割为更小的消息和帧(frame),并对它们采用二进制格式的编码 ,其中 HTTP1.x 的首部信息会被封装到 HEADER frame,而相应的 Request Body 则封装到 DATA frame 里面。
HTTP/2 通信都在一个连接上完成,这个连接可以承载任意数量的双向数据流。
在过去, HTTP 性能优化的关键并不在于高带宽,而是低延迟。TCP 连接会随着时间进行自我「调谐」,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度。这种调谐则被称为 TCP 慢启动。由于这种原因,让原本就具有突发性和短时性的 HTTP 连接变的十分低效。
HTTP/2 通过让所有数据流共用同一个连接,可以更有效地使用 TCP 连接,让高带宽也能真正的服务于 HTTP 的性能提升。
3.2 首部压缩
在 HTTP/1 中,HTTP 请求和响应都是由「状态行、请求 / 响应头部、消息主体」三部分组成。一般而言,消息主体都会经过 gzip 压缩,或者本身传输的就是压缩过后的二进制文件(例如图片、音频),但状态行和头部却没有经过任何压缩,直接以纯文本传输。
随着 Web 功能越来越复杂,每个页面产生的请求数也越来越多,导致消耗在头部的流量越来越多,尤其是每次都要传输 UserAgent、Cookie 这类不会频繁变动的内容,完全是一种浪费。
3.3 HTTP2支持服务器推送
服务端推送是一种在客户端请求之前发送数据的机制。当代网页使用了许多资源:HTML、样式表、脚本、图片等等。在HTTP/1.x中这些资源每一个都必须明确地请求。这可能是一个很慢的过程。浏览器从获取HTML开始,然后在它解析和评估页面的时候,增量地获取更多的资源。因为服务器必须等待浏览器做每一个请求,网络经常是空闲的和未充分使用的。
为了改善延迟,HTTP/2引入了server push,它允许服务端推送资源给浏览器,在浏览器明确地请求之前。一个服务器经常知道一个页面需要很多附加资源,在它响应浏览器第一个请求的时候,可以开始推送这些资源。这允许服务端去完全充分地利用一个可能空闲的网络,改善页面加载时间。
参考:
《让面试官颤抖,HTTP2.0协议之你应该要准备的面试题》
《HTTP/2.0 相比1.0有哪些重大改进?》
4. Https的基本概念
Https是基于安全套接字层的超文本传输协议 Http Over SSL,是一个Netscape开发的Web协议。
HTTPS = HTTP + SSL
Https在Http应用层的基础上使用安全套接字层作为子层。
Http是一个用来通过互联网传输和接收信息的协议。Http使用请求/响应的过程,因此信息可以在服务器间快速,轻松而且精确的进行传输。但Http是不安全的,所以就出现了Https。
Http和Https在大多数情况下都是相同的,唯一不同的只是一个协议头https的说明,其他都是一样的。
- Http的url以http://开头,而Https的url以https://开头
- Http是不安全的,而Https是安全的
- Http标准端口是80,而Https的标准端口是443
- 在OSI网络模型中,Http工作于应用层,而Https工作在传输层
- Http无需加密,而Https对传输的数据进行加密
- Http无需证书,而Https需要认证证书
使用Https连接时,服务器要求有公钥和签名的证书。当使用https连接,服务器响应初始连接,并提供它所支持的加密方法。作为回应,客户端选择一个连接方法,并且服务器端与客户端交换证书验证彼此身份。完成之后,在确保使用相同密钥的情况下传输加密信息,然后关闭连接。
Http包含如下动作:
- 浏览器打开一个TCP连接
- 浏览器发送http请求到服务器端
- 服务器发送http回应信息到浏览器
- TCP连接关闭
SSL包含如下动作:
- 验证服务器端
- 允许客户端和服务器端选择加密算法和密码,确保双方都支持
- 验证客户端(可选)
- 使用公钥加密技术来生成共享加密数据
- 创建一个加密的SSL连接
- 基于该SSL连接传递Http请求
参考:
《HTTPS的基本概念》
5. 三次握手和四次挥手、为什么挥手需要四次
三次握手过程:
- a --> b
B确认A发送功能正常,B确认B的接收功能正常 - b --> a
A确认A发送和接收功能正常,A确认B发送和接收功能正常 - a --> b
B确认A发送和接收功能正常,B确认A发送和接收功能正常。
三次握手是为了防止服务器收到已失效的连接请求报文段,以防服务器造成不必要的资源浪费。
四次挥手:
TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
- TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送。
- 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1,和SYN一样,一个FIN占用一个序号。
- 服务器完成可能的剩余数据发送后,关闭客户端的连接,发送一个FIN给客户端。
- 客户端发回ACK报文确认,并将确认序号置为收到序号加1。
之所以挥手需要四次是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
参考:
《 理论经典:TCP协议的3次握手与4次挥手过程详解》
《HTTPS 工作原理和 TCP 握手机制》
《TCP四次挥手(图解)-为何要四次挥手》
6. 从浏览器中输入URL到页面加载的发生了什么?
- dns解析
- tcp连接
- 发送http请求
- 服务器处理请求并返回http报文
- 浏览器解析渲染页面
- 连接结束
参考:
《从输入URL到页面加载发生了什么》