Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1198960
  • 博文数量: 272
  • 博客积分: 3899
  • 博客等级: 中校
  • 技术积分: 4734
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-15 14:53
文章分类

全部博文(272)

文章存档

2012年(272)

分类: 系统运维

2012-06-26 16:23:00

前段时间一直太忙了,所以planet 2的开发处于停滞状态,这两天重新捡起来,首页要做的是性能优化。

我们之前写的代码性能实在是很差,逻辑处理已经比较复杂了,所以要理清这些东西不是件轻松的事情。

一开始,我们的主要页面响应时间为10秒左右,这绝对是不可接受的,所以开始了我们的优化之旅。

首先,把各个class中调用数据库的地方全部统一,因为之前每个API自己要查询数据库的时候,都是把数据全部掉出来查一遍,然后再filter,这样的效率是极其低下的,因为如果某个逻辑处理需要连续调用很多不同的API,就要重复查询数据库N次。

所以我集中把数据库查询初始化在了class __init__(self)里,这样只要class初始化一次,就能够满足所有同时调用的API的请求。

其次,光这样还不够,同样会效率非常低下,频繁的查询数据库也会造成CPU飘高。于是我开始把查询出来的数据全部丢入了memcacheAPI调用的时候就先看看memcache里有没有这些数据,如果有,就直接从memcache里拿了,如果没有,再去查询数据库,同时把查出来丢到cache里。

这项改进做出后,性能果然大大提高,10倍左右吧,原来需要10秒才能完成的工作,在数据被cache后,缩短到了1秒左右。

但是这又带来另外一个问题,就是逻辑有点混乱。因为不同的API都会去读写memcache,这样有时候写操作后,memcache没刷新,返回的页面还是旧数据。这些地方一多,逻辑关系就很难理清了。

同时还发现了另外一个问题,CPU time还是没有降下来,而GAECPU time是有限制的,如果过高,很容易就达到了限制,从而要额外缴费。

于是我想把CPU time降下来。GAE提供了专门的API用于性能测试,如下:

import logging
from google.appengine.api import quota

start = quota.get_request_cpu_usage()
do_something_expensive()
end = quota.get_request_cpu_usage()

logging.info("do_something_expensive() cost %d megacycles." % (start - end))

使用这个API,在函数调用的前后插入,然后记录到log里,就可以再admin console里看到信息了。

注意这个API只能在线上环境用,本地测试环境不能用。这也导致我直接在线调试,一天发布了好多次。

这是个体力活,经过一系列追踪后,我终于发现了罪魁祸首!

template.render(path, values)

这个django里的模板渲染函数效率极其低下,而且非常吃CPU!!

怎么办? 第三方库里的东西不好改,改了还不好升级。

于是我走了另外一条路,把所有的页面全部丢进memcache

具体是这样做的:

1.
根据url请求缓存该页面,如果下次有对该url相同的GET请求过来,则直接从memcache中返回缓存页面
2.
约定所有的写操作全部通过POST完成,如果写操作执行后,则删除memcache中缓存的对应页面,页面需要重新生成进缓存

这样做后,性能再次提高了10倍,在我的本地测试,响应时间大概在60-80ms,比原来1秒左右提高了十倍,比原来的10秒左右提高了100倍!!


除了利用好memcache外,还有一些常规的性能优化技巧,比如增加静态图片、jscss等的浏览器缓存时间,还有一些技巧,google下可以找到很多,就不在这里赘述。

值得一提的是静态文件缓存,GAE的配置文件中直接提供了此功能:
比如在 app.yaml中这样写
handlers:
- url: /css
static_dir: static/css
expiration: "30d"

- url: /js
static_dir: static/js
expiration: "3d"

- url: /pic
static_dir: static/pic
expiration: "30d"

意思就是缓存30

"3d 5h 2m 8s"
就是3天,5小时,2分钟,8秒,规则很简单。更多的可以查阅开发手册。

加上这个后,webserver就会自动给response增加 cache-control expire 头。

但是经过我测试,发现只有IE认识,FF居然不认!

悲剧啊,

FF
只认 Last-Modified 头,但是这个实现则需要自己写了,配置文件里管不到。

网上也有现成的解决方案

http://www.ipsojobs.com/blog/2008/06/17/how-to-create-a-simple-but-powerful-cdn-with-google-app-engine-gae/

但是出于成本考虑,我就不折腾了。

附上两张效果图
调优前后

调优前首页的响应时间是 18.09秒, 调优后响应时间是 88毫秒

可以看到性能提高了200多倍

以上就是我的一点实践经验了,希望可以帮助一些有需要的朋友少走弯路。

阅读(1388) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~