![可扩展性问题(Tornado)。无法解决,推迟发布](https://linux22.com/image/555614/%E5%8F%AF%E6%89%A9%E5%B1%95%E6%80%A7%E9%97%AE%E9%A2%98%EF%BC%88Tornado%EF%BC%89%E3%80%82%E6%97%A0%E6%B3%95%E8%A7%A3%E5%86%B3%EF%BC%8C%E6%8E%A8%E8%BF%9F%E5%8F%91%E5%B8%83.png)
谢谢大家,任何想法/见解都值得赞赏,因为这让我发疯。
问题:在应用程序停止运行之前,只有大约 3 到 4 个用户可以同时使用服务器。
目前,我们发现正常使用情况下 CPU 使用率大幅飙升。由于未知原因,使用真实用户比使用自动化脚本更容易重现这种情况,但脚本可能无法很好地模拟实际使用情况。
我们的架构如下:
- 应用服务器(Tornado)- 单线程,具有异步 IO 循环。我们使用 Tornado 处理与长轮询相关的持久连接,并通过 WSGI 将所有基本 Web 请求发送到 Django。
- Django ORM 用于与数据库交互,尽管大多数 SQL 都是手工编写的
- MySQL 数据库
- Nginx 提供静态媒体服务,并将其他请求代理到 Tornado
- 目前,所有内容都设置为在一个“小型”EC2 实例上运行。将服务器分开到机器之间不会对性能产生明显影响
请参阅 EC2 服务器规格:http://aws.amazon.com/ec2/实例类型/有关服务器配置的更多详细信息。注意:总而言之,这不是最理想和最具可扩展性的设置,但它应该能够处理超过 3 个用户!
运行 top 并查看日志显示以下内容:
- CPU 峰值主要归因于 Tornado,每个活跃用户大约额外占用 25% 的 CPU
- “窃取时间”较低,因此我们的 CPU 能力不再受到 EC2 的严重限制
- 数据库查询全部当 CPU 没有达到峰值时,时间为 0-200 毫秒,但在峰值期间通常会持续 3 秒或更长时间
- 内存使用率低且不会激增
一些尝试过但没有效果的方法:
- 配置 MySQL 缓冲区大小、索引等。我 99% 确信这不是普通的 SQL/DB 优化问题
- 通过各种方式提高查询时间并减少查询次数
- 将服务器放在单独的 EC2 实例上
- 多个应用服务器之间的代理(这显然会更具可扩展性,但它不能解决每个实例 3 个用户的问题)
- 升级 EC2 实例。从“Micro”升级确实有帮助(由于 CPU 节流问题),但只能稍微增加我们的容量
- 在非 EC2 服务器 (Slicehost) 上部署 - 同样的问题
- 所有服务器均通过简单的测试用例单独进行负载测试,并且所有服务器都能够处理数千个同时连接
答案1
“Tornado,每个活跃用户大约多占用 25% 的 CPU”——对于单线程应用程序,如果每个用户占用 25% 的核心,那么在应用程序耗尽其唯一能够使用的核心之前,最多只能容纳 4 个用户。弄清楚为什么 Tornado 占用如此多的 CPU(是您的代码不好,还是 Tornado 不好?),您的解决方案就会排在最后。