HTTP协议
老规矩,还是从一个问题入手:http协议的keep-alive和多路复用是为了解决什么问题?有什么区别?
一些TCP/IP的前置知识:
跨主机通信是基于套接字,而套接字提供了进程之间的通信,是IPC的一种实现。
IP协议是面向无连接的,不可靠的,但ICMP也能实现一部分的可靠性
http的工作模型:请求,响应
http的版本演变:
HTTP/0.9:不支持多媒体
HTTP/1.0:开始支持多媒体。每个TCP连接只能发送一个请求,新的请求需要再次TCP的三次握手,四次挥手
HTTP/1.1:为了改善1.0的问题,1.1引入了持久连接,即keep-alive,即同一个TCP连接可以发送多个请求,但这些请求是串行的,如果有一个请求慢了将会导致
阻塞。要解决这个问题,要么减少请求,要么增加TCP连接。而大多数浏览器支持的TCP连接都有上限,比如6个。
HTTP/2.0:于是便有了2.0.2.0采用二进制传输,解决了1.0需要串行请求的问题,也就是多路复用。
I/O模型:
同步与异步:sync,async,关注的是消息通知的机制
阻塞与非阻塞:关注的是调用者等待返回结果时的状态。阻塞,调用结果返回之前,调用者会被挂起。不阻塞:调用者不会被挂起,但需要不断询问,而且在I/O时是阻塞的。
keepalive:是为了解决一定时间内,同一域名的多次请求数据只建立一次HTTP连接,这听起来很合理,毕竟一次http连接时有消耗的,TCP的三次握手,四次挥手。
从这个意义上讲,httpd的prework模型有点类似keep-alive,主进程负责监听,通过预先生成的几个子进程的复用来接收请求,prework节省的是进程创建销毁的开销。
多路复用:keepalive虽然复用连接,提高了效率,但仍存在问题。一个是基于文本的传输是串行,一个是连接数限制。怎么理解?文本的传输是有顺序的,服务端并不能识别顺序,所以只能
串行。还是基于文本的串行传输,浏览器端的限制是6个请求,这导致连接数限制。
而多路复用的创新在于二进制数据帧流式的传输,这解决了这两个问题。
多路复用模型是一个阻塞模型,它并不能提高性能。
事件驱动:我们知道多路复用通过二进制数据组的流式传输,极大的提高了传输的效率,但仍是一个同步阻塞模型。而事件驱动模型,是一个异步不阻塞模型,进一步提高性能。
nginx就采用了很多最新的技术,比如基于事件驱动模型和边缘触发。但事件驱动貌似还有其他一些劣势,并没有大规模使用。
可以看到,这里I/O模型关注到的几个点,连接的复用,并行传输,连接数,以及异步非阻塞等,有一个逐渐演变的过程。
分析到这里,开篇谈到的那个问题已经迎刃而解了。
cookie与session:
再往下走,http协议本身是无状态的,这句话怎么理解?在很多技术书籍或者文章里有很多这样生涩的语言。就如同我们看柯朗的《什么是数学》,世界上最苦恼的就是很容易得出,证明等等。
无状态在这里的含义是指服务器无法持续追踪访问者的来源,通俗点说当你刷新页面的时候就需要重新登陆了。我们说,技术是因为业务的需求,这就是业务需求,技术上如何解决呢?
目前的做法是通过cookie的方式来解决的。cookie的作用很类似一个令牌,当第一次连接时服务端发送一个令牌给客户端,客户端保存在本地,当客户端再次发送请求时会带上这个令牌,服务端就能识别了。这也很类似那种加密秘钥的原理,其实很多原理都是想通的。这里一定是服务端发给客户端令牌,服务端负责制作和解释,这有点像去超市服务台寄存包,服务台给你一个编号的令牌,到时候你去领回包的时候,带上这个令牌,服务台就知道哪个是你的包了。是不是有种道理都是相通的感受?
从这个角度出发,去公共网吧最好删除cookie信息就能解释了。如果你保留cookie信息,极有可能被人盗用了账号。正是因为cookie有这个泄露用户信息的风险,所以出现了轻cookie的概念,即本地用户只保存个人信息,而类似淘宝购物车这种信息就保留在服务端,被称为session空间的地方。
浙公网安备 33010602011771号