用Python的Tornado框架结合memcached页面改善博客性能
原因
Blog是一个更新并不很频繁的一套系统,但是每次刷新页面都要更新数据库反而很浪费资源,添加静态页面生成是一个解决办法,同时缓存是一个更好的主意,可以结合Memcached添加少量的代码进行缓存,而且免去去了每次更新文章都要重新生成静态页面,特别当页面特别多时.
实现
主要通过页面的uri进行缓存,结合tornado.web.RequestHandler的prepare和on_finish方法函数,prepare主要是请求前执行,on_finish()是请求结束之前执行.在渲染模板时缓存页面内容,然后在请求前检测是否有缓存,如果有直接输出缓存,结束请求,在POST提交之后清空所有缓存,重新生成缓存,从而保证内容实时性.由于登录用户和普通用户的页面不相同,所以不缓存登录用户页面(代码中没有体现,请自行实现).主要python代码(省略了模板渲染的代码):
#!/usr/bin/envpython
#-*-coding:utf-8-*-
#
#Author:cold
#E-mail:wh_linux@126.com
#Date:13/01/1409:57:31
#Desc:
#
importconfig
importpylibmc
fromtornado.webimportRequestHandler
####省略Cache类定义#####
classMemcached(object):
_mc=pylibmc.client.Client(config.CACHE_HOST,binary=True)
def__enter__(self):
ifconfig.CACHED:
returnMemcached
else:
returnCache()
def__exit__(self,exc_type,exc_val,exc_tb):
pass
@classmethod
defget_cache(cls):
returncls._mc
@classmethod
defget(cls,key,default=None):
r=cls._mc.get(key)
ifnotr:
r=default
returnr
@classmethod
defset(cls,key,value,timeout=0):
timeout=timeoutiftimeoutelseconfig.CACHE_TIMEOUT
returncls._mc.set(key,value,timeout)
@classmethod
defdelete(cls,key):
returncls._mc.delete(key)
@classmethod
defflush(cls):
returncls._mc.flush_all()
def__getattr__(self,key):
returnMemcached.get(key)
def__setattr__(self,key,value):
returnMemcached.set(key,value)
classBaseHandler(RequestHandler):
"""继承tornado请求基类,重写prepare和on_finish方法"""
cache=Memcached
defrender(self,template_path,*args,**kwargs):
"""渲染模板"""
#省略渲染模板代码
content=''#渲染模板后的内容
ifself.request.method=="GET"andCACHEDand\
notself.request.path.startswith("/admin"):
self.cache.set(self.request.uri,content)#将渲染后的内容缓存起来
self.write(content)
defprepare(self):
super(BaseHandler,self).prepare()
#如果请求是GET方法,而且不是请求后台
ifself.request.method=="GET"andCACHEDand\
notself.request.path.startswith("/admin"):
#尝试获取当前页面的缓存
cache=self.cache.get(self.request.uri)
#获取缓存则输出页面,结束请求
ifcache:
returnself.finish(cache)
defon_finish(self):
"""重写结束请求前的方法函数"""
ifself.request.method=="POST":
#如果遇到POST提交则清空缓存
self.cache.flush()
缓存系统在redis和Memcached选择了很久,因为只是单纯的缓存页面所以最后选择了memcached,使用pylibmcpython库.
测试
使用webbench网站压力测试对比了缓存前后的结果:使用缓存前
$webbench-c500-t30http://www.linuxzen.com/ Webbench-SimpleWebBenchmark1.5 Copyright(c)RadimKolar1997-2004,GPLOpenSourceSoftware. Benchmarking:GEThttp://www.linuxzen.com/ 500clients,running30sec. Speed=54pages/min,38160bytes/sec. Requests:27susceed,0failed.
使用缓存后:
$webbench-c500-t30http://www.linuxzen.com/ Webbench-SimpleWebBenchmark1.5 Copyright(c)RadimKolar1997-2004,GPLOpenSourceSoftware. Benchmarking:GEThttp://www.linuxzen.com/ 500clients,running30sec. Speed=256pages/min,238544bytes/sec. Requests:128susceed,0failed.
明显快了很多...