讨论django并发能力及提供并发解决方案
django 的并发能力真的是令人担忧,这里就使用 nginx + uwsgi 提供高并发
nginx 的并发能力超高,单台并发能力过万(这个也不是绝对),在纯静态的 web 服务中更是突出其优越的地方,由于其底层使用 epoll 异步IO模型进行处理,使其深受欢迎
做过运维的应该都知道,php 需要使用 nginx + fastcgi 提供高并发,java 需要使用 nginx + tomcat 提供 web 服务
如何再次增加并发量
采用nginx做负载
去掉自增主键
原因很简单,因为自增主键的存在写库存在抢锁, 可以利用全局id生成器提前生成id直接写入数据库
换成异步任务去写库
如果数据只是存在mysql中做备份,建议使用异步的方式写入库,先把数据写到缓存下发给用户,之后在利用后台异步任务一点点的写入,例如聊天系统可以这样干
换成更高效的框架或者语言
可以试试tornado, 如果tornado依然无法满足,可以尝试使用golango,毕竟golang是以高并发著称, 而且是编译语言,而且基于它的web框架也很容易上手,性能很可观,例如Iris
======================================
django
毫无疑问,用原生django的server做处理的表现是最烂的,在10000次请求的情况下brokenpipe的几率极高,只有1400次请求被处理,成功率只有14%,我也懒得继续测下去了。
django + nginx
这次搭上了nginx做反向代理,也使的脆弱的django服务器的情况有所缓解,但成功率仍然不高(10000次请求中有3684个请求被处理)。
uwsgi + nginx
uwsgi是性能极高的一个由C编写的服务器,它使用uwsgi协议,这次让它配合nginx处理django的request,参数为4进程+2线程,性能立即直线上升,处理请求的成功率也基本在90%左右,不过我在测试时遇到了一个坑,就是uwsgi在处理请求的时候发送了队列溢出的问题,因为当前测试设置的并发数为每秒1000次并发,而uwsgi的处理队列容量默认为100,导致处理请求的时间加长,而这个问题则可以通过修改somaxcon的大小解决,总的来说,使用uwsgi+nginx是一个理想的选择。
gunicorn + nginx
gunicorn跟uwsgi类似,也是一个高性能的http服务器,它由ruby的unicorn项目移植,是由python编写的,它的配置简单,而且可以灵活地搭配其他网络库,部署十分方便,在测试数据中可以看到,用这种配置运行django能在短时间内就能处理大量的并发请求,成功率在90%左右。
gunicorn + nginx + gevent
前面说的几种环境,看似不错,但我们需要追求完美!由于gunicorn是同步(sync)单线程模型的,有的时候它不免会发生一些阻塞问题,这时候我们为gunicorn加上-k gevent参数来用gevent做处理接口,这就比较靠谱地处理了阻塞问题,从数据中可以看到,gunicorn + nginx + gevent的模式不仅拥有100%的处理成功率,而且时间也在很短之内完成,是5组测试数据当中的性能最好的。
=======================================
多套方案来提高 python web 框架的并发处理能力
Python 常见部署方法有 :
- fcgi :用 spawn-fcgi 或者框架自带的工具对各个 project 分别生成监听进程,然后和 http 服务互动
- wsgi :利用 http 服务的 mod_wsgi 模块来跑各个 project(Web 应用程序或框架简单而通用的 Web 服务器 之间的接口)。
- uWSGI 是一款像 php-cgi 一样监听同一端口,进行统一管理和负载平衡的工具,uWSGI,既不用 wsgi 协议也不用 fcgi 协议,而是自创了一个 uwsgi 的协议,据说该协议大约是 fcgi 协议的 10 倍那么快。
其实 WSGI 是分成 server 和 framework (即 application) 两部分 (当然还有 middleware)。
严格说 WSGI 只是一个协议, 规范 server 和 framework 之间连接的接口。
WSGI server 把服务器功能以 WSGI 接口暴露出来。比如 mod_wsgi 是一种 server, 把 apache 的功能以 WSGI 接口的形式提供出来。
- WSGI framework 就是我们经常提到的 Django 这种框架。不过需要注意的是, 很少有单纯的 WSGI framework , 基于 WSGI 的框架往往都自带 WSGI server。比如 Django、CherryPy 都自带 WSGI server 主要是测试用途, 发布时则使用生产环境的 WSGI server。而有些 WSGI 下的框架比如 pylons、bfg 等, 自己不实现 WSGI server。使用 paste 作为 WSGI server。
- Paste 是流行的 WSGI server, 带有很多中间件。还有 flup 也是一个提供中间件的库。
- 搞清除 WSGI server 和 application, 中间件自然就清楚了。除了 session、cache 之类的应用, 前段时间看到一个 bfg 下的中间件专门用于给网站换肤的 (skin) 。中间件可以想到的用法还很多。
- 这里再补充一下, 像 django 这样的框架如何以 fastcgi 的方式跑在 apache 上的。这要用到 flup.fcgi 或者 fastcgi.py (eurasia 中也设计了一个 fastcgi.py 的实现) 这些工具, 它们就是把 fastcgi 协议转换成 WSGI 接口 (把 fastcgi 变成一个 WSGI server) 供框架接入。整个架构是这样的: django -> fcgi2wsgiserver -> mod_fcgi -> apache 。
- 虽然我不是 WSGI 的粉丝, 但是不可否认 WSGI 对 python web 的意义重大。有意自己设计 web 框架, 又不想做 socket 层和 http 报文解析的同学, 可以从 WSGI 开始设计自己的框架。在 python 圈子里有个共识, 自己随手搞个 web 框架跟喝口水一样自然, 非常方便。或许每个 python 玩家都会经历一个倒腾框架的
uWSGI 的主要特点如下:
- 超快的性能。
- 低内存占用(实测为 apache2 的 mod_wsgi 的一半左右)。
- 多app管理。
- 详尽的日志功能(可以用来分析 app 性能和瓶颈)。
- 高度可定制(内存大小限制,服务一定次数后重启等)。
你应该是使用了Django自己的开发服务器跑的例子,在Django关于manage.py的文档中写道:
--nothreading
The development server is multithreaded by default. Use the --nothreading option to disable the use of threading in the development server.
也就是说,默认情况下你使用./manage.py runserver
会开启多个线程对HTTP请求进行伺服,所以第二个请求进来时虽然第一个请求仍在sleep,但已经新开了一个线程进行响应处理,看起来像是“非阻塞”的工作模式,其实质是多线程而非单线程,想禁用这一行为也已经给出了答案,加上--nothreading
参数:./manage.py runserver --nothreading
即可。
讨论django并发能力及提供并发解决方案的更多相关文章
- php中并发读写文件冲突的解决方案(文件锁应用示例)
PHP(外文名: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,入门门槛较低,易于学习,使用广泛,主要适 ...
- IO复用(Reactor模式和Preactor模式)——用epoll来提高服务器并发能力
上篇线程/进程并发服务器中提到,提高服务器性能在IO层需要关注两个地方,一个是文件描述符处理,一个是线程调度. IO复用是什么?IO即Input/Output,在网络编程中,文件描述符就是一种IO操作 ...
- PHP-高并发和大流量的解决方案
一 高并发的概念在互联网时代,并发,高并发通常是指并发访问.也就是在某个时间点,有多少个访问同时到来. 二 高并发架构相关概念1.QPS (每秒查询率) : 每秒钟请求或者查询的数量,在互联网领域 ...
- 异步IO的并发能力:backlog的配置很重要
今天中午正准备完工的时候,发现一个让人抓狂的问题. 一个精简版的AIO应用理论上应该比一个完整版的AIO应用并发能力高一些(因为完整版的事务处理复杂一些),在同一台机器上测试. 但测试结果显示,精简版 ...
- 11.python3标准库--使用进程、线程和协程提供并发性
''' python提供了一些复杂的工具用于管理使用进程和线程的并发操作. 通过应用这些计数,使用这些模块并发地运行作业的各个部分,即便是一些相当简单的程序也可以更快的运行 subprocess提供了 ...
- java并发编程与高并发解决方案
下面是我对java并发编程与高并发解决方案的学习总结: 1.并发编程的基础 2.线程安全—可见性和有序性 3.线程安全—原子性 4.安全发布对象—单例模式 5.不可变对象 6.线程封闭 7.线程不安全 ...
- Tomcat的并发能力
关注 一.一些限制 Windows 每个进程中的线程数不允许超过 2000 Linux 每个进程中的线程数不允许超过 1000 在 Java 中每开启一个线程需要耗用 1MB 的 JVM 内存空间 ...
- 并发编程概述--C#并发编程经典实例
优秀软件的一个关键特征就是具有并发性.过去的几十年,我们可以进行并发编程,但是难度很大.以前,并发性软件的编写.调试和维护都很难,这导致很多开发人员为图省事放弃了并发编程.新版.NET 中的程序库和语 ...
- Java并发(一)并发编程的挑战
目录 一.上下文切换 1. 多线程一定快吗 2. 测试上下文切换次数和时长 3. 如何减少上下文切换 4. 减少上下文切换实战 二.死锁 三.资源限制的挑战 四.本章小结 并发编程的目的是为了让程序运 ...
- Java并发编程系列-(1) 并发编程基础
1.并发编程基础 1.1 基本概念 CPU核心与线程数关系 Java中通过多线程的手段来实现并发,对于单处理器机器上来讲,宏观上的多线程并行执行是通过CPU的调度来实现的,微观上CPU在某个时刻只会运 ...
随机推荐
- k3s 部署应用
部署k3s 环境 名称 ip地址 cpu 内存 k3s-master 10.65.91.53 4c 8G k3s-node 10.65.91.52 4c 8G master 与 node 节点 # 改 ...
- Python 集合常用方法
数据类型:int/str/bool/list/dict/tuple/float/set (set类型天生去重) 一.集合的定义 s = set() #定义空集合 s = {'a','b','c' ...
- Java方法之方法的定义和调用
方法的定义 Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法: 方法包含一个方法头和一个方法体.下面是一个方法的所有部分: 1.修饰符:修饰符 ...
- js时间转化为几天前,几小时前,几分钟前
在前面一篇文章中,我们学习到了如何获取时间和怎么算出两者之间的时间差 今天看看怎么将时间戳转换为几个月前,几周前,几天前,几分钟前的形式.与上面类似通过JavaScript计算当前时间与定义的时间的对 ...
- vue解决点击事件冒泡 .stop
vue解决点击事件冒泡 .stop <div @click="toCourse()" > <van-button type="primary" ...
- python菜鸟学习: 10. 函数的基本用法
# -*- coding: utf-8 -*-# 回参函数def test01(): return 0# 以元组返回参数def test02(): return 1, [1, 2, 3, 4, 5], ...
- Dapper存储过程分页
create database Month6use Month6 --用户表create table UserInfo( UId int primary key identity, UName var ...
- MBR和gpt说明
1.MBR MBR的全称是Master Boot Record(主引导记录),MBR早在1983年IBM PC DOS 2.0中就已经提出.之所以叫"主引导记录",是因为它是存在于 ...
- (1)从txt读取GPS数据 真实GPS和slam定位GPS匹配 坐标系ecef和enu转化 计算均方根误差和单帧误差
#!/usr/bin/python # -*- coding: UTF-8 -*- import numpy as np import os #==========================1坐 ...
- Java基础Day6-面向对象
一.面向对象编程(Object-Oriented Programming, OOP) 面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据. 从认识论的角度:先有对象后有类.对象是具体 ...