使用 ruby 开发 web 应用之所以高效,ruby 语法友好是一方面,另外一方面就是社区资源,涉及 web 应用场景的 gem 有很多。
比如连 HTTP 加速器HTTP accelerator这种产品,都有纯 ruby 的实现:rack-cache。
使用起来,难以置信的简单:
require 'rack/cache'
use Rack::Cache,
:verbose => true,
:metastore => 'file:/var/cache/rack/meta',
:entitystore => 'file:/var/cache/rack/body'
run app
我们的产品中,所有上传图片,都是存储在 MongoDB,而且通过rack-thumb实现图片缩放功能,通过 url 中指定图片尺寸,就能获取对应尺寸的图片。
通过 HTTP 加速器,一种尺寸的图片,只需要生成一次,以后就从加速器的缓存中返回。
最初就是用简单的 rack-cache 来做 HTTP 加速,但很快就遇到瓶颈,
首先是性能,使用 rack-cache 后,配置为硬盘存储,测试响应性能,仅提升 20%。将 rack-cache 的存储改为 heap 后,性能提升也不显著。
其次是拓展,rack-cache 是 rack 的插件,必须跟着 app 走。部署多几台 app,那它们之间的缓存是无法共享的,除非将存储改为 Memcached,但是用内存来缓存静态资源,太奢侈!
所以总体来说,rack-cache 性价比太低,在有规模的生产环境中用,很不划算。
所以不得已,还是要跳出 ruby 的圈子,找业内通用的方案,首选肯定是名气最大的varnish。 安装的是最新版 v4.0,官方提供 CentOS 安装的 rpm,所以安装很方便。
把存储配置为硬盘,测试响应性能,能带来 200 倍以上的性能提升,一个词来形容当时心情的话,那就是:惊喜。 通过对 vcl 的配置vcl-backends,支持多个 app 也很方便。
不过 varnish 的在转发 request 到 app 时,只有两种策略:循环和随机,没有类似 nginx 的负载均衡功能,不过这点缺失影响不大。
虽然 rack-cache 比较弱,但它有个优势:容易用。如果是小项目,可以先用,等遇到性能瓶颈,再升级方案,用 varnish。
我们的 SaaS 产品友好速搭在内测期,用户数量是固定的,用了 4 台 rack-cache。之后上线开放,发现性能跟不上,很快就换成 varnish,配合一台处理缩略图的 app。 部署 varnish 的那台机器,4000req/s 的性能,应付 1000rpm 以内的压力,绰绰有余,此外,cpu 和内存也都很稳定,果然名不虚传。