并发场景下,python各个web框架的优劣对比与示例分析

Python有许多适合高并发场景的Web框架,下面是其中几个:

  1. Flask

Flask一个轻量级的Web框架,由Werkzeug和Jinja2模板引擎组成。Flask设计简单,易于扩展具有较高的灵活性和可定制性。它适用于开发小型Web应用程序和API,以及中小型的高并发Web应用程序

  1. Django

Django一个完整的Web框架,具有强大的功能和灵活的架构。它的设计重点是开发大型、高度扩展的Web应用程序。Django支持ORM、自动化管理界面表单处理缓存安全性等功能,这些功能使得开发Web应用程序更加高效和简单

  1. Tornado

Tornado是一个高性能的Web框架,具有轻量级设计异步阻塞的I/O模型。它被广泛应用于实时Web应用程序、高并发的API、聊天应用程序领域。Tornado适合处理并发、大规模请求响应的Web应用程序

  1. FastAPI

FastAPI是一个基于Starlette框架和Pydantic库的高性能Web框架,它采用异步非阻塞的I/O模型和OpenAPI(以前称为Swagger规范。FastAPI支持自动化的API文档数据验证异步请求响应等功能。它适用于高性能的Web API和微服务

总之,Python有许多适合高并发场景的Web框架,开发者可以根据自己需求和实际情况选择适合自己的框架。

flask框架处理高并发场景 ==>不推荐

Flask是一个轻量级的Web框架,由于其设计简单和易于扩展,因此在处理高并发场景方面可能需要进行一些额外工作。下面是一些关于如何处理高并发和如何部署启动Flask应用程序的一些建议

  1. 使用Gunicorn或uWSGI等WSGI服务器

在生产环境中,通常使用WSGI服务器作为Web服务器部署Flask应用程序。WSGI服务器允许Flask应用程序与Web服务器之间进行快速、高效的通信。Gunicorn和uWSGI是两个常用的WSGI服务器,它们都可以与Flask一起使用提高应用程序性能和并发能力。

  1. 使用Nginx进行反向代理

在高流量场景,使用Nginx进行反向代理可以有效提高Flask应用程序的性能和并发能力。通过请求从Nginx转发到Flask应用程序,可以降低应用程序的负载,并使请求处理更快。

  1. 使用缓存

Flask提供了内置缓存支持,可以使用缓存来减少对数据库和其他资源访问通过使用缓存,可以大大减少对数据库访问次数,从而提高应用程序的响应速度和并发能力。

  1. 使用异步处理

Flask框架本身不支持异步处理,但可以使用像Flask-SocketIO这样的扩展实现异步处理。异步处理可以提高应用程序的并发能力,特别是在处理大量实时请求时,效果更佳。

关于部署启动Flask应用程序,在生产环境中,通常使用WSGI服务器将Flask应用程序部署服务器上。可以使用类似于Gunicorn或uWSGI这样的WSGI服务器,通过命令行将Flask应用程序部署服务器上。在部署Flask应用程序时,还应该考虑安全性监控日志记录等方面,以确保应用程序的稳定和安全

将Flask应用程序部署到Gunicorn服务器上:
  1. 安装Gunicorn

    pip install gunicorn
    
  2. 创建启动脚本

    在Flask应用程序的根目录创建一个启动脚本例如app.sh

    gunicorn -w 4 -b 0.0.0.0:8000 app:app
    

    -w参数指定Gunicorn的工作进程数,可以根据需要进行修改。 -b参数指定绑定的IP地址端口号app:app参数表示Flask应用程序的入口文件和应用程序对象

  3. 启动应用程序

    运行以下命令启动应用程序:

    sh app.sh
    

​ 4. 示例app代码:

from flask import Flask, request

app = Flask(__name__)


@app.route('/showip', methods=['GET'])
def hello_world():
    if request.method == 'GET':
        return request.remote_addr

# if __name__ == '__main__':
#     app.run(host='0.0.0.0',port=5000,debug=True)
flask使用缓存

Flask提供了多种缓存机制,包括内存缓存文件缓存、Redis缓存等。以下是一个使用内存缓存的示例

from flask import Flask
from flask_caching import Cache

app = Flask(__name__)
cache = Cache(app, config={'CACHE_TYPE': 'simple'})

@app.route('/hello/<name>')
@cache.cached(timeout=60) # 缓存60秒
def hello(name):
    return f'Hello {name}!'

if __name__ == '__main__':
    app.run()

在上面的示例中,使用flask_caching扩展来实现缓存功能。首先,在Flask应用程序中实例化一个Cache对象,并将其与应用程序关联config参数用于设置缓存的类型这里使用的是内存缓存(simple)。然后,在路由函数添加@cache.cached装饰器,表示对该函数结果进行缓存,并设置缓存时间为60秒。如果在缓存时间内再次访问同样的路由,将直接返回缓存中的结果,而不是再次执行路由函数

django处理高并发场景策略 ==>不推荐

Django 本身并不是一个异步的 Web 框架,但是可以通过使用异步任务队列、异步视图函数、缓存机制方式提高并发处理能力。

以下是一些在 Django 中处理高并发的方式

  1. 使用异步任务队列:Django 支持使用异步任务队列执行一些耗时的后台任务例如发送邮件、处理大量数据等。常用的异步任务队列包括 Celery 和 RQ。
  2. 使用异步视图函数:Django 支持使用异步视图函数来处理异步请求例如 AJAX 请求、WebSocket 连接等。在视图数中使用异步 IO 操作,可以提高并发处理能力。
  3. 使用缓存机制:Django 支持使用多种缓存后端,例如 Memcached 和 Redis 等。使用缓存机制可以避免重复计算、减轻数据库负载、加速响应等。
  4. 使用分布式架构:Django 可以与其他分布式系统配合使用,例如使用消息队列来进行任务分发、使用负载均衡器均衡流量等。
  5. 使用数据库读写分离:Django 支持数据库层面上进行读写分离,例如使用 MySQL 的主从复制、PostgreSQL 的流复制等。
  6. 使用缓存页面:Django 支持使用缓存页面来避免重复渲染相同的页面,从而提高响应速度。可以使用 Django 自带的缓存框架或第三方缓存插件来实现。

Tornado如何处理高并发场景 ==>推荐

Tornado 是一个 Python 异步 Web 框架,天生适合处理高并发场景。以下是一些 Tornado 处理高并发的方式

  1. 使用协程coroutine):Tornado 支持使用协程来处理异步 IO 操作,可以避免使用传统回调方式简化代码逻辑,提高代码可读性和维护性。
  2. 使用异步 IO 操作:Tornado 支持使用异步 IO 操作来处理网络 IO,例如使用异步 HTTP 客户端、异步数据库驱动程序等。
  3. 使用异步任务队列:Tornado 支持使用异步任务队列,例如 Celery,来处理一些耗时的后台任务,从而释放主线程的资源,提高并发处理能力。
  4. 使用缓存机制:Tornado 支持使用多种缓存后端,例如 Memcached 和 Redis 等。使用缓存机制可以避免重复计算、减轻数据库负载、加速响应等。
  5. 使用反向代理:Tornado 可以与反向代理服务器(如 Nginx)一起使用,通过负载均衡、缓存、压缩等方式来优化性能。
  6. 使用异步 WebSocket:Tornado 支持使用异步 WebSocket 通信,可以处理大量实时通信请求,例如聊天室在线游戏等。

