随着工作的深入,我越来越发现Python Web开发中有很多坑,也一直在羡慕AspNetCore和Go等的可执行文件部署和高性能,以及Spring生态的丰富,不过因为工作用了Django,生活还是要继续的嘛,这Django好歹也是有很大份额的Web框架,也没那么不堪,至少开发速度上就吊打一众框架了~

在之前的文章里我介绍过使用Docker部署Django应用的方法,不过那种部署方式只适合上线调试的场景,直接使用Django内置的Web服务器提供服务,单线程,性能很低,真正上线服务,还是要uwsgi配合nginx部署。

理清思路

以前我写过文章介绍了Django应用使用uwsgi+nginx在Linux服务器上直接的部署方法,现在我们为了方便管理,使用Docker来部署Django应用。

我看到网上很多方案都是把nginx也一起用了docker,感觉有些不妥,我们服务器上可能有很多个项目,一个项目一个nginx,多占用的资源不说,就配置而言,也要麻烦不少。

一个装在系统里的nginx是完全足够的,也方便配置,就我们团队而言,公司的网安做得比较严格,对服务器开放的端口和申请的域名有限制,没办法一个应用开一个端口,只能用nginx监听一个端口并且配置反向代理来实现多个项目的服务,所以一个nginx就很方便了。

我们的思路是django和uwsgi放在docker里,老办法,使用docker-compose编排相关依赖的数据库、缓存、监控服务,然后使用nginx做反向代理和提供静态文件服务,为了静态文件和代码热更新,还要做volume映射。

接下来一步步介绍构建一个方便的uwsgi+django镜像的方法。

Dockerfile编写

首先是我们的镜像文件,相比起之前的开发镜像,多了一个uwsgi模块,其他的不变。

FROM python:3.7

# 设置 python 环境变量
ENV PYTHONUNBUFFERED 1 # 创建 code 文件夹并将其设置为工作目录
RUN mkdir /code
WORKDIR /code # 更新 pip
RUN pip install -i https://mirrors.aliyun.com/pypi/simple pip -U
# 设置国内源
RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple # 将 requirements.txt 复制到容器的 code 目录
ADD requirements.txt /code/ # 安装库
RUN pip install -r requirements.txt # 将当前目录复制到容器的 code 目录
ADD . /code # 安装uwsgi
RUN pip install uwsgi

uwsgi的ini配置

uwsgi的配置我选择ini的形式,文件内容如下:

[uwsgi]
socket = :8000 # the base directory (full path)
chdir = /code # Django s wsgi file
module = config.wsgi # 启用主进程,当进程挂掉会再spawn一个(以下三个指标,实现“并发”)
master = true
# 进程个数
processes = 4
# 每个进程中的线程个数/workers
threads = 2
# 一个工作进程最大请求数
max-requests = 5000 vacuum = true # pid文件,用于脚本启动、停止该进程
pidfile = /code/uwsgi.pid # 当文件改变时,优雅的重启uWSGI
touch-reload = /code/readme.md

注意一点,在之前的配置中,我们是用daemonize = log/uwsgi.log来配置日志文件路径实现uwsgi输出日志的,但是如果docker这样做的话,会导致docker-compose启动这个容器的时候直接执行完成自动退出,所以权宜之计只能不输出日志文件,输出到控制台,这样保持容器不被关闭(以后有更好的方法我会更新文章进行记录)

还有我用了touch-reload来监控文件修改自动重启uwsgi,这样就可以实现代码的热更新了(严格来说不算真的热更新哈哈哈。但够用了)每次更新代码的同时修改一下readme文件,可以记录一下更新内容,又自动重启了服务,多方便~

不过这样的热更新会带来短暂的 bad request ,所以尽量选择流量少的时段进行服务更新~

目前的系统还比较简单,所以我的方案是在测试服务器测试没问题就会同步代码到线上服务器~ 由于前端是小程序且用户量还不大,所以用户基本无感知~

Docker-Compose

这个没啥好说啦,就改了一下command而已~

version: "3"
services:
redis:
image: redis
expose:
- 6379
web:
restart: always # 除正常工作外,容器会在任何时候重启,比如遭遇 bug、进程崩溃、docker 重启等情况。
build: .
environment:
- ENVIRONMENT=docker
command: uwsgi uwsgi.ini
volumes:
- .:/code
ports:
- "19001:8000"
depends_on:
- redis

经过以上的步骤,一个简单的docker-compose up命令就把我们的服务跑起来了,再在nginx里配置一下反向代理和静态文件就美滋滋了,关于nginx的配置的,我打算下一篇文章再讲。

最后就是关于性能了,经过以上的部署,经过测试这个系统在目前没有任何优化的情况下可以承受最高1800 QPS,可能大佬会觉得太低了,嗯Python这性能确实…但按照目前我们的产品来说完全足够(超出),不行就让公司堆配置,反正是云服务随便扩容(公司服务器和钱都管够哈哈哈)以后按需优化…溜了哈哈哈

