随着工作的深入,我越来越发现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. Typora及Markdown的介绍及使用

    Typora及Markdown的介绍及使用 Typora是一款免费的Markdown编辑器,Typora不像其他Markdown编辑器一样使用一边代码一边预览的方式,而是写完代码之后直接出效果,所见即 ...

  2. 一个比CBitmap更优秀的类 -- CImage类

    Visual C++的CBitmap类的功能是比较弱的,它只能显示出在资源中的图标.位图.光标以及图元文件的内容,而不像VB中的Image控件可以显示出绝大多数的外部图像文件(BMP.GIF.JPEG ...

  3. 【部分】@using (Html.BeginForm())参数示例

    原文:https://www.cnblogs.com/firstcsharp/p/3238321.html 1.指定表单提交方式和路径等 @using (Html.BeginForm("In ...

  4. 不错的UI设计

  5. 单调队列练习题解(切蛋糕&好消息,坏消息)

    单调队列的练习题解 前言: 在上一篇学习记录中,单调队列给出了几道练习题,因为这两道题的算法以及思路相差无几(几乎可以算是双倍经验quq),所以就在这里集中写一下相关的题解 前置知识: 见:队列专题( ...

  6. My97DatePicker 4.8

    https://jeesite.gitee.io/front/my97/demo/index.htm

  7. Angular2-------Error: Unexpected value ‘undefined’ declared by the module ‘模块名

    请检查[app.module.ts]文件中的[declarations]模块最后是否多了一个逗号 (完)

  8. Mysql百万级数据查询优化

    1.   直接用limit start, count分页语句, 也是我程序中用的方法: select * from product limit start, count当起始页较小时,查询没有性能问题 ...

  9. Maven Jar包下载失败及解决方案

    我是阿福,公众号「阿福聊编程」作者,一个在后端技术路上摸盘滚打的程序员,在进阶的路上,共勉! 文章已收录在 JavaSharing 中,包含Java技术文章,面试指南,资源分享. 明显的下载失败 具体 ...

  10. Activity启动流程分析

    我们来看一下 startActivity 过程的具体流程.在手机桌面应用中点击某一个 icon 之后,实际上最终就是通过 startActivity 去打开某一个 Activity 页面.我们知道 A ...