python——Web服务开发(二)分布式缓存

上一篇博客写了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 查看本文章

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)







猜你喜欢

转载自blog.csdn.net/sm9sun/article/details/80627249