需要注意的是,以上方式都需要根据具体场景进行评估和选择,不能一概而论。在处理高并发场景时,需要考虑多方面的因素,例如数据库性能、缓存策略网络瓶颈等,综合权衡后选择合适的方案

使用异步 IO 操作
# coding=utf-8

import tornado.ioloop
import tornado.web
import tornado.httpclient


class MainHandler(tornado.web.RequestHandler):
    async def get(self):
        url = "https://baidu.com/"
        # 异步请求url并把结果提交response传输接口返回
        response = await tornado.httpclient.AsyncHTTPClient().fetch(url)
        self.write(response.body)


def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])


if __name__ == "__main__":
    app = make_app()
    app.listen(18888)
    # 添加debug=True参数,可以在控制台看到错误信息
    tornado.ioloop.IOLoop.current().start()

在这个示例中,我们定义了一个 MainHandler 类来处理 HTTP 请求,其中使用了异步关键字 async定义异步方法。在 get 方法中,我们使用了 Tornado 异步 HTTP 客户端 AsyncHTTPClient发送 HTTP 请求,并使用 await 关键字等待响应返回

通过使用异步 IO 操作我们可以避免使用传统的回调方式,简化代码逻辑,提高代码可读性和维护性。同时,异步 IO 操作也能够提高服务器的并发处理能力,提升系统的性能表现。

使用协程
# coding=utf-8


import tornado.ioloop
import tornado.web
import tornado.gen
import tornado.httpclient

class MainHandler(tornado.web.RequestHandler):
    @tornado.gen.coroutine
    def get(self):
        url = "https://www.google.com.hk/"
        response = yield tornado.httpclient.AsyncHTTPClient().fetch(url)
        self.write(response.body)

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    # 设置公网可以访问
    app.listen(18888, address="0.0.0.0")
    tornado.ioloop.IOLoop.current().start()


在这个示例中,我们使用 @tornado.gen.coroutine 装饰器来定义协程方法。在 get 方法中,我们使用 tornado.httpclient.AsyncHTTPClient().fetch 方法发送 HTTP 请求,并使用 yield 关键字等待响应返回。