聊聊Django应用的部署和性能的那些事儿的更多相关文章

  1. Linux 集群概念 , wsgi , Nginx负载均衡实验 , 部署CRM(Django+uwsgi+nginx), 部署学城项目(vue+uwsgi+nginx)

    Linux 集群概念 , wsgi , Nginx负载均衡实验 , 部署CRM(Django+uwsgi+nginx), 部署学城项目(vue+uwsgi+nginx) 一丶集群和Nginx反向代理 ...

  2. 将 Django 应用程序部署到生产服务器

    原文出自: http://www.ibm.com/developerworks/cn/opensource/os-django/ 比较有启发性质的一篇文章,会避免很多弯路 Django 是一个基于 P ...

  3. django 本地项目部署uwsgi 以及云服务器部署 uwsgi+Nginx+Docker+MySQL主从

    一 .django 本地项目部署uwsgi 1 本地部署项目 uwsgi安装测试 通过uwsgi 进行简单部署 安装uwsgi命令:pip install uwsgi -i http://pypi.d ...

  4. Ubuntu14.04 Django Mysql安装部署全过程

    Ubuntu14.04 Django Mysql安装部署全过程   一.简要步骤.(阿里云Ubuntu14.04) Python安装 Django Mysql的安装与配置 记录一下我的部署过程,也方便 ...

  5. Ubuntu 14.04下Django+MySQL安装部署全过程

    一.简要步骤.(Ubuntu14.04) Python安装 Django Mysql的安装与配置 记录一下我的部署过程,也方便一些有需要的童鞋,大神勿喷~ 二.Python的安装 由于博主使用的环境是 ...

  6. 【Django】 gunicorn部署纪要

    使用Gunicorn 来部署Django应用, 没有一步一步写怎么操作,简单记录下重要的点,方面以后查阅. 主要的方式还是Nginx反向代理到Gunicorn, Gunicorn wsgi来启动Dja ...

  7. 解决django配合nginx部署后admin样式丢失

    解决django配合nginx部署后admin样式丢失 1.  在项目的settings.py文件里添加以下内容: STATIC_URL = '/static/' STATICFILES_DIRS = ...

  8. **测试某系统切换成docker部署之后性能的下降情况**

    ###分析 * 对比:某系统/docker* A:某系统性能情况* B:dockers部署的性能情况* 求出A&B两者之间的差异* 确定性能指标(tps)* 测试报告里体现:tps的变化 ## ...

  9. 高性能web服务器(热死你)Resin Linux的安装、配置、部署,性能远超Nginx支持Java、PHP等

    高性能web服务器(热死你)Resin Linux的安装.配置.部署,性能远超Nginx支持Java.PHP等 一.    安装resin 1.  下载resin: 下载地址:http://cauch ...

随机推荐

  1. 《JavaScript高级程序设计》(第二版)

    这本书的作者是 Nicholas C.Zakas ,博客地址是 http://www.nczonline.net/ ,大家可以去多关注,雅虎的前端工程师,是YUI的代码贡献者,可想而知这本书得含金量, ...

  2. 用户不在sudoers文件中怎么办,ziheng is not in the sudoers file解决方法

    sudo是linux系统中,用来执行需要权限命令,但是一些朋友使用sudo时,出现下面的错误“ziheng is not in the sudoers file. This incident will ...

  3. 在 Spring Boot 中,如何干掉 if else!

    需求 传统实现 策略模式实现 ClassScanner:扫描工具类源码 总结 需求 这里虚拟一个业务需求,让大家容易理解.假设有一个订单系统,里面的一个功能是根据订单的不同类型作出不同的处理. 订单实 ...

  4. 真的可以,用C语言实现面向对象编程OOP

    ID:技术让梦想更伟大 作者:李肖遥 解释区分一下C语言和OOP 我们经常说C语言是面向过程的,而C++是面向对象的,然而何为面向对象,什么又是面向过程呢?不管怎么样,我们最原始的目标只有一个就是实现 ...

  5. 'printf' Function

    printf is not part of the C language; there is no input or output defined in C itself. printf is jus ...

  6. vue项目chunk包loading失败解决办法

    错误截图: 解决方法: // loading chunk 出错处理 router.onError((error) => { const pattern = /Loading chunk (\d) ...

  7. Mybatis一对一映射resultMap子标签中顺序问题

    直接上图 鼠标点上红线出现如下提示 The content of element type "resultMap" must match  "(constructor?, ...

  8. Docker镜像-删除镜像

    因为尝试使用新的镜像,对原来的镜像进行删除,报错如下: 意思就是在删除镜像之前,要先删除对应的docker.因为该image被对应的container引用,所以image删除失败. 显示所有状态的容器 ...

  9. Hexo学习

    01.安装 Node.js 打开官方网站 https://nodejs.org 267b6d6d335cf62907c70321a1cbd3b 安装步骤非常简单,一直next,下一步就可以了,默认安装 ...

  10. postman-3-请求

    请求头 单击Headers选项卡将显示请求头键-值编辑器.我们可以将任何字符串设置为请求头名称.在输入字段时,自动完成下拉菜单将补充常见HTTP请求头. Content-Type标题的值也可从自动完成 ...