一次千万pv投放的心路历程

442 阅读5分钟

本文提送了在做项目过程中的一些思路和方向,以及缓存的一些基础知识,如有不正确的地方请指正。

不久前我接到了这样一个需求,我们即将做一些活动的投放,页面的交互并不复杂,但是可能会面临大流量的访问,让我提前做一些储备知识和应对的方案。经过翻阅一些资料,在大的方向上总结了一下。

CDN

CDN,这是一种分发网络技术,用户访问一个页面资源的时候,会通过负载均衡的形式就近的去获取资源,降低网络拥堵的情况,提高资源的可访问性。

抛弃vue

由于页面的交互相对简单,并没有很复杂的流程,因此考虑的技术方案是通过原生的js和html来编写页面。当然,复杂页面也可以通过nuxt或者是ssr来实现,那是一套相对复杂的流程,在此一笔带过。考虑使用原生实现的原因是因为,vue相对快捷的编码的同时,本身需要将vue框架打包进来,带来不小的js包的大小。

服务端返回html

再有就是我考虑了通过node直出html的形式来返回页面,而不是我们平时的先返回一个空白页面然后请求js包,然后渲染dom请求数据这样的过程,也就是通过最复古的方式返回了一个html资源。这种形式可以大大的减少用户等待的焦虑感。采用的方案就是express和ejs来实现。通过express在服务端获取好页面所需要的数据,然后由ejs模板来动态的渲染页面。

我本来以为事情到此就应该结束了,但在开发的过程中突然发现了一个问题,我页面中的数据由于使用了CDN的缓存,因此,除非缓存到期,否则数据是不会更新的。

生活就像一颗糖,你永远也不知道下一颗,会有多粘牙。

再粘牙也要吃完不是,于是我开始思考这个问题需要如何解决。我去网上翻阅了一些文章和资料,从而学习了一些关于缓存的知识,由于我们以前的静态服务是通过nginx启动的,因此如果有修改调整的话是需要由运维同学来操作的。但现在不一样了,在项目中我接入了express,也就意味着我有了服务端的代码,理论上来讲,服务端能做的事情,我都可以做了。因此,我可以通过header来控制缓存。

那么接下来,我们可以聊下关于缓存的一些知识

强缓存

expires

在http1.0的时候,缓存的控制是通过expires这个字段来控制的,这个字段会包含一个静态时间,在这个时间之后,缓存就会失效,而现在已经基本默认是http1.1的服务,所以这个字段已经基本放弃。

cache-control

而现在控制缓存主要使用的字段是cache-control。 cache-control常用的取值有几种,分别对应了不同的规则

  1. no-store,不使用任何缓存,页面实时性要求很高的时候则需要用到它。
  2. no-cache,使用协商缓存(对比缓存)来验证数据。
  3. private,客户端可以缓存。
  4. max-age,缓存在xxx秒后失效。
  5. public,客户端和代理服务器都可以缓存。

协商缓存

协商缓存是指强缓存失效后,浏览器会携带一些标识向服务器发起请求,由服务器根据标识判断是否使用缓存的过程。

Etag和if-none-match

Etag是服务器返回资源时,会带有该资源的唯一标识,而if-none-match则会携带该资源上一次的Etag标识,如果标识发生变化,则标识无更新,返回304状态码,不一致则会获取最新资源,返回200状态码。

last-modified和if-modified-since

last-modified是服务器返回资源时带有该资源的最后的修改时间,而if-modified-since则会带有上一次该资源的修改时间,请求到达服务端进行比对,一致则返回304,不一致则返回200。

实践

了解了以上知识,我再在服务端设置了header,信心满满的再去看我的页面header,发现,得确生效了,但是页面确并没有更新。

如图,cache-control已经有了max-age字段。

果然,问题不是那么轻易解决的。

我马上联想到了是不是因为我使用了CDN的缘故,再次询问了我们的运维同学得知,CDN上有关于是否遵从源站header配置,但是他们并没有勾选,因此,我再怎么费力的修改,都无济于事,经过一番磨难,最终,我可以自由的控制缓存的失效时间了。

以上是我在这次项目开发过程中遇到的问题以及处理的方案,当然不是那么的完美,还有一些关于代码编写过程中的优化,例如,js后置加载,优先渲染页面,尽量减少回流重绘,css的编码风格等等,那些我更趋向于编码的规范而非优化过程,因此就不详细描述啦。

tip

看到最后再分享一个小tips吧:

在开发过程中我发现,不勾选disable cache,一直刷新的情况时,html资源是会默认命中协商缓存的,也就是304,也就是需要时刻去服务器访问,以保证能够在html更新的情况下获取最新的html,而如果想要html也命中强缓存,哈哈哈哈,我发现CDN已经将这件事帮我做好了。

如图,勾选之后将禁用浏览器缓存。

最后,如有不正确,或者有更好的方案,欢迎评论指出,万分感谢~