用Python的Tornado框架结合memcached页面改善博客性能

原因

Blog是一个更新并不很频繁的一套系统,但是每次刷新页面都要更新数据库反而很浪费资源,添加静态页面生成是一个解决办法,同时缓存是一个更好的主意,可以结合Memcached添加少量的代码进行缓存,而且免去去了每次更新文章都要重新生成静态页面,特别当页面特别多时.
实现

主要通过页面的uri进行缓存,结合tornado.web.RequestHandler的prepare和on_finish方法函数, prepare 主要是请求前执行,on_finish()是请求结束之前执行.在渲染模板时缓存页面内容,然后在请求前检测是否有缓存,如果有直接输出缓存,结束请求,在POST提交之后清空所有缓存,重新生成缓存,从而保证内容实时性.由于登录用户和普通用户的页面不相同,所以不缓存登录用户页面(代码中没有体现,请自行实现).主要python代码(省略了模板渲染的代码):

#!/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 网站压力测试对比了缓存前后的结果: 使用缓存前

$ 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.

使用缓存后:

$ 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.

明显快了很多...

(0)

相关推荐

  • python采集博客中上传的QQ截图文件

    哎,以前写博文的时候没注意,有些图片用QQ来截取,获得的图片文件名都是类似于QQ截图20120926174732-300×15.png的形式,昨天用ftp备份网站文件的时候发现,中文名在flashfxp里面显示的是乱码的,看起来好难受,所以写了一个python小脚本,爬取整个网站,然后获取每个文章页面的图片名,并判断如果是类似于QQ截图20120926174732-300×15.png的形式就输出并将该图片地址和对应的文章地址保存在文件中,然后通过该文件来逐个修改. 好了,下面是程序代码: im

  • python实现批量下载新浪博客的方法

    本文实例讲述了python实现批量下载新浪博客的方法.分享给大家供大家参考.具体实现方法如下: # coding=utf-8 import urllib2 import sys, os import re import string from BeautifulSoup import BeautifulSoup def encode(s): return s.decode('utf-8').encode(sys.stdout.encoding, 'ignore') def getHTML(url

  • python实现博客文章爬虫示例

    复制代码 代码如下: #!/usr/bin/python#-*-coding:utf-8-*-# JCrawler# Author: Jam <810441377@qq.com> import timeimport urllib2from bs4 import BeautifulSoup # 目标站点TargetHost = "http://adirectory.blog.com"# User AgentUserAgent  = 'Mozilla/5.0 (X11; Lin

  • Python采用Django开发自己的博客系统

    好久之前就想做一下自己的博客系统了,但是在网上查了查好像是需要会一些Node.js的相关知识,而且还要安装辣么多的库什么的,就不想碰了.但是我遇到了Django这么一款神器,没想到我的博客系统就这么建立起来了.虽然是最基础的类型.但是也算是成功了,这篇博客比较适合对Django有了一定了解的童鞋,如果是新手的话,建议先看一下django的基础知识点再来做实验,这样效率更高! 好了,话不多说,开始吧. 搭建框架  •创建项目及应用 搭建框架的意思,就是安装Django以及做好相关的配置.因为我是在

  • Python+django实现简单的文件上传

    今天分享一下Django实现的简单的文件上传的小例子. 步骤  •创建Django项目,创建Django应用  •设计模型  •处理urls.py 以及views.py  •设计模板,设计表单  •运行项目,查看数据库 下面我们就一起来分别完成每一个小部分吧. 创建项目和应用 django-admin startproject Django_upload django-admin startapp app 添加一个名为upload的目录,待会要用哦. 然后记得在settings.py 中的INS

  • Python+Django在windows下的开发环境配置图解

    1         安装配置开发环境 1.1   准备安装 下载以下软件 Eclipse for C/C++ SUN JDK 1.6 不一定要1.6,1.5的也可以 Python3.1  Python2.6.4  Pythone2.5.2 mod_python-3.3.1.win32-py2.5-Apache2.2 MySQL-python-1.2.2.win32-py2.5 pysqlite-2.5.5.win32-py2.5 python.pydev.feature-1.5.0.125198

  • Python 爬虫爬取指定博客的所有文章

    自上一篇文章 Z Story : Using Django with GAE Python 后台抓取多个网站的页面全文 后,大体的进度如下: 1.增加了Cron: 用来告诉程序每隔30分钟 让一个task 醒来, 跑到指定的那几个博客上去爬取最新的更新 2.用google 的 Datastore 来存贮每次爬虫爬下来的内容..只存贮新的内容.. 就像上次说的那样,这样以来 性能有了大幅度的提高: 原来的每次请求后, 爬虫才被唤醒 所以要花大约17秒的时间才能从后台输出到前台而现在只需要2秒不到

  • Python Django使用forms来实现评论功能

    貌似Django从版本1.6开始就放弃了对自带的comments的使用,具体原因未查,但是现在使用Django的内部的模块也可以实现评论功能,那就是借助于forms模块,下面是我的一个小例子. 环境准备  •操作系统 : windows 7 64 位旗舰版  •IDE: PyCharm 2016.1  •Python :2.7.11  •Django :1.9.6 设计 所谓设计,就是指我们将要实现的评论功能将要涉及的底层模型.我这里简单的设计如下,大家按照自己的想法,可以随意的设置,我这里的设

  • 如何使用python爬取csdn博客访问量

    最近学习了python和爬虫,想写一个程序练练手,所以我就想到了大家都比较关心的自己的博客访问量,使用python来获取自己博客的访问量,这也是后边我将要进行的项目的一部分,后边我会对博客的访问量进行分析,以折线图和饼图等可视化的方式展示自己博客被访问的情况,使自己能更加清楚自己的哪些博客更受关注,博客专家请勿喷,因为我不是专家,我听他们说专家本身就有这个功能. 一.网址分析 进入自己的博客页面,网址为:http://blog.csdn.net/xingjiarong 网址还是非常清晰的就是cs

  • python抓取最新博客内容并生成Rss

    osc的rss不是全文输出的,不开心,所以就有了python抓取osc最新博客生成Rss # -*- coding: utf-8 -*- from bs4 import BeautifulSoup import urllib2 import datetime import time import PyRSS2Gen from email.Utils import formatdate import re import sys import os reload(sys) sys.setdefaul

随机推荐