- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在使用 aiohttp 模块开发一个网络应用程序。我正在使用:
aiohttp.web
、asyncio
、uvloop
、aiohttp_session
、aiohttp_security
、 aiomysql
和 aioredis
我已经针对它运行了一些基准测试,虽然它们相当不错,但我忍不住想要更多。我知道 Python 本质上是单线程的。 AIOHTTP 使用异步作为非阻塞,但我假设它没有利用所有 CPU 核心是否正确?
我的想法:通过 concurrent.futures
在多处理模式下运行我的 aiohttp.web 代码的多个实例。每个进程都将在不同的端口上为站点提供服务。然后我会在他们面前放置一个负载平衡器。 MySQL 和 Redis 可用于在必要时共享状态,例如 session 。
问题:给定一个具有多个 CPU 核心的服务器,这会带来预期的性能提升吗?如果是这样,是否有任何特定的模式可以避免出现问题?我想不出这些 aio 模块所做的任何事情需要只有一个线程,尽管我可能是错的。
注意:这不是我提出的主观问题。该模块当前要么绑定(bind)到一个线程/进程,要么没有绑定(bind)——可以从多处理模块+负载均衡器中受益,也可以不受益。
最佳答案
你是对的,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-02-04:
我的解决方案在 2019 年 12 月 9 日添加有效,但会触发弃用警告。
当有更多时间自己测试时,我将在这里发布改进的解决方案。暂时可以通过AIOHTTP - Application.make_handler(...) is deprecated - Adding Multiprocessing找到
添加于 2019-12-09:
这是一个 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
关于Python AIOHTTP.web 服务器多处理负载均衡器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59217853/
我是一名优秀的程序员,十分优秀!