WEB平台DJANGO&VUE配置部署生产环境

栏目: Python · 发布时间: 7年前

内容简介:本文主要讲述了如何一步步在生产环境上部署django和vue,操作系统默认为centos说明:后文中出现的以下字符串均表示具体的路径或者名称,含义如下:一个常用的web框架图如下图所示

本文主要讲述了如何一步步在生产环境上部署django和vue,操作系统默认为centos

说明:后文中出现的以下字符串均表示具体的路径或者名称,含义如下:

  • DJANGO_DIR----表示django的工程根目录
  • DJANGO_NAME----表示django的工程名称
  • VUE_HTML_DIR----表示vue编译好的index.html路径
  • VUE_STATIC_DIR----表示vue编译好的静态文件夹static的路径

整体框架

一个常用的web框架图如下图所示

框架选用.jpg

我们使用nginx + uwsgi来驱动django,因为uwsgi性能非常高

720333-20170312154455592-1425120615.png

一、安装和配置nginx

安装

使用yum安装即可

yum -y install nginx

启动

service nginx start

此时到浏览器输入对应的ip地址,出现下面页面即表示安装成功

1324702136-57fb16aa00d21_articlex.png

修改配置文件

nginx可以新建一个配置,放在项目目录,暂时不修改nginx的默认配置,端口号可以换一个,然后在/etc/nginx/conf.d/内新建一个软链接指向该配置文件,这样nginx在读取配置时会将该配置一起读进去。这样,访问端口号8080的请求便会指向我们自己的这个配置。

server {
    listen 8080;
    server_name 132.232.50.225;
    root /data/;
    charset  utf-8;
    access_log /data/access_narwhals.log;
    error_log /data/error_narwhals.log;
    client_max_body_size 75M;
    location / {
            uwsgi_pass 127.0.0.1:9090;
            include /etc/nginx/uwsgi_params;
    }
    location ^~ /admin/ {
            uwsgi_pass 127.0.0.1:9090;
            include /etc/nginx/uwsgi_params;
    }
}

该配置中uwsgi_pass要指向uwsgi绑定的接口。(我们先假设uwsgi配置的是9090端口)

二、安装和配置uwsgi

安装

使用yum或者pip均可安装

yum install uwsgi
# 或者
pip install uwsgi

不过这里需要注意,如果运行uwsgi出现下面错误

uwsgi: option '--http' is ambiguous; possibilities: '--http-socket' '--https-socket-modifier2' '--https-socket-modifier1' '--https-socket' '--http11-socket' '--http-socket-modifier2' '--http-socket-modifier1'
getopt_long() error

主要是用yum安装的uwsgi,缺少 python 的plugin,可以安装对应的插件

yum install uwsgi-plugin-python
plugins = python (加在ini配置文件中)

配置

uwsgi可以使用命令行启动,也可以使用配置文件来启动,推荐使用配置文件来启动守护进程,配置文件内容如下

[uwsgi]
socket = 127.0.0.1:9090
stats = 127.0.0.1:9293
workers = 4
# 项目根目录
chdir = DJANGO_DIR
touch-reload = DJANGO_DIR
py-auto-reload = 1
# 在项目跟目录和项目同名的文件夹里面的一个文件
module= DJANGO_NAME.wsgi
pidfile = /var/run/inner_manager.pid
daemonize = /data/uwsgi9090.log
# If you plan to receive big requests with lots of headers you can increase this value up to 64k (65535).
buffer-size=65535

这里以socket形式运行uwsgi,绑定了本地的9090端口,也就是上文nginx配置中uwsgi_pass指定的端口。

大概解释下几个配置的含义:

  1. chdir----应用加载前chdir到指定目录,一般设置为django的工程根目录
  2. touch-reload----如果修改/碰了指定的文件,那么重载uWSGI
  3. module----加载一个WSGI模块的路径,如果django的话就指向对应的wsgi文件模块
  4. buffer-size----设置请求的最大大小 (排除request-body),这一般映射到请求头的大小。默认情况下,它是4k。如果你接收到了一个更大的请求 (例如,带有大cookies或者查询字符串),那么你也许需要增加它。它也是一个安全度量,所以调整为你的应用需要,而不是最大输出。该值如果太小会报错

具体参数含义可以到 官方文档 查找

然后使用命令启动uwsgi进程,其中uwsgi.ini为上面内容的配置文件

uwsgi -i uwsgi.ini

可以看下日志文件有没有报错,或者看下 ps -ef|grep uwsgi 进程有没有跑起来。一定要确保进程正常run起来才行

至此,DJANGO已经通过nginx+uwsgi可以访问了

三、配置访问vue

