flask ==》 信号
Flask框架中的信号基于blinker,其主要就是让开发者可是在flask请求过程中定制一些用户行为。
pip3 install blinker
pip3 install flask_session
pip3 install redis
目的:open_session, save_session 放到redis里面使用。
要重写:open_session,save_session 里面的方法,该怎么办?
app.session_interface = Foo() # 重写 open_session, save_session
存储方式:redis
#!/usr/bin/env python # -*- coding:utf-8 - import redis from flask import Flask, session from flask_session import Session app = Flask(__name__) app.debug = True app.secret_key = ‘xxxx‘ app.config[‘SESSION_TYPE‘] = ‘redis‘ # session类型为redis app.config[‘SESSION_PERMANENT‘] = False # 如果设置为True,则关闭浏览器session就失效。 app.config[‘SESSION_USE_SIGNER‘] = False # 是否对发送到浏览器上session的cookie值进行加密 app.config[‘SESSION_KEY_PREFIX‘] = ‘session:‘ # 保存到session中的值的前缀 app.config[‘SESSION_REDIS‘] = redis.Redis(host=‘127.0.0.1‘, port=‘6379‘, password=‘123123‘) # 用于连接redis的配置 Session(app) #实例化 @app.route(‘/index‘) def index(): session[‘k1‘] = ‘v1‘ #按这样整个写下来,这个值就保存到redis了 return ‘xx‘ if __name__ == ‘__main__‘: app.run()
请求先进来:
里面的open_session方法。
第二次进来: 运行 save_session:
def save_session(self, app, session, response): domain = self.get_cookie_domain(app) #拿到域名 path = self.get_cookie_path(app) #拿到路径 if not session: if session.modified: self.redis.delete(self.key_prefix + session.sid) response.delete_cookie(app.session_cookie_name, domain=domain, path=path) return # Modification case. There are upsides and downsides to # emitting a set-cookie header each request. The behavior # is controlled by the :meth:`should_set_cookie` method # which performs a quick check to figure out if the cookie # should be set or not. This is controlled by the # SESSION_REFRESH_EACH_REQUEST config flag as well as # the permanent flag on the session itself. # if not self.should_set_cookie(app, session): # return httponly = self.get_cookie_httponly(app) #获取日期 secure = self.get_cookie_secure(app) #获取日期 expires = self.get_expiration_time(app, session) #获取日期 val = self.serializer.dumps(dict(session)) #里面的session是个字典,进行序列化 #self.redis是 redis连接 它有字典,列表 #conn.set(‘xxx‘:‘{k1:v1}‘,ex = ‘超时时间‘) #conn.setex(‘xxx‘:‘{k1:v1}‘) value值:是传过来的 key: session+随机字符串 self.redis.setex(name=self.key_prefix + session.sid, value=val, time=total_seconds(app.permanent_session_lifetime)) if self.use_signer: #是否加密 session_id = self._get_signer(app).sign(want_bytes(session.sid)) #self._get_signer 跳入(加密) else: #不加密 session_id = session.sid response.set_cookie(app.session_cookie_name, session_id, expires=expires, httponly=httponly, domain=domain, path=path, secure=secure) #写到用户浏览器的cookie: key=session value=sid
def open_session(self, app, request): sid = request.cookies.get(app.session_cookie_name) #sid: cookie里是否含有session if not sid: #一开始没有 sid = self._generate_sid() #生成一个sid return self.session_class(sid=sid, permanent=self.permanent) #session_class 继承了字典的方法 if self.use_signer: #解密 signer = self._get_signer(app) if signer is None: return None try: sid_as_bytes = signer.unsign(sid) sid = sid_as_bytes.decode() except BadSignature: sid = self._generate_sid() return self.session_class(sid=sid, permanent=self.permanent) if not PY2 and not isinstance(sid, text_type): sid = sid.decode(‘utf-8‘, ‘strict‘) val = self.redis.get(self.key_prefix + sid) if val is not None: try: data = self.serializer.loads(val) return self.session_class(data, sid=sid) except: return self.session_class(sid=sid, permanent=self.permanent) return self.session_class(sid=sid, permanent=self.permanent)
memcached:
redis把数据放到内存里,什么时候引入redis? redis实在引入自动分配的时候用到。
分配订单时一次一次去数据取,为了防止多次数据操作,故而写在了内存里, 但是,重启,多线程又出现问题了。
那么怎么办? 加了redis之后,即没有数据库取的慢,又不会出现重启之后,多线程下重新分配了。
小结: redis就是在另外一台机器的内存放到数据。
这里: mamcached就和 redis 类似。
他们两的区别:
redis: 可含有5大数据类型。
memcached: 只有字符串一个。
#!/usr/bin/env python # -*- coding:utf-8 - import redis from flask import Flask, session from flask_session import Session import memcache app = Flask(__name__) app.debug = True app.secret_key = ‘xxxx‘ app.config[‘SESSION_TYPE‘] = ‘memcached‘ # session类型为redis app.config[‘SESSION_PERMANENT‘] = True # 如果设置为True,则关闭浏览器session就失效。 app.config[‘SESSION_USE_SIGNER‘] = False # 是否对发送到浏览器上session的cookie值进行加密 app.config[‘SESSION_KEY_PREFIX‘] = ‘session:‘ # 保存到session中的值的前缀 app.config[‘SESSION_MEMCACHED‘] = memcache.Client([‘10.211.55.4:12000‘]) Session(app) @app.route(‘/index‘) def index(): session[‘k1‘] = ‘v1‘ return ‘xx‘ if __name__ == ‘__main__‘: app.run()