上一篇博客写了flask模块实现web服务搭建的基本方法以及简单的缓存功能,但是这种缓存随着服务重启便会丢失,也无法满足多个服务共享缓存的需求,因此,我们通过redis来实现web服务的分布式缓存。
import redis client = redis.StrictRedis(host="***",port="***") cache = Cache(client)
以斐波那契数为例:[fn=f(n-1)+f(n-2)]
我们通过递归构造缓存方法如下:
def get_fib(self, n): if n == 0: return 0, True if n == 1: return 1, True result = cache.get_fib(n) if result: return result, True result = self.get_fib(n-1)[0] + self.get_fib(n-2)[0] cache.set_fib(n, result) return result, False
即:如果服务器处理过n,则n以下的结果再以后的调用中皆可以直接返回缓存答案。
第一次求fib(213) cached为false 服务器首次计算
第二次求fib(200) chaend为true 服务器通过缓存直接获取答案
重启服务器进程或其他服务端口不影响缓存提取
扫描二维码关注公众号,回复:
1562691 查看本文章
![](/qrcode.jpg)
API服务扩展
1.MethodView
把参数直接注入到MethodView的构造器中,不再使用request.args,而是将参数直接放进URL里面
app.add_url_rule('/fib/<int:n>', view_func=MathAPI.as_view('fib', cache)) class MathAPI(FlaskView): def __init__(self, cache): self.cache = cache def get(self, n): …… def post(self, n): ……
2.flask-classy
flask默认的MethodView无法在一个类里提供多个不同URL名称的API服务。所以接下来我们引入flask的扩展flask-classy来解决这个问题。
pip install flask-classy
完整代码:
import math import redis from flask import Flask from flask.json import jsonify from flask_classy import FlaskView, route app = Flask(__name__) # pi的cache和fib的cache要分开 class Cache(object): def __init__(self, client): self.client = client def set_fib(self, n, result): self.client.hset("fibs", str(n), str(result)) def get_fib(self, n): result = self.client.hget("fibs", str(n)) if not result: return return int(result) def set_pi(self, n, result): self.client.hset("pis", str(n), str(result)) def get_pi(self, n): result = self.client.hget("pis", str(n)) if not result: return return float(result) client = redis.StrictRedis(host="*",port="*") cache = Cache(client) class MathAPI(FlaskView): @route("/fib/<int:n>") def fib(self, n): result, cached = self.get_fib(n) return jsonify({"cached": cached, "result": result}) def get_fib(self, n): if n == 0: return 0, True if n == 1: return 1, True result = cache.get_fib(n) if result: return result, True result = self.get_fib(n-1)[0] + self.get_fib(n-2)[0] cache.set_fib(n, result) return result, False @route("/pi/<int:n>") def pi(self, n):#正整数的平方倒数之和求PI n为精度级数 result = cache.get_pi(n) if result: return jsonify({"cached": True, "result": result}) s = 0.0 for i in range(1, n): s += 1.0/i/i result = math.sqrt(6*s) cache.set_pi(n, result) return jsonify({"cached": False, "result": result}) MathAPI.register(app, route_base='/') if __name__ == '__main__': app.run('127.0.0.1', 5000)