HTTP,是Web工程师每天打交道最多的一个基本协议。很多工作流程、性能优化都围绕HTTP协议来进行的。
前端视角
前端工程师的职责之一是,让网站又快又好地展现在用户的浏览器中。从这个角度来说,对HTTP的理解是这样的:打开HttpWatch,然后随意访问一个网站。HttpWatch会按照浏览器请求的次序,列出打开这个网站的时候发生的请求细节。
【发出的请求列表,每个请求的开始时间,每个请求从开始到结束花费的时间,每个请求的类型(比如是文本、css、JS,还是图片或者字体等),每个请求的状态码(比如200,还是 from cache 、304、404等),每个请求产生的流量消耗,每个请求gzip压缩前的体积,以及在本地gzip解压后的体积。】
通过查看站点的HTTP请求信息,可以得到很多优化信息。每一个前端工程师都知道的基本优化方法是:尽量减少同一域下的HTTP请求数(浏览器常常限定了对同一域名发起的并发连接数的上限【很大程度上是对服务器的一种保护行为】),以及尽量减少每一资源的体积。
(HttpWatch是一个浏览器插件,他可以用来检测页面中所有HTTP请求。类似的工具还有Fidder,或者各种现代浏览器的开发者工具中的“网络”标签页)
(gzip是一种开源的数据压缩算法,其中g代表免费的意思(gratis)。HTTP/1.1协议允许客户端选择要求从服务器下载压缩内容,gzip是绝大多数客户端和服务器都支持的压缩算法,它的压缩文本文件(比如css、HTML、JavaScript)时压缩压缩效果很好)
(通过Chrome开发者工具中的PageSpeed工具,可以快速获得关于站点性能优化的建议)
后台视角
前端工程师对HTTP的关注点在于尽量减少同一域名下的HTTP请求数,以及尽量减少每一个资源的体积。
后台工程师对于HTTP的关注在于让服务器尽快响应请求,以及减少请求对服务器的开销。
为什么服务器对并发请求数这么敏感?
虽然服务器的多个进程看上去是在同时运行,但是对于单核CPU的架构来说,实际上是计算机系统同一段时间内,以进程的形式,将多个程序加载到存储器中,并借由时间共享,以在一个处理器上表现出同时运行的感觉。由于在操作系统中,生成进程、销毁进程、进程间切换都很消耗CPU和内存,因此当负载高时,性能会明显降低。
提高处理器的请求处理能力
apache是市场份额最大的服务器,apache通过模块化的设计来适应各种环境,其中一个模块叫做多处理模块(MPM),专门用来处理多请求的情况。Apache安装在不同系统上的时候会调用不同的默认MPM,我们不用关心具体的细节,只需要了解Unix上默认的MPM是prefork。为了优化,我们可以改成worker模式。
prefork和worker模式的最大区别就是:prefork的一个进程维持一个连接,而worker的一个线程维持一个连接。所以prefork更稳定但内存消耗也更大,worker没有那么稳定,因为很多连接的线程共享一个进程,当一个线程崩溃的时候,整个进程和所有线程一起死掉。但是worker的内存使用要比prefork低得多,所以适合用在高HTTP请求的服务器上。
在高连接并发的情况下Nginx是Apache服务器不错的替代品或者补充,一方面Nginx更加轻量级,占用更少的资源和内存,另一方面Nginx处理请求是异步非阻塞的,Apache则是阻塞的,在高并发下Nginx能保持低资源、低消耗和高性能。
经常是搭配Nginx处理前端并发,Apache处理后台请求。
Node.js也是采用基于事件的异步非阻塞方式处理请求。
DDoS攻击
DDoS是Distributed Denial of Service的缩写,DDoS攻击翻译就是“分布式拒绝服务”攻击。(简单说就是黑客入侵并控制了大量用户的计算机(俗称“肉鸡”),然后在这些计算机上安装了DDoS攻击软件,就这样,攻击者通过海量的请求,让目标服务器瘫痪,无法响应正常的用户请求,以此达到攻击的效果【应对措施:增加带宽和提高服务器能同时接纳的客户数,另一种就是让让首页静态化】)(静态资源能过部署在CDN上)
DDoS是最简单的TCP/IP攻击,DDoS是一个概念,有各种攻击方式,比如CC攻击,SYN攻击、NTP攻击、TCP攻击和DNS攻击等。
BigPipe
前端跟后端在HTTP上能有交集,BigPipe就是一个例子。
现有的HTTP数据请求流程是:客户端建立连接,服务器同意连接,客户端发起请求,服务器返回数据,客户端接收并处理数据。
处理流程有两个问题:
(1)HTTP协议底层是TCP/IP,而TCP/IP规定3次握手才建立一次连接。每一个新增的请求都要重新建立TCP/IP连接,从而消耗服务器的资源,并浪费连接时间。对于几种不同的服务器程序(Apache、Nginx和Node.js等),所消耗的内存和CPU资源也不太一样,但是新的连接无法避免,没有从本质上解决问题。
(2)在现有的阻塞模型,服务器计算生成页面需要时间。等服务器完全生成好整个页面,才开始网络传输,网络传输也需要时间。整个页面都完全传输到浏览器中之后,在浏览器中最后渲染还是需要时间。三者是阻塞式的,每一个环节都在等上一个环节100%完成才开始。页面作为一个整体,需要完整的经历3个阶段才能出现在浏览器中,效率很低。
BigPipe是一种非阻塞式模型,这种模型能完美解决上述两个问题。
通俗来解释,BigPipe首先把HTML页面分为很多部分,然后在服务器和浏览器之间建立一条管道,HTML的不同部分可以源源不断的从服务器传输到浏览器。(BigPipe首先输送的内容是框架性HTML结构)
HTTP 1.1 引入分块传输编码,允许服务器为动态生成的内容维持HTTP持久链接。如果一个HTTP消息(请求消息或应答消息)的TransferEncoding消息头的值为chunked,那么消息体由数量不确定的块组成--------也就是说想发送多少块就发送多少块---------并以最后一个大小为0的块为结束。