原因
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 configimport pylibmcfrom 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()
新聞熱點
疑難解答