首页 > 解决方案 > 为什么异步比同步慢?

问题描述

为什么当我开始测试服务器上的负载时,同步编写方式的运行速度比异步方式快数百倍。我只是在尝试异步,我做错了什么?

ab -t 10 -n 10000 -c 100 http://127.0.0.1:8888/api/db/sync/ 每秒请求数:35

ab -t 10 -n 10000 -c 100 http://127.0.0.1:8888/api/db/ 每秒请求数:0.37

import asyncio
import json
import time
from asyncio import sleep
from typing import Optional, Union

import tornado.ioloop
import tornado.web

from jinja2 import Environment, select_autoescape, FileSystemLoader
from sqlalchemy import text, create_engine
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker, Session
from tornado import gen
from tornado.httpserver import HTTPServer

env = Environment(
    loader=FileSystemLoader('templates'),
    autoescape=select_autoescape()
)

async_engine = create_async_engine(
    "postgresql+asyncpg://***:***@localhost:5431/***",
    echo=True,
)

async_session = sessionmaker(
    async_engine, expire_on_commit=False, class_=AsyncSession
)

engine = create_engine(
    "postgresql://***:***@localhost:5431/***",
    echo=True,
)

sync_session = sessionmaker(
    engine, expire_on_commit=False
)


class ApiDbHandler(tornado.web.RequestHandler):
    
    def prepare(self):
        header = "Content-Type"
        body = "application/json"
        self.set_header(header, body)
        
    async def get(self):
        async with async_session() as session:
            session: AsyncSession
            
            for result in await asyncio.gather(
                
                    session.execute(text('SELECT * from *** where client_id = :bis_id').bindparams(bis_id='bis1')),
                    session.execute(text('SELECT * from *** where bis_id = :bis_id').bindparams(bis_id='bis1')),
                    session.execute(text('SELECT * from *** where abs_id = :abs_id').bindparams(abs_id='abs1')),
                    session.execute(
                        text('SELECT * from *** where abs_id = :abs_id').bindparams(abs_id='abs1')),
                
            ):
                self.write(
                    json.dumps(result.fetchall(), default=str)
                )

class ApiDbSyncHandler(tornado.web.RequestHandler):
    
    def prepare(self):
        header = "Content-Type"
        body = "application/json"
        self.set_header(header, body)
        
    def get(self):
        with sync_session() as session:
            session: Session
            
            assets = session.execute(text('SELECT * from *** where client_id = :bis_id').bindparams(bis_id='bis1'))
            self.write(
                json.dumps(assets.fetchall(), default=str)
            )
            ili = session.execute(text('SELECT * from *** where bis_id = :bis_id').bindparams(bis_id='bis1'))
            self.write(
                json.dumps(ili.fetchall(), default=str)
            )
            securities = session.execute(text('SELECT * from *** where abs_id = :abs_id').bindparams(abs_id='abs1'))
            self.write(
                json.dumps(securities.fetchall(), default=str)
            )
            abs_accounts = session.execute(text('SELECT * from *** where abs_id = :abs_id').bindparams(abs_id='abs1'))
            self.write(
                json.dumps(abs_accounts.fetchall(), default=str)
            )

def make_app():
    return tornado.web.Application([
        (r"/api/db/", ApiDbHandler),
        (r"/api/db/sync/", ApiDbSyncHandler),
    ])


if __name__ == "__main__":
    app = make_app()
    server = HTTPServer(app)
    server.listen(8888)
    tornado.ioloop.IOLoop.current().start()

标签: python-asynciotornado

解决方案


推荐阅读