主题:【原创】网站,没有缓存怎么行,520码 -- 铁手
最近一段时间网站出现大量520错误返回。目前我用 cloudflare 来加速内容访问。基本原理是用户访问西西河,实际上是到 cloudflare 要内容,cloudflare 作为中间人在必要时到我的服务器要内容。这个520错误返回,是我服务器和 cloudflare 之间的问题。经过大量排查,特别是各种试图,也没法在 web server 的 log里找到对应的错误信息后,现在基本确定是因为 cloudflare 程序认为我的服务器响应太慢有关。正好我一直想找时间把西西河的缓存机制理清一下,现在问题找上门来,就赶紧抓紧完善一下。
欢迎帮忙质疑,并帮忙改进实施方案。我是三脚猫的功夫,所以特别希望来点实锤。
每个网页的内容生成,在后台基本上涉及到数据库、程序计算、缓存机制设定。
数据库方面的优化,这里暂时略过。将来可能转到 pgsql(是好注意么?),准备专注到那里。
后台程序根据内容生成网页。程序里对一些局部操作的内容做了缓存,可以减轻数据库和程序计算的负担。
在此基础上,希望通过访问缓存机制来尽可能减少对服务器的直接需求。尽可能让内容从本地或者是代理缓存那里获得,而不是每次都要从服务器那里取。
对返回给浏览器的内容设定缓冲控制,要考虑两个方面:一是缓存时间,要考虑静态和动态内容,二是缓存所在,要考虑用户终点(私缓)和中间代理CDN(公缓)。
象 Javascript 或 CSS,及一些图片,原则上一旦确定基本上不变,缓存时间可以长一些,这个在 Web server 中可以设定。
在后台程序生成的内容页面中,一部分内容中长期不变化,一部分内容短期变化频繁,还有一部分和用户是否在线有关。以看一个帖为例,帖内容中长期不变,帖得花变化会比较频繁,对作者的屏蔽或趋订则和用户在线有关。缓存策略可以分别为公缓长、公缓短、私缓,必要时通过ETAG到后台验证。
随着技术的发展和应用,考虑以后每个页面都根据上述分析分为三个访问请求,对每个请求采用不同的缓存策略。
Cache-Control 的一些参数和解释。
缓存控制有关。
public:能被所有缓存使用,包括代理CDN
private:只能由终点用户缓存。
no-store:不做缓存
no-cache:缓存,但下次访问,则必须先到源服务器去验证是否有变。
缓存时间有关
max-age=seconds 秒钟计算。
s-maxage=seconds 代理缓存时间,和终点用户无关。似乎没道理需要和max-age不一致。可不用。
缓存验证有关
must-revalidate 如果缓存过期,需要到源服务器确认之后,才能使用。
proxy-revalidate 同上,但只和代理有关。
immutable 在期限内不会改变,因此不用到源头验证。
no-cache 和 max-age=0, must-revalidate 等效,每次都需要去源服务器去验证。
在只有 max-age=0 时,如果网络不通,则缓存可用。
另外需要注意,如果内容返回带有 cookie,代理基本上应该不会缓存。
则,对于公缓,如果有效期限比较确定的,可类似
Cache-Control: public, max-age=86400
对于公缓,如果有效期限不确定,需要到源服务器确认
Cache-Control: public, no-cache
Cache-Control: public, no-cache, must-revalidate (must-revalidate 这里不需要吧?保险起见?)
对于私缓,根据上述两种情况,用 private 替换 public 就可以。
对于一些特殊情况,完全不缓存的
Cache-Control: no-store, max-age=0
比如:之前有缓存,但是改成不缓存,硬刷新后,如果没有 max-age=0,则内容还可以从旧的缓存来,有 max-age=0 则会导致刷新。
大致就这样。欢迎补充。
到cloudflare上看了一下,似乎有不少用户也是最近出现类似问题。我在error log里面找,似乎也找不到什么关联的。也许是cloudflare减小了timeout时间(我觉得并不慢啊)。
你说的镜像压力测试,是完全独立,但是程序相同,还是说网站本身的镜像?我对这方面不熟悉。
眼下大部分西西河的内容并没有被 cloudflare 所缓存,多一些被缓存也许能改善一些。
总数据量大概是多少?
页面生成为什么不放在浏览器做呢?生成的页面会缓存吗?
如果是速度慢的话,瓶颈在哪里呢?最好针对瓶颈做优化。
520的出现比较随机,LOG里我也没怎么看到错误,现在最大的可能就是cloudflare认为从我这里取内容太慢。也许是个别功能慢吧,但不管怎样,缓存的优化都要做一下。
页面的生成,目前主要在服务器实现,有一部分由浏览器通过 VUE 来实现,以后会更多一些。主要的顾虑是搜索引擎的检索,所以VUE照顾那些不影响检索内容的地方。
具体细节很多,要看西西河整体的架构来定,这里只能一般性的随便说说供你参考。比如说我们现在给客户维护的生产系统,至少要有一个Staging系统,端到端软硬件环境和生产系统完全一致,生产数据定期复制到Staging系统。这样生产系统有问题可以尽量试着在Staging系统测试和调试。可以考虑在Cloud上建一个Staging系统,根据Cloud定价,平时可以不启动或者保持一个最小系统来节省费用,测试时再按需增加CPU,RAM,网络等系统资源。
另外,不知道西西河有没有enable access log,如果有的话而且time-taken也配置了的话,可以统计一下520错误时访问的time-taken时间,如果真是cloudflare timeout的话,两者是有联系的,应该可以看出来。
不了解具体情况,泛泛而谈,希望抛砖引玉吧。
或者可视化监控的系统,最好看看平均响应时间和P99时间。
如果能确定是响应时间很慢的话,要分析下子模块(比如数据查询模块,页面生成模块,或者更细分)耗时,找到最慢的模块来优化。
不太了解西西河后台的具体业务逻辑,盲猜的话,如果只有数据查询+页面生成,整体响应时间不应该超过200ms。
西西河整体的qps是多少?
单机系统还是集群?如果是,集群规模多大?硬件配置如何?
后台编程语言是什么?
存储用的什么系统?
数据量多大?
大致和 Cloudflare 对源服务器的 keepalive timeout 的响应有关。具体细节不知道,猜测是每次到 timeout Cloudflare 就返回 520 所以源头没有错误记录。如果 keepalive off 就不会有这个问题。
Cloudflare 的这个软件问题,影响了很多人,持续了几个星期,好在现在终于彻底搞定了。
关于网站本身,具体不好说,但用 Cloudflare 以后,负载是小很多,当然现在各种因素下,访问量本身也比以前小不少。
目前存储用 MYSQL,但考虑转到 PGSQL。主要考虑mysql, mariadb这些纠结,mysql变成oracle一部分,而且pgsql看上去也不差,就算支持开源吧。不知道你对此有没有看法?
基本上系统设置相同,数据基本上也类似。Cloud上建一个Staging系统是个好主意,最接近实际情况。
520现在几乎绝迹了。是cloudflare的软件问题,具体机制不清楚,估计是对服务器设定的 keepalive timeout 有关,在timeout的时候直接返回520所以源头没有任何错误记录。
比如带宽,延时,负载均衡等。另一方面存储设备也会有些不同。
这些因素在网站访问量大时都会有一定影响。
也说不清楚。技术上用mysql是完全没有问题的,数据量太大分库分表就行了,查询量大就用缓存。