PythonAIOHTTP.web网站服务器多处理负载平衡器?

2024-05-10 08:36:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在开发一个使用aiohttp模块的web应用程序。我用的是:

aiohttp.webasynciouvloopaiohttp_sessionaiohttp_securityaiomysql,和{}

我已经对它运行了一些基准测试,虽然它们相当不错,但我还是忍不住想要更多。我知道Python本质上是单线程的。AIOHTTP使用async作为非阻塞,但是我是否正确地假设它没有使用所有的CPU核心?在

我的想法:运行多个aiohttp.web网站在多处理模式下通过concurrent.futures进行编码。每个过程将在不同的端口上为站点服务。然后我会在他们面前放一个负载平衡器。MySQL和Redis可以在必要的地方共享状态,比如会话。在

问题:给定一个具有多个CPU核心的服务器,这会导致期望的性能提高吗?如果是这样的话,有没有什么具体的模式可以用来避免问题?我想不出这些aio模块所做的任何事情都只需要一个线程,尽管我可能错了。在

注意:这不是我提出的主观问题。模块当前要么绑定到一个线程/进程,要么没有——可以从多处理模块+负载平衡器中获益,要么不能


Tags: 模块webasyncio应用程序核心uvloopaiohttpsession
1条回答
网友
1楼 · 发布于 2024-05-10 08:36:13

你说得对,asyncio只使用一个CPU。(一个事件循环只使用一个线程,因此只使用一个CPU)

你的整个项目是网络还是CPU的问题我不能说。 你得试试。在

您可以使用nginx或haproxy作为负载平衡器。 您甚至可以尝试根本不使用负载平衡器。我从来没有尝试过,但是有了新的内核,多个进程可以监听同一个端口,我猜是内核在执行循环。 如果对此感兴趣,我可以试着找一个例子。在

新增20191209:

在同一个HTTP服务器上可以多次启动一个小的HTTP套接字。 内核将分配任务。我从来没有检查过这是否有效。在

重用报表.py:

import asyncio
import os
import socket
import time
from aiohttp import web


def mk_socket(host="127.0.0.1", port=8000, reuseport=False):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    if reuseport:
        SO_REUSEPORT = 15
        sock.setsockopt(socket.SOL_SOCKET, SO_REUSEPORT, 1)
    sock.bind((host, port))
    return sock

async def handle(request):
    name = request.match_info.get('name', "Anonymous")
    pid = os.getpid()
    text = "{:.2f}: Hello {}! Process {} is treating you\n".format(
        time.time(), name, pid)
    time.sleep(0.5)  # intentionally blocking sleep to simulate CPU load
    return web.Response(text=text)

if __name__ == '__main__':
    host = "127.0.0.1"
    port=8000
    reuseport = True
    app = web.Application()
    sock = mk_socket(host, port, reuseport=reuseport)
    app.add_routes([web.get('/', handle),
                    web.get('/{name}', handle)])
    loop = asyncio.get_event_loop()
    coro = loop.create_server(
        protocol_factory=app.make_handler(),
        sock=sock,
        )
    srv = loop.run_until_complete(coro)
    loop.run_forever()

还有一种测试方法:

^{pr2}$

输出可能如下所示:

1575887410.91: Hello 1! Process 12635 is treating you
1575887410.91: Hello 2! Process 12633 is treating you
1575887411.42: Hello 5! Process 12633 is treating you
1575887410.92: Hello 7! Process 12634 is treating you
1575887411.42: Hello 6! Process 12634 is treating you
1575887411.92: Hello 4! Process 12634 is treating you
1575887412.42: Hello 3! Process 12634 is treating you
1575887412.92: Hello 8! Process 12634 is treating you

相关问题 更多 >