其实这里访问编译好的vue静态文件有很多方式,本文主要讲述 通过nginx直接访问通过django路由访问

通过django路由访问

其实我们也可以直接通过http://ip:8080/ 来经由django的路由来访问vue的页面。当然要做到这样要确保以下配置的正确

找到DJANGO_DIR根目录下DJANGO_NAME同名文件夹下urls.py,使用通用视图创建最简单的模板控制器,增加一行路由

url(r'^$', TemplateView.as_view(template_name="index.html")),

这样访问 http://ip:8080/ 时会直接返回 index.html。

上一步使用了Django的模板系统,所以需要配置一下模板使Django知道从哪里找到index.html。在project目录的settings.py下:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [VUE_HTML_DIR],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

按照上述配置完成后,结合前面配置好的nginx和uwsgi,你已经可以通过http://ip:8080/ 来访问到对应的vue编译好的VUE_HTML_DIR目录下的index.html了,但是这时候你可能会有其他困扰,比如找不到css样式文件的问,这经常是静态配置有误导致找不到静态文件的问题。

Django通过django.contrib.staticfiles来管理静态文件,首先确保django.contrib.staticfiles已经添加到INSTALLED_APPS。

然后可以在DJANGO的配置文件settings.py中增加以下几个配置:

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static")
# Add for vuejs
STATICFILES_DIRS = [
    VUE_STATIC_DIR,
    # other static folders
]
  • STATIC_URL 对外提供WEB访问时static的URL地址
  • STATIC_ROOT 设置绝对路径, 用来保存收集到的静态文件,服务器最终也将从该路径中获取文件进行转发。在collectstatic运行的时候会把 STATICFILES_DIRS 中的静态文件拷贝到这个目录中,达到从开发环境到生产环节过程中移植静态文件的作用。
  • STATICFILES_DIRS 用来配置一些开发环境下生成的静态文件的地址,即编译好的VUE_STATIC_DIR

在url.py中添加路由

url(r'^static/(?P<path>.*)$', static.serve,
        {'document_root': settings.STATIC_ROOT}, name='static'),

配置好以上配置后,编译好的静态文件还在 VUE_STATIC_DIR 目录下,我们最终要执行下面命令才能把 STATICFILES_DIRS 中的静态文件拷贝到 STATIC_ROOT 这个目录中,也就是最终生产环境指定的static的存放目录

python manage.py collectstatic

那么为什么不直接手动把构建好的VUE_STATIC_DIR中的文件拷过来呢,因为Django自带的App:admin 也有一些静态文件(css,js等),它会一并collect过来,毕竟nginx只认项目跟目录的静态文件,它不知道django把它自己的需求文件放到哪了

这样你访问django的admin网址http://ip:8080/admin 时,也不会出现找不到css的问题了

当然这种方式其实是通过django的路由来访问静态文件的,一般的,生产环境不会通过django来转发静态文件,而是通过其他服务器进行转发,比如nginx,apache等,所以这里我们需要再配置下nginx的配置文件,在8080的server中增加如下路径的配置

location /static/ {
        expires 30d;
        autoindex on;
        add_header Cache-Control private;
        alias  VUE_STATIC_DIR;
        access_log off;
    }

这样访问静态文件便会直接通过nginx来访问了,不用担心静态文件访问导致Django的处理速度变慢了。

通过nginx直接访问

如果你想直接通过nginx访问对应的前端vue文件,可以重新配置一个server来访问对应的html文件,比如上面已经使用了8080端口,我们可以用默认的80端口来配置个server,其中root可以指向存放index.html文件的路径, /static/ 路径下的root路径可以指向html对应的存放css和js的static文件夹,如果static就在index.html路径下,不指认也可以。直接修改/etc/nginx.conf即可,里面已经有配置好的80端口的server

配置如下所示

server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
	    root         VUE_HTML_DIR;	

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }
        
        location /static/ {
            root  VUE_STATIC_DIR;
            access_log off;
    	 }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

这样我们可以通过http://ip:80/ 来访问vue编译好的页面,使用http://ip:8080/ 访问django配置的cgi请求

四、通过supervisor管理进程

上面我们已经用到了uwsgi,后面可能还会用到 redis 、celery,都需要开启守护进程,其中celery自身还不支持守护进程。那么如何管理这么多进程呢,这时候可以考虑下supervisor

安装

使用pip安装即可

pip install supervisor

配置

我们可以配置redis,celery,uwsgi进去,比如向下面一样

[program:redis]
;指定运行目录
directory=%(here)s/
;执行命令(redis-server redis配置文件路径)
command=redis-server /etc/redis.conf

