各位用户为了找寻关于用Python的Tornado框架结合memcached页面改善博客性能的资料费劲了很多周折。这里教程网为您整理了关于用Python的Tornado框架结合memcached页面改善博客性能的相关资料,仅供查阅,以下为您介绍关于用Python的Tornado框架结合memcached页面改善博客性能的详细内容
原因
Blog是一个更新并不很频繁的一套系统,但是每次刷新页面都要更新数据库反而很浪费资源,添加静态页面生成是一个解决办法,同时缓存是一个更好的主意,可以结合Memcached添加少量的代码进行缓存,而且免去去了每次更新文章都要重新生成静态页面,特别当页面特别多时. 实现
主要通过页面的uri进行缓存,结合tornado.web.RequestHandler的prepare和on_finish方法函数, prepare 主要是请求前执行,on_finish()是请求结束之前执行.在渲染模板时缓存页面内容,然后在请求前检测是否有缓存,如果有直接输出缓存,结束请求,在POST提交之后清空所有缓存,重新生成缓存,从而保证内容实时性.由于登录用户和普通用户的页面不相同,所以不缓存登录用户页面(代码中没有体现,请自行实现).主要python代码(省略了模板渲染的代码):
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# Author : cold
# E-mail : wh_linux@126.com
# Date : 13/01/14 09:57:31
# Desc :
#
import
config
import
pylibmc
from
tornado.web
import
RequestHandler
#### 省略Cache类定义 #####
class
Memcached(
object
):
_mc
=
pylibmc.client.Client(config.CACHE_HOST, binary
=
True
)
def
__enter__(
self
):
if
config.CACHED:
return
Memcached
else
:
return
Cache()
def
__exit__(
self
, exc_type, exc_val, exc_tb):
pass
@classmethod
def
get_cache(
cls
):
return
cls
._mc
@classmethod
def
get(
cls
, key, default
=
None
):
r
=
cls
._mc.get(key)
if
not
r:
r
=
default
return
r
@classmethod
def
set
(
cls
, key, value, timeout
=
0
):
timeout
=
timeout
if
timeout
else
config.CACHE_TIMEOUT
return
cls
._mc.
set
(key, value, timeout)
@classmethod
def
delete(
cls
, key):
return
cls
._mc.delete(key)
@classmethod
def
flush(
cls
):
return
cls
._mc.flush_all()
def
__getattr__(
self
, key):
return
Memcached.get(key)
def
__setattr__(
self
, key, value):
return
Memcached.
set
(key, value)
class
BaseHandler(RequestHandler):
""" 继承tornado请求基类,重写 prepare和on_finish方法 """
cache
=
Memcached
def
render(
self
, template_path,
*
args,
*
*
kwargs):
""" 渲染模板 """
# 省略渲染模板代码
content
=
''
# 渲染模板后的内容
if
self
.request.method
=
=
"GET"
and
CACHED
and
not
self
.request.path.startswith(
"/admin"
):
self
.cache.
set
(
self
.request.uri, content)
# 将渲染后的内容缓存起来
self
.write(content)
def
prepare(
self
):
super
(BaseHandler,
self
).prepare()
# 如果请求是GET方法,而且不是请求后台
if
self
.request.method
=
=
"GET"
and
CACHED
and
not
self
.request.path.startswith(
"/admin"
):
# 尝试获取当前页面的缓存
cache
=
self
.cache.get(
self
.request.uri)
# 获取缓存则输出页面,结束请求
if
cache:
return
self
.finish(cache)
def
on_finish(
self
):
""" 重写结束请求前的方法函数 """
if
self
.request.method
=
=
"POST"
:
# 如果遇到POST提交则清空缓存
self
.cache.flush()
缓存系统在redis和Memcached选择了很久,因为只是单纯的缓存页面所以最后选择了memcached,使用pylibmc python库. 测试
使用webbench 网站压力测试对比了缓存前后的结果: 使用缓存前
? 1 2 3 4 5 6 7 8 9$ webbench
-
c
500
-
t
30
http:
/
/
www.linuxzen.com
/
Webbench
-
Simple Web Benchmark
1.5
Copyright (c) Radim Kolar
1997
-
2004
, GPL
Open
Source Software.
Benchmarking: GET http:
/
/
www.linuxzen.com
/
500
clients, running
30
sec.
Speed
=
54
pages
/
min
,
38160
bytes
/
sec.
Requests:
27
susceed,
0
failed.
使用缓存后:
? 1 2 3 4 5 6 7 8 9$ webbench
-
c
500
-
t
30
http:
/
/
www.linuxzen.com
/
Webbench
-
Simple Web Benchmark
1.5
Copyright (c) Radim Kolar
1997
-
2004
, GPL
Open
Source Software.
Benchmarking: GET http:
/
/
www.linuxzen.com
/
500
clients, running
30
sec.
Speed
=
256
pages
/
min
,
238544
bytes
/
sec.
Requests:
128
susceed,
0
failed.
明显快了很多...