原文URL:https://www.jianshu.com/p/ad2731c2dce4

这几天做了一个简单的博客站点,开发基本完成之后发现部署真的是一个大问题,在网上看了好多经验贴,跟着他们一步一步的做,因为网上的教程中使用的系统和版本都不是完全相同的,所以后来还是没有部署成功。后来一步一步捋清Nginx和uwsgi之间的关系,把他们的原理搞明白,这才成功部署,这个过程花了大概two days。

一、背景+环境说明

1、Nginx

Nginx 是俄罗斯人编写的十分轻量级的 HTTP 服务器,Nginx,它的发音为“engine X”,是一个高性能的HTTP和反向代理服务器,同时也是一个 IMAP/POP3/SMTP 代理服务器。Nginx 是由俄罗斯人 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的。Nginx 以事件驱动的方式编写,所以有非常好的性能,同时也是一个非常高效的反向代理、负载平衡。其拥有匹配 Lighttpd 的性能,同时还没有 Lighttpd 的内存泄漏问题,而且 Lighttpd 的 mod_proxy 也有一些问题并且很久没有更新。 其特点主要有:

处理静态文件,索引文件以及自动索引;打开文件描述符缓冲. 无缓存的反向代理加速,简单的负载均衡和容错. FastCGI,简单的负载均衡和容错. 模块化的结构。包括 gzipping, byte ranges, chunked responses,以及 SSI-filter 等 filter。如果由 FastCGI 或其它代理服务器处理单页中存在的多个 SSI,则这项处理可以并行运行,而不需要相互等待。 支持 SSL 和 TLSSNI. 2、WSGI

WSGI,全称 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是为 Python 语言定义的 Web 服务器和 Web 应用程序或框架之间的一种简单而通用的接口。从名字就可以看出来,这东西是一个Gateway,也就是网关。网关的作用就是在协议之间进行转换。也就是说,WSGI就像是一座桥梁,一边连着web服务器,另一边连着用户的应用。但是呢,这个桥的功能很弱,有时候还需要别的桥来帮忙才能进行处理。 WSGI 的作用如图所示:

WSGI 3、uWSGI

uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。 要注意 WSGI / uwsgi / uWSGI 这三个概念的区分。

WSGI看过前面小节的同学很清楚了,是一种通信协议。 uwsgi同WSGI一样是一种通信协议。 而uWSGI是实现了uwsgi和WSGI两种协议的Web服务器。 4、uwsgi

uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型描述,它与WSGI相比是两样东西。

为什么有了uWSGI为什么还需要nginx?因为nginx具备优秀的静态内容处理能力,然后将动态内容转发给uWSGI服务器,这样可以达到很好的客户端响应。

5、环境说明

Django==2.0,CentOS==7.2,Nginx==1.12.2,uwsgi==2.0.17

这里服务器使用的是阿里云入门级ECS,目前作为一个网站的服务器完全够用了,后续可以根据需要提升配置。期间使用xshell和xftp来远程连接服务器并上传代码和其他一些文件。

二、上传源代码

1、在CentOS中新建一个新用户

首先在服务器中新建一个用户,因为后面用uwsgi的时候用root操作会提示一些警告信息,所以事先新建一个用户,并为用户分配超级管理员权限。然后su - newuser切换到新建的用户下面进行操作。

2、安装Python3

CentOS7.2自带了Python2.7.5,但是Django2.0已经不支持Python2了,所以需要安装Python3。

The Django 1.11.x series is the last to support Python 2. The next major release, Django 2.0, will only support Python 3.5+【来自Django官网】 但是在安装Python3,和系统自带的Python2如何区分呢?而且很多CentOS中的库都依赖于Python2,所以这是一个问题,不过你能遇到的问题别人已经遇到了而且已经完美的解决了,详细操作请看这里。

3、使用virtualenv为Django2.0开辟一个独立的环境

使用virtualenv为Django2.0一个独立的运行环境,注意在创建的时候加上下面这个命令行参数:--python=python3,加入你要在某个文件夹中用virtualenv新建一个Django2.0的项目,可以使用:virtualenv --no-site-packages venv --python=python3便可以完成这一步。

除此之外,还要安装好项目中所有的依赖库,比如pillow,django-ckeditor等等。

4、在3中创建的独立环境里面再创建一个Django2.0项目

这里使用:

django-admin startproject your_project_name【your_project_name=开发好的项目名称】

cd your_project_name

django-admin startapp your_app_name【your_app_name=开发好的项目中的APP名称】 5、上传你的源代码

使用xftp直接将开发好的项目下的文件上传到4中新建好的空项目中:

上传源代码 项目结构 在我的项目中:project_name=myblog app_name=blog

这时可以使用django自带的:python manage.py runserver 0:8080测试项目是否可以正常运行,按理来说是可以的。

三、安装和配置uwsgi

1、安装uwsgi

进入你的项目中,注意这里需要进入virtualenv环境中,并用source venv/bin/activate激活这个独立的环境。然后使用pip install uwsgi来安装uwsgi。

安装完成之后编写一个文件来测试一下

def application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return "Hello World" 然后在终端使用测试一下uwsgi安装 是否成功:

uwsgi --http :80--wsgi-filetest.py,出现下面即成功 uwsgi测试成功

使用uwsgi测试项目是否可以正常运行:

uwsgi --http :8080 --chdir /home/walker/walkerblog/myblog/ --module myblog.wsgi
#用--chdir指定项目所在位置;用--module指定项目的wsgi文件,这里直接使用项目名称.wsgi即可 这是按理来说是可以访问你的站点了,只是还不能加载静态文件。 使用下面这句来指定静态文件,从而让站点可以像和使用 python manage.py runserver一样来运行,注意这种只是临时的一种方式。

uwsgi --http :8080 --chdir /home/walker/walkerblog/myblog/ --module myblog.wsgi --static-map=/static=static 此时,已经可以正常访问你的站点了。

2、编写uwsgi配置文件

在项目目录中新建一个uwsgi.ini文件,和manage.py在同一个文件夹内即可,文件内容如下:

#uwsgi.ini file [uwsgi]

Django-related settings

socket = 127.0.0.1:8001

the base directory (full path)

chdir = /home/walker/walkerblog/myblog #你的项目路径

Django's wsgi file

module = myblog.wsgi #项目名称.wsgi

process-related settings

master

master = true

maximum number of worker processes

processes = 2

... with appropriate permissions - may be needed

chmod-socket = 666

chown-socket = nginx:nginx

clear environment on exit

vacuum = true

enable-threads = true

uwsgi配置文件 这里注意socket中127.0.0.1表示本机,后面的8001表示端口,你可以指定一个范围从1024到65535的整数作为动态端口,因为前面的1023个是固定使用的端口,并且不能和已有程序中使用的port冲突,这个端口要和后面Nginx配置文件中的socket端口相同。

四、安装个配置Nginx

1、安装Nginx

在root用户下使用yum -y install nginx便可以完成安装Nginx

安装完成之后使用 nginx -t测试一下,出现successful表示安装成功

Nginx测试 2、配置Nginx

nginx的配置文件在:/etc/nginx/nginx.conf,使用vim进行编辑

upstream django {     #自己加入的部分
    server 127.0.0.1:8001;    #端口8001必须和uwsgi配置文件中的socket端口一样
}

server {

    listen      80 default_server;

    listen      [::]:80 default_server;

    server_name  www.your_domain.com your_domain.com  your_ip_addr;

    root        /home/walker/walkerblog/myblog;    #项目路径

    # Load configuration files for the default server block.

    include /etc/nginx/default.d/*.conf;

    location / {

            include uwsgi_params;

            uwsgi_pass django;

    }

    location /static/ {    #加入静态文件路径,包括css文件,image文件和js文件

            autoindex on;

            alias /home/walker/walkerblog/myblog/static/;

    }

    location /media/ {    #加入其他资源文件,上传文件

            autoindex on;

            alias /home/walker/walkerblog/myblog/meida/;

    }

到这里,按理来说就可以正常访问网站了,切换到新建的用户下使用:uwsgi --ini uwsgi.ini & nginx就OK了。

但是

还是有点问题,静态文件还是访问不了,在/var/log/nginx/error.log发现是

因为权限

造成的,在nginx.conf的最上面,有一句

user nginx; 把它改成:

user root; 即可解决问题!

3、Nginx常用操作及说明

(1) 日志文件和错误信息

在/etc/nginx/nginx.conf中已经指定好了日志文件和错误信息: 日志文件 如果不能成功配置,可以打开这两个文件看详细原因,然后对症下药,这样问题解决得还是比较快的。 (2) nginx常用操作

nginx -t #测试nginx是否安装成功; nginx -s stop/quit #停止nginx服务进程 nginx -s reload #在不停止服务的条件下重新加载一些配置文件,比如css和js文件; 好了,如果整个过程还是有问题,我建议你先好好想一想它们之间的关系,不要只跟着别人的去盲目的“配置”,因为自己的环境或者其他信息都不太一样,所以你首先要想清楚,然后再去动手。

作者:xWalker 链接:https://www.jianshu.com/p/ad2731c2dce4 來源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。