通过使用协程,我们可以避免使用传统的回调方式,简化代码逻辑,提高代码可读性和维护性。同时,协程也能够提高服务器的并发处理能力,提升系统的性能表现。

需要注意的是,如果协程中存在耗时操作(如 IO 操作),则需要使用 Tornado 的异步 IO 操作或异步任务队列来处理,避免阻塞主线程

FastAPI高并发场景应用 ==>最新推荐

from fastapi import FastAPI
import uvicorn

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

在这个示例中,我们使用 FastAPI 构建了一个简单的 Web 应用程序,并使用 Uvicorn 作为 Web 服务器运行。使用 async 关键字定义异步方法,使得应用程序能够异步地处理请求。

FastAPI 内置的异步支持和 Uvicorn 的高性能异步服务器可以让我们轻松地构建高性能、高并发的 Web 应用程序。

需要注意的是,在高并发场景下,除了使用异步 IO 操作和高性能服务器之外,还需要注意应用程序的并发连接数、数据库连接池大小、缓存的使用问题,以避免出现瓶颈和性能问题

使用数据库连接池
# coding=utf-8

from fastapi import FastAPI
from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker
import uvicorn


app = FastAPI()

user = ""
host = ""
port = 3306
database = ""
# 创建数据库引擎

DATABASE_URL = f"mysql+aiomysql://{user}:{password}@{host}:{port}/{database}"
engine = create_async_engine(DATABASE_URL, echo=True, pool_size=10, max_overflow=20)

# 创建会话工厂
async_session_factory = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)


# 定义接口
@app.get("/")
async def read_root():
    async with async_session_factory() as session:
        # 测试连通性
        # result = await session.execute(text("SELECT 1"))
        # return {"result": result.scalar()}

        # 获取一条数据
        result = await session.execute(text("SELECT * FROM demo.runoob_tbl"))
        data = result.fetchone()
        print(data)
        # 将数据转换字典
        # 提取出数据
        # (1, '学习 PHP', '菜鸟教程', datetime.date(2023, 2, 23))
        result = {"id": data[0], "title": data[1], "author": data[2], "submission_date": data[3]}
        return {"result": result}



if __name__ == "__main__":
    # fastApi_mysql_conn_pool
    uvicorn.run(app="fastApi_mysql_conn_pool:app", host="127.0.0.1", port=8000, reload=True)

在这个示例中,我们使用 SQLAlchemy 实现了 MySQL 数据库连接池的功能。首先,我们创建了一个异步引擎 engine,并指定了连接池大小最大溢出数量。然后,我们创建了一个会话工厂 async_session_factory,用于创建异步会话

在 API 接口中,我们使用 async with async_session_factory() as session 创建一个异步会话,并通过 session.execute 执行 SQL 查询语句

使用 MySQL 数据库连接池可以有效地管理数据库连接,提高应用程序的性能和并发处理能力。同时,使用 SQLAlchemy 和异步会话可以使代码更加简洁和易于维护。

使用多进程提高并发处理能力

在运行 FastAPI 应用程序时,可以使用 uvicorn 或其他 WSGI 服务器来启动应用程序,并设置工作进程数或线程数来处理并发请求。在启动 uvicorn 时,可以使用 -w 参数来指定工作进程数,例如:

uvicorn main:app -w 4

这个命令启动 4 个工作进程来处理并发请求。根据 CPU 核心数和服务器资源情况,可以适当调整工作进程数,以提高处理并发请求的能力。

缓存的使用场景

缓存是一种用于提高数据访问速度降低系统负载技术。以下是一些常见的缓存使用场景:

  1. 频繁查询的结果:当某个查询结果被频繁请求时,可以将查询结果缓存起来,下次请求时直接从缓存中获取,避免重复查询计算,从而提高系统响应速度和性能。
  2. 计算结果:当某个计算结果的计算成本较高时,可以将计算结果缓存起来,下次请求时直接从缓存中获取,避免重复计算和浪费资源
  3. 静态资源:当应用程序中的某些静态资源(如图片、脚本样式表等)被频繁请求时,可以将这些资源缓存到浏览器或CDN中,从而加速资源的加载和降低服务器负载。
  4. 第三方API调用:当应用程序需要调用第三方API时,可以将API的响应结果缓存起来,下次请求时直接从缓存中获取,避免重复调用等待,从而提高系统响应速度和稳定性。
  5. 用户会话数据:当应用程序需要维护用户会话数据时,可以将用户会话数据缓存到内存或Redis中,避免重复查询数据库文件系统,从而提高系统响应速度和性能。

需要注意的是,缓存并不是万能解决方案,不适合所有场景。缓存的使用需要根据实际情况进行评估和调整,权衡缓存带来的性能提升和资源消耗,以及缓存的一致性失效策略因素

原文地址:https://blog.csdn.net/Jesse_Kyrie/article/details/129182961

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_29124.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注