你说得对,asyncio 只使用一个 CPU。 (一个事件循环只使用一个线程,因此只使用一个 CPU)
我不能说您的整个项目是受网络限制还是受 CPU 限制。
你必须尝试。
您可以使用 nginx 或 haproxy 作为负载均衡器。
您甚至可以尝试完全不使用负载平衡器。我从未尝试过将此功能用于负载平衡,就像故障转移系统的概念证明一样。
使用新内核时,多个进程可以监听同一个端口(使用SO_REUSEPORT 选项时),我猜是内核会进行循环。
这里有一个小链接指向一篇比较典型 nginx 配置与具有 SO_REUSEPORT 功能的 nginx 设置的性能的文章:
https://blog.cloudflare.com/the-sad-state-of-linux-socket-balancing/
似乎SO_REUSEPORT 可能会相当均匀地分配 CPU 费用,但可能会增加响应时间的变化。不确定这与您的设置是否相关,但我想我让您知道了。
于 2020 年 2 月 4 日添加:
我添加 2019-12-09 的解决方案有效,但触发了弃用警告。
当我有更多的时间和时间自己测试它时,我会在此处发布改进的解决方案。暂时你可以在AIOHTTP - Application.make_handler(...) is deprecated - Adding Multiprocessing找到它
于 2019 年 12 月 9 日添加:
这是一个 HTTP 服务器的小例子,它可以在同一个套接字上启动多次侦听。
内核将分发任务。不过,我从未检查过这是否有效。
reuseport.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()
还有一种测试方法:
./reuseport.py & ./reuseport.py &
sleep 2 # sleep a little so servers are up
for n in 1 2 3 4 5 6 7 8 ; do wget -q http://localhost:8000/$n -O - & done
输出可能如下所示:
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