Gunicorn + gevent + flask + sqlalchemy + scoped_session 高并发解决方案

Gunicorn + gevent + flask + sqlalchemy + scoped_session 高并发解决方案

Gunicorn

gunicorn 是wsgi http server,也就是web sever

它的作用: 多进程(woker) + 协程(gevent) + 管理web应用(flask)

gevent

gevent是第三方库,通过greenlet实现协程

Gunicorn + Gevent

Gunicorn支持多个woker模式,其中包括异步的Gevent

使用gevent,在guncorn的配置文件中添加参数

worker_class = 'gevent'

再使用wokers参数可以设置woker数量,即实现了多进程web 应用

workers = 2

gunicorn + gevent与monkey.patch_all()

在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 + Sqlalchemy + Scoped_session

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

你可能感兴趣的:(Python)