;启动设置
numprocs=1          ;进程数
autostart=true      ;当supervisor启动时,程序将会自动启动
autorestart=true    ;自动重启

;停止信号
stopsignal=INT


[program:celery.worker.default]
;指定运行目录
directory=%(here)s/
;运行目录下执行命令
command=celery -A DjangoProject worker --loglevel info --logfile log/celery_worker.log -Q default -n %%h-%(program_name)s-%(process_num)02d
process_name=%(process_num)02d

;启动设置 
numprocs=2          ;进程数
autostart=true      ;当supervisor启动时,程序将会自动启动 
autorestart=true    ;自动重启
 
;停止信号,默认TERM 
;中断:INT (类似于Ctrl+C)(kill -INT pid),退出后会将写文件或日志(推荐) 
;终止:TERM (kill -TERM pid) 
;挂起:HUP (kill -HUP pid),注意与Ctrl+Z/kill -stop pid不同 
;从容停止:QUIT (kill -QUIT pid) 
stopsignal=INT

[program:uwsgi]
;指定运行目录
directory=%(here)s/
;运行目录下执行命令
command=uwsgi -i conf/uwsgi/uwsgi9090.ini

;启动设置
numprocs=1          ;进程数
autostart=true      ;当supervisor启动时,程序将会自动启动
autorestart=true    ;自动重启

;停止信号,默认TERM
;中断:INT (类似于Ctrl+C)(kill -INT pid),退出后会将写文件或日志(推荐)
;终止:TERM (kill -TERM pid)
;挂起:HUP (kill -HUP pid),注意与Ctrl+Z/kill -stop pid不同
;从容停止:QUIT (kill -QUIT pid)
stopsignal=INT

使用

启动supervisor输入如下命令,使用具体的配置文件执行:

supervisord -c supervisord.conf

关闭supervisord需要通过supervisor的控制器:

supervisorctl -c supervisord.conf shutdown

重启supervisord也是通过supervisor的控制器:

supervisorctl -c supervisord.conf reload

一些特殊的变量

%(here)s   配置文件所在路径
(program_name)s   program的名字
%(process_num)02d  多进程时的进程号

注意:command中如果含有%,需要进行转义 %%

多进程时如果不指定process_name会遇到如下错误

Error: Format string 'celery -A INTProject worker --loglevel info --logfile log/celery_worker.log -Q diff_task,caller_task -n %h' for 'program:celery.worker.mac.command' is badly formatted: incomplete format in section 'program:celery.worker.mac' (file: 'supervisord.conf')

中间可能遇到的坑

*8107 recv() failed (104: Connection reset by peer) while reading response header from upstream, client 错误

使用django+uwsgi+nginx,发现如下报错

2018/10/08 14:34:33 [error] 12283#0: *8107 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 9.19.161.66, server: 132.232.50.225, request: "GET /auth/info?token=ZXlKaGJHY2lPaUprWldaaGRXeDBJaXdpZEhsd0lqb2lTbGRRSW4wOjFnOVA3aDp0bVZYcmg3XzJPR3RXSHJrbXFLRVdCZEpUdXc_ZXlKMWMyVnlibUZ0WlNJNkltVjBhR0Z1Wm1GdUlpd2lhV0YwSWpveE5UTTRPVGd3TkRjekxqZzVNekk1TVgwOjFnOVA3aDpMVXRHZkFiQkhrRTNaenFnS3NuS1RvOHBOMGM_3bdf34e6de16096f9982015a2382d3c8 HTTP/1.1", upstream: "uwsgi://127.0.0.1:9090", host: "int.oa.com", referrer: "http://int.oa.com/"

I finally found a reference to fastcgi and a 502 bad gateway error ( https://support.plesk.com/hc/en-us/articles/213903705 ). That lead me to look for a buffer size limit in the uwsgi configuration which exists as buffer-size. The default value is 4096. From the documentation, it says: If you plan to receive big requests with lots of headers you can increase this value up to 64k (65535).

意思是uwsgi中有一项配置是buffer-size,表明收到的最大请求size,默认是4096,可以将其改成65535

buffer-size=65535

#四 参考

https://www.cnblogs.com/alex3714/p/6538374.html

https://stackoverflow.com/questions/22697584/nginx-uwsgi-104-connection-reset-by-peer-while-reading-response-header-from-u


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Masterminds of Programming

Masterminds of Programming

Federico Biancuzzi、Chromatic / O'Reilly Media / 2009-03-27 / USD 39.99

Description Masterminds of Programming features exclusive interviews with the creators of several historic and highly influential programming languages. Think along with Adin D. Falkoff (APL), Jame......一起来看看 《Masterminds of Programming》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

SHA 加密
SHA 加密

SHA 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换