当前位置: 首页 > 科技观察

Web服务器静态资源加速技术

时间:2023-03-15 22:48:24 科技观察

1.引言在互联网应用中,WEB页面的打开速度在用户体验中占有极其重要的地位。根据HubSpot进行的研究,如果雅虎将页面加载时间减少0.4秒,流量可能会增加9%;1秒的慢速页面可能会使亚马逊损失16亿美元的年销售额;Bing搜索延迟2秒将导致每位访问者的收入损失4.3%,点击次数减少3.75%,查询次数减少1.8%。根据以上数据可以看出,网页的加载时间对于一个网站来说意义重大。网页一般包括两类资源:静态资源和动态资源。静态资源主要包括静态html、图片、js、css、视频等资源。这些资源基本不会经常变化,对所有用户来说基本一致。动态资源主要是为每个用户动态展示的数据信息,如:用户信息、登录状态、用户数据、账户余额、账户明细等。动态资源的处理时间主要取决于后台应用程序和数据库的处理性能。可以通过提升服务器性能和优化业务处理逻辑来解决。一般需要具体问题具体分析。本文将主要讨论静态资源的加速技术。2、HTTP缓存技术介绍打开一个网站在一段时间内浏览多个页面,会出现大量对同一个静态资源的请求。由于静态资源的变化频率较低,可以将之前下载过的资源缓存起来,供后续请求使用。访问请求。我们打开浏览器访问一个页面,在开发者模式下可以看到如下信息:图1打开这个页面一共发送了303个请求,传输了21.6M的数据,总耗时11.48秒。总的来说,这是一个非常慢的页面(由于使用了异步请求,就用户体验而言还算不错)。再次使用F5刷新页面,可以看到如下信息:图2这次是300个请求,但是传输的数据量只有369K,整体耗时6.5秒,加载仅2.5秒。这次体验很好,页面上需要显示的内容很快就会显示出来,这些都是资源缓存的效果。在开发者模式下的Network项下,可以看到大量耗时为0ms、大小为(内存缓存)的请求。这些请求被标记,并没有真正发送到服务器,而是直接在浏览器的内存缓存中读取。拿,所以他的响应时间是0ms,非常快!在图3中,还有一些大小(磁盘缓存)的请求。这些请求实际上并没有发送到服务器,而是在浏览器的磁盘缓存中读取。由于磁盘的速度没有内存快,所以会有几十到几百不等的处理时间。什么时候把请求缓存到内存,什么时候把请求缓存到硬盘,由浏览器自己决定。通常,较小的资源缓存在内存中,较大的资源缓存在磁盘上。在图4中,还有一些返回码为304,大小在几十到百字节的请求。这些请求的资源在本地有缓存,但是缓存内容已经过期,浏览器不确认是否需要更新,所以向服务器发起请求。确认资源没有过期后,服务器会返回一个没有消息体的返回码为304的消息。在这种情况下,会减少文件资源的传输,降低带宽的利用率。但是由于仍然需要向服务器发起请求,处理时间会在几十毫秒到几秒之间。图53.HTTP缓存相关协议及应用浏览器如何确定哪些资源可以缓存,缓存资源什么时候过期,什么情况下需要更新本地缓存资源?这些都是由HTTP协议头决定的。缓存方式可以分为本地缓存和协商缓存两种。本地缓存就是直接使用本地缓存的资源,不会再向服务器发送请求。协商缓存是根据本地浏览器最后一次下载资源的时间和标签向服务器发送下载请求。如果服务器认为本地资源是最新的,则只会返回响应码为304的HTTP响应头,浏览器会直接使用本地资源,否则服务器会根据正常响应,响应码为200。这两个缓存不是相互排斥的,而是相辅相成的。浏览器将首先使用本地缓存。如果本地缓存已经过期,它会确认缓存内容的有效性,并通过协商缓存来更新缓存。可缓存的资源一般都是静态资源,但是浏览器不会根据资源类型判断是否可以缓存。浏览器根据响应码判断是否可以缓存。只有成功的响应才会被缓存。成功响应码包括:200(OK)、203(Non-AuthoritativeInformation)、206(PartialContent)、300(MultipleChoices)、301(MovedPermanently)、410(Unauthorized),另外缓存一般是GET请求,而一个POST请求一般是不会做缓存的。一个资源是否可以缓存,如何缓存,什么时候缓存,都是由HTTP头决定的。涉及的HTTP头属性包括:Expires、Pragma、Cache-Control、Last-Modified/If-Modified-Since、ETag/If-None-Match。Expires:指定一个绝对时间,缓存中的资源将在该时间后过期。例如:Expires:Tue,04May202222:00:00GMT标志资源文件将于2022年4月5日星期二22点过期,过期前浏览器会直接使用内存中的缓存或者硬盘。过期后,浏览器会再次请求新的资源。Pragma:是一个通用的定义。目前只有一种标准定义no-cache,用法如下:Pramgma:在请求头中使用no-cache,意思是强制缓存服务器向源服务器提交请求。这个一般用在代理服务器上,当我们使用Ctrl+F5刷新浏览器时,这个属性会自动包含在请求头中;在响应头中使用,浏览器在使用缓存信息时需要服务器评估缓存的有效性,同时也需要将文件的属性信息(文件修改时间,ETag)发送给服务器。如果文件资源有更新,则正常返回,否则返回304,告知浏览器缓存有效。所以这里的no-cahce并不是说不缓存,而是需要在使用前进行验证。如果打算禁止浏览器缓存,则需要使用HTTP1.1协议中新增的Cache-Control。Pragma和Expires是HTTP1.0中的标准。Cache-Control是在HTTP1.1中加入的,功能更加丰富。常用的函数定义包括:Public:响应可以被任何对象缓存,即使是那些通常不可缓存的内容;private:response只允许单个用户缓存,不能作为共享缓存使用(通常指代理服务器);无缓存:与Pramgma相同:无缓存;no-store:这就是我们通常理解的浏览器不缓存数据,此时任何请求和响应都不会被缓存,新的请求也不会在缓存中读取,需要重新发起请求到服务器;max-age:指定资源在缓存中的最大时间段(以秒为单位),超过该时间段缓存将失效。Cache-Control:public,max-age=864000表示这个资源可以任意缓存,缓存周期为10天;Cache-Control:no-store表示这个资源不能被浏览器缓存,因为有可能每次变化都访问到。Cache-Control:privete,no-cache,max-age=0表示该资源可以缓存,但是会立即过期,下次访问时需要查询服务器确认。通过Cache-Control,可以根据资源的变化,灵活定义浏览器可以缓存哪些数据以及缓存的时长。然而,缓存的资源一般很少改变。大多数情况下,缓存期过后,服务器上的资源不会发生变化。此时不需要重新下载服务器上的所有资源。这时候就用到了协商缓存。根据HTTP1.0协议的要求,响应头中需要包含:Last-Modified,标识当前资源文件的最后修改时间。使用的格式是:Last-Modified:Tue,04May202222:00:00GMT浏览器在缓存资源的同时,这个时间也会被同时存储。当本地缓存过期,再次发起请求时,需要在请求头中包含If-Modified-Since。格式为:Last-Modified-Since:Tue,04May202222:00:00GMTservice终端收到这个请求后,会将这个时间与本地文件的修改时间进行比较。如果本地文件已经更新,则正常返回完成消息;如果本地文件的更新时间没有变化,会返回一个响应码304的响应头,告诉浏览器服务器文件没有变化,节省了整个资源文件的下载时间和流量。在使用Last-Modified/If-Modified-Since时,需要注意的几个问题是:1)时间精确到秒级。如果一秒钟内只能发生多次变化,则无法识别此方法。所以不适合变化频率高的资源,需要保证变化间隔大于1秒;2)在负载均衡的多台服务器上发布时,需要保证每台服务器上的文件修改时间一致,一般需要通过tar包发布发布;如果直接拷贝文件到各个服务器,很有可能各个服务器的时间不一致,导致资源文件更新判断错误,导致重复下载。HTTP1.1协议中新加入的ETag/If-None-Match使用了另一种方法来判断服务器端的文件是否发生了变化。Etag(EntigyTag)是根据文件的属性生成的ID。这些属性可以包括:inode、修改时间、文件大小和其他文件属性信息。不同的WEB服务器可以实现自己的ID生成策略,用这个Etag代替单个文件修改时间来标识一个文件是否发生了变化。这样可以解决一些Last-Modified不能解决的问题:1)有些文件可能会周期性的发布,但它的内部变化不一定会发生。只是由于完全发布才更新了修改时间。这时,我们不想让客户认为文件已经更新,重新下载;2)有些文件修改频繁,修改时间间隔小于1秒,Last-Modified/If-Modified-Since无法识别。同时,ETag对于集群部署服务也存在与Last-Modified相同的问题。同一个文件在不同的服务器上可能会生成不同的ETag,因为除了文件大小外,不同服务器上的修改时间和Inode也可能不同。不一样的,这时候可以自定义ETag的生成方式,保证同一个文件在不同服务器上ETag的一致性。4、HTTP优化加速技术浏览器和服务器端可以使用缓存技术来加速静态资源的访问。但是由于客户端接口的丰富和多样化,需要下载和处理的静态资源会更多。下载大量资源文件也会导致客户端资源加载缓慢,用户体验下降。图6从上图可以看出,下载js文件时,每个文件需要1~2秒(这是在内网环境下,所以下载速度慢肯定不是网络环境造成的)。图7在1~2秒的详细时间查看,可以看到整体时间为1.76秒,Stalled时间为1.67秒,实际下载时间为0.09秒。大部分时间花在Stalled上。根据Chrome的说明,Stalled状态可能是由于以下原因:有更高级别的请求;同一个请求源服务器打开了6个链接;浏览器正在批处理磁盘缓存。也就是说,为了避免对后台服务器造成特别大的影响,浏览器最多只能同时打开6个TCP连接。这6个连接中,所有资源文件只能顺序下载,其他冗余资源下载请求只能下载。可以排队等。因此,唯一的解决办法就是减少下载请求的数量。具体方法是合并需要下载的资源文件。js和css文件可以通过将相同类型、功能、稳定性的资源合并到一个文件中来进行合并。针对大量小图资源的需求,可以将大量小图合并为一张大图一次性下载缓存,使用时通过程序截取需要的部分即可。需要注意的是,这种优化可以加快资源下载速度,但可能会增加编程的复杂度和浏览器的CPU消耗。这两方面的优势需要根据实际情况来选择。5、CDN加速技术上面介绍的浏览器缓存技术主要是利用浏览器缓存已经访问过的文件资源,以加速下次访问。但是浏览器第一次访问网站时,还是需要下载大量的资源。如果服务器在广州,用户在新疆,整个资源的下载过程还是比较慢的,因为仅仅一次网络传输的时间就会达到几十毫秒。一次网页访问会包含数百或数千次网络传输,仅网络传输时间就达到秒级。这时候就需要用到CDN技术,一种分布式网络资源缓存技术,它不仅可以加快网站静态资源的下载速度,还可以大大节省互联网带宽。CDN的全称是ContentDeliveryNetwork,即内容分发网络。其主要功能是将站点上的各种静态资源分发到分布在全国各地的节点上,使用户就近访问所需资源,从而缩短用户下载时间。静态资源的延迟提高了用户访问网站的响应速度和网站的可用性。图8CDN将在全国乃至全球部署缓存服务器,为网络运营商提供多种接入方式。当客户端基于域名发起请求时,DNS服务器会根据客户端发起的请求的IP地址,解析出理论上距离最近、访问速度最快的CDN网络中缓存服务器的IP地址客户。CDN缓存服务器缓存的资源内容的更新策略主要包括主动更新和被动更新。主动更新是在源服务器发生内容更新后,主动通知CDN服务器更新资源。CDN会扫描源服务器下指定目录下的所有资源,并更新本地缓存服务器。被动更新是指客户端访问CDN服务器时,如果CDN缓存服务器发现本地缓存中不存在,就会向源站服务器发起回源请求,CDN缓存服务器保存获取到最新资源后,将最新资源发送到本地缓存服务器。6、总结上面介绍的WEB服务器静态资源加速技术,主要是从技术层面通过缓存来加速静态资源的下载,但是为了越来越丰富多样的页面展示,需要下载的资源越来越多。缓存技术并不能完全达到满意的效果,那么就需要结合懒加载技术。页面采用批量分步渲染的过程,先展示部分内容,同时在后台异步下载其他非必需资源,让浏览器展示部分信息到用户至上,没有无聊的等待,给用户带来更好的用户体验。此外,还有很多其他的用户体验优化方法需要结合使用,以提高系统的易用性和易用性。