gunicorn 是wsgi http server,也就是web sever
它的作用: 多进程(woker) + 协程(gevent) + 管理web应用(flask)
gevent是第三方库,通过greenlet实现协程
Gunicorn支持多个woker模式,其中包括异步的Gevent
使用gevent,在guncorn的配置文件中添加参数
worker_class = 'gevent'
再使用wokers参数可以设置woker数量,即实现了多进程web 应用
workers = 2
在gunicorn初始化工作进程中,调用self.patch()方法,执行了mokey.patch_all()给第三方库打上了补丁,从而保证了非阻塞
Gevent在mokey.patch_all()的时候,已经把thread-local换成了greenlet-local,不同协程间是隔离的
https://github.com/benoitc/gunicorn/blob/master/gunicorn/workers/ggevent.py
class GeventWorker(AsyncWorker):
...
def patch(self):
monkey.patch_all()
# monkey patch sendfile to make it none blocking
patch_sendfile()
# patch sockets
sockets = []
for s in self.sockets:
sockets.append(socket.socket(s.FAMILY, socket.SOCK_STREAM, fileno=s.sock.fileno()))
self.sockets = sockets
...
def init_process(self):
self.patch()
super().init_process
flask 是 web 框架
sqlalchemy 是 ORM 框架
scoped_session 类似单例模式
三者最终实现:web 应用操作数据库的简单和安全
在使用flask初始化时通过scoped_session函数对原始的session进行处理,返回一个ScopedSession工厂,在每个请求来的时候就可以通过这个工厂获得一个 scoped_session 对象。
这实际上实现了一种 registry 模式,它有个中心化的 registry 来保存已经创建的 session,并在你调用ScopedSession工厂的时候,在 registry 里面找找是不是之前已经为你创建过 session 了,如果有,就直接把这个 session 返回给你,如果没有,就创建一个新的 session,并注册到 registry 中以便你下次来要的时候给你。
scoped_session 使用了 tls 作为 session 的存储方式,一个线程只能拿到自己创建出来的 session,保证了不同线程不会乱入别人的 session。保证了数据安全
tls (Thread-Local Storage,线程本地化存储)
简单的讲:使用TLS线程本地化存储隔离数据的session工厂,有且只有一个session。
如果使用gevent会 从thread-local会变成greenlet-local
https://farer.org/2017/10/28/sqlalchemy_scoped_session/
https://blog.csdn.net/luoxingjue6423/article/details/81979256