python——Web服務開發(二)分散式快取
阿新 • • 發佈:2018-12-27
上一篇部落格寫了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 伺服器通過快取直接獲取答案
重啟伺服器程序或其他服務埠不影響快取提取
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)