利用gunicorn提高django的并发能力

原文连接

引言

手头上的项目有一些采用django框架编写, 如果说并发量比较小的时候简单的runserver是可以应对的.
那么当并发达到一两千的时候,该怎么提高django的并发能力呢?

Overview

  • 环境说明:
    • python: 3.5
    • django: 1.8.2
    • gunicorn: 19.7.1
  • 系统:
    • 服务器: centos 4核
    • 压测机器: centos 4核
  • 压测环境
    • siege/ysab
    • 4核centos测试机
  • 为什么用django
    • 开发效率高
    • 好上手
  • 关于gunicorn
    • Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX.It's a pre-fork worker model. The Gunicorn server is broadly compatible with various web frameworks, simply implemented, light on server resources, and fairly speedy.(这是官方给出的回答)

压测方式及命令

本次实验业务场景

业务

代码展示

settings部分

# 这里我们用mysql,其他配置都是默认
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'ce',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '192.168.96.95',
        'PORT': '3306',
        # 'CONN_MAX_AGE': 600,
    }
}

models部分

class Test(models.Model):
    url = models.CharField(max_length=228, blank=True, null=True)
    img_url = models.CharField(max_length=228, blank=True, null=True)
    title = models.CharField(max_length=228, blank=True, null=True)
    content = models.CharField(max_length=228, blank=True, null=True)

    class Meta:
        db_table = 'test'
        verbose_name = "test表"

    def __unicode__(self):
        return self.id

views部分

class Test(APIView):

    def post(self, requsts):
        Test.objects.create(
            **{'url': str(1000000 * time.time())})
        return Response({"status": 200})

开始压测

数据说明

目前数据库test表的数据量是, 其中id是自增主键
MySQL [ce]> select id from test order by id desc limit 2;
+--------+
| id     |
+--------+
| 627775 |
| 627774 |
+--------+

runserver 方式压测结果

Lifting the server siege...      done.

Transactions:               24041 hits
Availability:               99.93 %
Elapsed time:               99.60 secs
Data transferred:            0.32 MB
Response time:                1.03 secs
Transaction rate:          241.38 trans/sec  # 并发量只有241
Throughput:                0.00 MB/sec
Concurrency:              248.94
Successful transactions:       24041
Failed transactions:              16
Longest transaction:           32.55
Shortest transaction:            0.05

gunicorn + gevent (4个worker)

Lifting the server siege...      done.

Transactions:               23056 hits
Availability:              100.00 %
Elapsed time:               99.49 secs
Data transferred:            0.31 MB
Response time:                1.09 secs
Transaction rate:          231.74 trans/sec # 并发量只有231
Throughput:                0.00 MB/sec
Concurrency:              252.95
Successful transactions:       23056
Failed transactions:               0
Longest transaction:            8.21
Shortest transaction:            0.01

gunicorn + gthread (4个worker, --threads=50)

启动方式

[官方有相应说明]((http://docs.gunicorn.org/en/latest/settings.html)

gunicorn --env DJANGO_SETTINGS_MODULE=ce.settings ce.wsgi:application -w 4 -b 0.0.0.0:8080 -k gthread --threads 40 --max-requests 4096 --max-requests-jitter 512

压测结果

启动方式:

done.
siege aborted due to excessive socket failure; you
can change the failure threshold in $HOME/.siegerc

Transactions:               28231 hits
Availability:               95.67 %
Elapsed time:               30.71 secs
Data transferred:            0.41 MB
Response time:                0.27 secs
Transaction rate:          919.28 trans/sec  # 提高了不少吧,能不能在提高?
Throughput:                0.01 MB/sec
Concurrency:              251.06
Successful transactions:       28231
Failed transactions:            1278        # 但是失败的有些多
Longest transaction:            8.06
Shortest transaction:            0.01

gunicorn + gthread + CONN_MAX_AGE(4个worker, --threads=50)

关于CONN_MAX_AGE

CONN_MAX_AGE: 复用数据库链接

Lifting the server siege...      done.

Transactions:              110289 hits
Availability:               99.62 %
Elapsed time:               99.65 secs
Data transferred:            1.47 MB
Response time:                0.23 secs
Transaction rate:         1106.76 trans/sec  # 这次又提升了不少啊
Throughput:                0.01 MB/sec
Concurrency:              253.84
Successful transactions:      110289
Failed transactions:             422
Longest transaction:            3.85
Shortest transaction:            0.01

能不能gunicorn+gevent+CONN_MAX_AGE(4个worker)

这里我不建议使用,这样的话你的数据库连接数会飚的很高,服务会挂的很惨, 毕竟数据库是不会允许
无休止的建立连接的。前边的提高手段无非用的多线程,如果一定要用协程(gevent)的方式呢,能不
能解决数据库连接数过高的问题,而且还能有不错的性能呢?可以看一下这篇文章:
gunicorn+gevent+django数据库连接池

如何再次增加并发量

采用nginx做负载

[图片上传失败...(image-55dc84-1555064167047)]

去掉自增主键

原因很简单,因为自增主键的存在写库存在抢锁, 可以利用全局id生成器提前生成id直接写入数据库

换成异步任务去写库

如果数据只是存在mysql中做备份,建议使用异步的方式写入库,先把数据写到缓存下发给用户,之后在
利用后台异步任务一点点的写入,例如聊天系统可以这样干

换成更高效的框架或者语言

可以试试tornado, 如果tornado依然无法满足,可以尝试使用golango,毕竟golang是以高并发著称,
而且是编译语言,而且基于它的web框架也很容易上手,性能很可观,例如Gin
Gin

文章推荐

关于gunicorn的worker调度
gunicorn+gevent+django数据库连接池

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348

推荐阅读更多精彩内容