hello,各位。
我使用django和rest framework 写了一个简单的api接口,数据库用的是sqlite (后面用pgsql性能还下降了一点)
就一个model 可以简单的理解为book和auth 这样两个例子的model
我将服务搭建到树莓派(3b)上 4核 1g内存 (树莓派性能是差了点,开始之前我还是有心理准备)
我用ab测试,测试指令(每秒200并发,一共请求1000次)
ab -t 200 -n 1000 http://192.168.3.250:8000/api/
使用传统的runserver方式启动一个服务 每秒的并发数是13,我惊呆了。所以我换了gunicorn。
使用gunicorn之后,gunicorn+gevent 每秒并发11。
我在gunicorn上尝试加上 -w 4 参数多建立几个进程来提高处理速度,然而依旧差强人意。并发数量大概在12左右。
我使用htop观察进程的cpu占用和内存占用,发现进程占用基本上在50%左右4个核的平均值。内存的使用也不高,一百多m.
使用iotop观察io读写,在请求的过程中并没有发现有大量的io产生,虽然树莓派的sd卡读写比较烂,但是io就偶尔几十k顶多300k/s左右。
so,我很疑惑,在有大量并发请求的情况下,200的并发请求对于树莓派来说我认为是量比较大的请求了,这时候cpu应该会忙于请求工作开始负载,但是并没有满载,只有50%左右。
是什么原因导致的呢?python语言本身处理速度过慢导致?还是我并没有正确的配置我的django项目?
附上我使用gunicorn的代码
gunicorn -k gevent yoyoyo.wsgi:application -b 127.0.0.1:8000 --reload -w 4
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
面对您描述的性能问题,有几个可能的原因和优化方向可以考虑:
Python GIL(全局解释器锁):Python的全局解释器锁限制了多线程在CPU密集型任务中的并行能力。尽管您使用了Gunicorn配合gevent来实现异步处理,但Python的GIL仍然可能影响到整体性能,尤其是在CPU密集型操作上。对于I/O密集型任务,gevent能够通过协程有效提升效率,但在CPU密集型场景下,GIL会成为瓶颈。
数据库访问:即使您的观察显示没有大量IO操作,SQLite或PostgreSQL的查询效率、连接池大小、以及数据缓存策略都可能影响性能。尤其SQLite并不适合高并发场景,它更适合单用户或轻量级应用。尝试优化数据库查询,使用连接池,或者考虑更高效的数据存储解决方案如Redis进行缓存,减少直接对数据库的读写需求。
Django设置与中间件:检查Django项目的设置,确保没有不必要的中间件启用,因为每个请求都会经过这些中间件,可能会增加额外的处理时间。同时,确保静态文件服务等非核心功能不占用主要服务资源。
代码优化:审查API视图函数和模型方法,确保没有低效的循环、查询或其他可优化的逻辑。使用Python的cProfile工具来分析代码性能,找出瓶颈所在。
Gunicorn配置:您提到使用了-w 4
参数来启动4个工作进程,这在树莓派这样的硬件上可能是合适的,但也要考虑到操作系统本身的开销。有时候,过多的工作进程反而会因内存交换而降低性能。可以尝试调整工作进程数,找到最优配置。另外,考虑使用更高效的worker类型,比如gthread
或uvicorn
workers(如果适用),它们在某些场景下能提供更好的性能。
网络与系统限制:树莓派的网络接口和系统配置也可能成为瓶颈。检查网络设置,确保没有带宽限制或网络延迟问题。此外,Linux系统的内核参数(如打开文件描述符的数量、最大进程数等)也会影响性能,适当调整这些参数可能有帮助。
硬件限制:最后,树莓派3B的硬件规格确实有限,尤其是1GB的RAM和相对较低的CPU性能。在达到一定并发水平后,硬件将成为不可忽视的限制因素。虽然您已经有所预期,但这是无法通过软件完全克服的限制。
综上所述,您可以从多个角度入手进行优化,但最终可能需要权衡是否升级硬件平台以满足更高的性能需求。