flask请求上下文
理论基础
Threading.local:处理了线程安全,多个线程修改同一个数据,复制多个变量给每一个线程开辟一块内存空间
通俗原理:可以把他看成大字典,不同的线程来有不同的id号,作为字典的key值 例如:{ 线程id:{key:value}}
没有处理:
处理过:
自定义:
from threading import get_ident,Thread import time class Local(object): def __init__(self):
#不能用self.storage = {} 这样会超过最大递归深度,原因就是会自动触发__setattr__ object.__setattr__(self,'storage',{}) def __setattr__(self, k, v): ident = get_ident() if ident in self.storage: self.storage[ident][k] = v else: self.storage[ident] = {k: v} def __getattr__(self, k): ident = get_ident() return self.storage[ident][k] obj = Local() def task(arg): obj.val = arg obj.xxx = arg print(obj.val) for i in range(10): t = Thread(target=task,args=(i,)) t.start()
代理:
代理其实就是一个中介,A和B本来可以直连,中间插入一个C,C就是中介。
刚开始的时候,代理多数是帮助内网client访问外网server用的
后来出现了反向代理,"反向"这个词在这儿的意思其实是指方向相反,即代理将来自外网客户端的请求转发到内网服务器,从外到内
正向代理:
正向代理类似一个跳板机,代理访问外部资源
比如我们国内访问谷歌,直接访问访问不到,我们可以通过一个正向代理服务器,请求发到代理服,代理服务器能够访问谷歌,这样由代理去谷歌取到返回数据,再返回给我们,这样我们就能访问谷歌了
正向代理的用途:
(1)访问原来无法访问的资源,如google
(2) 可以做缓存,加速访问资源
(3)对客户端访问授权,上网进行认证
(4)代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息
通俗的话来说就是黄牛
反向代理
反向代理(Reverse Proxy)实际运行方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器
反向代理的作用:
(1)保证内网的安全,阻止web攻击,大型网站,通常将反向代理作为公网访问地址,Web服务器是内网
(2)负载均衡,通过反向代理服务器来优化网站的负载
通俗的话来说就是房子中介
偏函数
他可以预处理一些函数
flask请求上下文
from flask import Flask app = Flask(__name__) @app.route("/") def test(): return 'helloworld' if __name__ == '__main__': app.run() app.__call__ #入口
图一:
在self.request_context中返回一个RequestContext(self, environ)类的对象 其中self是app
在RequestContext(self, environ)
图二:
图三:
request是我们用的request对象,其中app.request_class是属性
在图二中返回的对象内通过图三可知有request,app,session等,所以图一中的ctx对象包含图三的东西
继续向下:
ctx.push()
_request_ctx_stack是在global.py中,只要程序已运行就直接放在内存中
图四
在进入到_request_ctx_stack.push()
图五
self._local.stack 是在global(图四)localstack
__ident_func__
图五中self._local 是local对象,在对象中找stack,没有会走if
相当于 self._local.stack 和 rv 是一个内存地址
其中obj就是ctx
----------------------------------------------
request 中localProxy就是代理
偏函数
图片理解
总结:
wsgi_app(environ,start_response)
ctx = self.request_context(environ):返回一个requestcontext对象,传入env,app 对象内部有:app,request等
ctx.push():调用了_request_ctx_stack.push(self),_request_ctx_stack:是localstack对象(内部有个local)
调用localstack的push方法,传入ctx(app,request...) 把ctx放到了localstack内的local对象上,处理了线程安全
执行视图函数
print(request) --> 执行request(localProxy)对象的__str__方法
结束