加缓存是最有效和简单的性能优化方法。

0. PHP OPcode Cache

开PHP7自带的OPcache就完了。OPcache 通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能, 存储预编译字节码的好处就是省去了每次加载和解析PHP 脚本的开销。
1. Object Cache
mediawiki把存储抽象成了4种大类:
Local server ( < 0.1ms,从内存读取,小容量,应用之间不共享) 会自动尝试使用APCu和WinCache
Local cluster 和 WAN cache (~1ms,来自别的服务的内存,中等容量,应用之间共享) 这两种的区别是会不会被跨数据中心的复制,对我们这种只有一台服务器的没区别,一起用memcached
Main Stash (1-10ms,可能导致磁盘读写,半永久,在服务间共享,跨数据中心同步) 默认使用数据库,wikipedia曾经用redis集群来存这种数据,后来迁移到了MariaDB集群,我们也选择直接存到数据库里面。

2. Cache Proxy(HTTP accelerator)

我们使用Varnish来缓存所有的匿名访问,所有可以被缓存的内容都会至少缓存5分钟,大部分请求都会被Varnish直接响应其在内存中的副本,省去了php缓慢的html/js/css生成。由于侧边栏和页面内容,当用户有登录态时,对于html页面的请求几乎是无法被缓存的。
当一个用户编辑页面并保存,Mediawiki会发送请求到Varnish服务器要求刷新这些页面的html缓存。像单个机器发送请求这个功能其实已经被废弃了,wikipedia换成了用htcp来广播,我们没研究htcp,所以我们稍微改了一下

includes/deferred/CdnCacheUpdate.php
Varnish通过一套DSL来控制其行为,比起通过多个配置项来控制,这种方位更为灵活,可以轻松的实现一些通过配置项难以描述的行为,比如基于UA的自动桌面视图到移动视图跳转就是由Varnish直接完成的。
Varnish还完成了请求节流并提供了额外的可用性。在一个回源请求发起前,varnish会先检查是不是已经有同样的回源请求。当一个请求访问一个刚刚过时的缓存时,varnish会立刻返回这个缓存,并尝试拉取新的响应,在一个缓存失效后的5分钟内,这个行为会不断的重复直到获得新的缓存。这提供了额外的缓冲时间来处理源站的故障。
我们使用阿里云的CDN服务来加速资源的加载。


受限于CDN的表达能力和价格,我们基本只将其用于加速静态资源和提供HTTPS服务。当有用户上传了一张图片的新版本,我们有一个拓展会让mediawiki会调用阿里云的sdk来刷新相关的资源。
https://github.com/MooncellWiki/mediawiki-extension-PurgeAliyunCDN