用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.
明显快了很多...