nginx+uwsgi+django

一django部分需要修改:

归纳:

  1. 自定义设置404.html和500.html文件
  2. 关闭开发模式:DEBUG = False 和TEMPLATE_DEBUG = False
  3. 设置ALLOWED_HOSTS =[]

平时我们写的代码都是用django的开发模式,该模式输出的错误信息(error详情页)和修改配置文件之后自动重启配置生效的特点。

在生产模式中,为了安全,以及程序稳定性,需要关闭开发模式。

一:关闭debug模式:

在开发模式中,默认是开启debug模式,在setting.py中可以看出:

1 # SECURITY WARNING: don't run with debug turned on in production!
2 DEBUG = True

在setting配置文件已经告知这个模式不在生产中使用。

该模式:

  • 所有的数据库查询将被保存在内存中, 以 django.db.connection.queries 的形式. 你可以想象,这个吃内存!
  • 任何404错误都将呈现django的特殊的404页面,而不是普通的404页面。 这个页面包含潜在的敏感信息,但是不会暴露在公共互联网。比如含有url信息:

  • 你的应用中任何未捕获的异常,从基本的python语法错误到数据库错误以及模板语法错误都会返回漂亮的Django错误页面。 这个页面包含了比404错误页面更多的敏感信息,所以这个页面绝对不要公开暴露。

注意:

debug设置成True和False的时候,setting.py文件中ALLOWED_HOSTS 默认值是[]empty list设置:

ALLOWED_HOSTS可以设置成完整的可以被解析的FQDN主机名,比如:www.example.com 句点前可以写shell的通配符比如:*.example.com会匹配以example.com结尾的主机名。

其中匹配的不区分大小和端口号。当然如果ALLOWED_HOSTS 的值写成['*']会匹配所有的主机。

1、DEBUG=True

  • ALLOWED_HOSTS设置成空的列表即:ALLOWED_HOSTS =[]和DEBUG=True的时候,那么将会阻止一些host访问:['localhost', '127.0.0.1', '[::1]']。ALLOWED_HOSTS value default is empty list。
  • DEBUG=False的时候,需要设置ALLOWED_HOSTS 的值,来保证那些主机可以访问的web项目。
  • 在django1.10.3 、1.911、 1.8.16当DEBUG=True,会ALLOWED_HOSTS进行检查,其他的老版本中不会检查ALLOWED_HOSTS

二、关闭模板的debug模式:

类似的在模板的debug形式,也会显示一些敏感信息,也需要关闭这个模式。

 该设置的值在:OPTIONS中设置debug,默认值是False

 1 TEMPLATES = [
 2     {
 3         'BACKEND': 'django.template.backends.django.DjangoTemplates',
 4         'DIRS': [],
 5         'APP_DIRS': True,
 6         'OPTIONS': {
 7             # ... some options here ...
 8         },
 9     },
10 ]

综上所述需要关闭在setting.py的里的DEBUG=False或者去掉该选项,默认值是False。之后需要设置ALLOWED_HOSTS的值,否则django启动报错。(CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False.)

设置成False之后,django将不会提供错误页面以及静态资源(css、js、html等)的访问。

所以接下来我们需要做:写错误页面和静态资源访问设置(由nginx提供)

 设置404错误页面:

在模板的根目录下设置一个404页面,楼主的模板的根目录为template:

404页面内容:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4   <meta http-equiv="content-type" content="text/html; charset=utf-8">
 5   <title>Page not found at /</title>
 6   <meta name="robots" content="NONE,NOARCHIVE">
 7   <style type="text/css">
 8     html * { padding:0; margin:0; }
 9     body * { padding:10px 20px; }
10     body * * { padding:0; }
11     body { font:small sans-serif; background:#eee; }
12     body>div { border-bottom:1px solid #ddd; }
13     h1 { font-weight:normal; margin-bottom:.4em; }
14     h1 span { font-size:60%; color:#666; font-weight:normal; }
15     table { border:none; border-collapse: collapse; width:100%; }
16     td, th { vertical-align:top; padding:2px 3px; }
17     th { width:12em; text-align:right; color:#666; padding-right:.5em; }
18     #info { background:#f6f6f6; }
19     #info ol { margin: 0.5em 4em; }
20     #info ol li { font-family: monospace; }
21     #summary { background: #ffc; }
22     #explanation { background:#eee; border-bottom: 0px none; }
23   </style>
24 </head>
25 <body>
26   <div id="summary">
27     <h1>Page not found <span>(404)</span></h1>
28     <table class="meta">
29       <tr>
30         <th>Request Method:</th>
31         <td>GET</td>
32       </tr>
33       <tr>
34         <th>Request URL:</th>
35         <td>http://127.0.0.1:8000/</td>
36       </tr>
37 
38     </table>
39   </div>
40 </body>
41 </html>

 我们访问一个不存在url:

同样我们可以定义的500错误页面在模板的根目录下:

 1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
 2     "http://www.w3.org/TR/html4/strict.dtd">
 3 <html lang="en">
 4 <head>
 5     <title>Page unavailable</title>
 6 </head>
 7 <body>
 8 
 9 
10     <h1>Page unavailable</h1>
11 
12     <p>Sorry, but the requested page is unavailable due to a
13     server hiccup.</p>
14 
15     <p>Our engineers have been notified, so check back later.</p>
16 </body>
17 </html>

 针对不同的产品线和环境设置你们想要的模式:

比如说在生成环境中 你不要自己手动修改DEBUG=False,和TEMPLATE_DEBUG=False,在测试环境中设置True的时候,你可以在你自己的setting.py的文件中进行如下代码的判断:

1 # settings.py
2 
3 import socket
4 
5 if socket.gethostname() == 'my-laptop':
6     DEBUG = TEMPLATE_DEBUG = True
7 else:
8     DEBUG = TEMPLATE_DEBUG = False

根据主机名的不同。设置不同的参数。方便灵活每次切换环境。

当然了,我们在测试环境和生产环境中的数据库是不一样的,所以我们有可能setting的设置是不一样的。那怎么办呢?

我们可以进行如下设计:

1、你可以根据上面的例子,对系统的主机名进行判断加载不同的配置。

测试:

 1  2 
 3 DEBUG = True
 4 TEMPLATE_DEBUG = DEBUG
 5 
 6 DATABASE_ENGINE = 'postgresql_psycopg2'
 7 DATABASE_NAME = 'devdb'
 8 DATABASE_USER = ''
 9 DATABASE_PASSWORD = ''
10 DATABASE_PORT = ''

生产:

1 2 
3 from settings import *
4 
5 DEBUG = TEMPLATE_DEBUG = False
6 DATABASE_NAME = 'production'
7 DATABASE_USER = 'app'
8 DATABASE_PASSWORD = 'letmein'

主配置文件为:setting.py文件。内容如下:

 1 # settings.py
 2 
 3 import socket
 4 
 5 if socket.gethostname() == 'my-laptop':
 6     DEBUG = TEMPLATE_DEBUG = True
 7     DATABASE_ENGINE = 'postgresql_psycopg2'
 8     DATABASE_NAME = 'devdb'
 9     DATABASE_USER = ''
10     DATABASE_PASSWORD = ''
11     DATABASE_PORT = ''
12 else:
13     DEBUG = TEMPLATE_DEBUG = False  
14     DEBUG = TEMPLATE_DEBUG = False
15     DATABASE_NAME = 'production'
16     DATABASE_USER = 'app'
17     DATABASE_PASSWORD = 'letmein'

这样根据不同的环境设置我们想要的开发模式。

注意:

  • 如果修改了setting.py文件的文件名字,django并不关心你想修改成什么文件名字,只要你告诉django使用的配置文件是哪个就可以.
  • 在manange.py文件中进行修改,其中有如下配置需要更改:
1 if __name__ == "__main__":
2     os.environ.setdefault("DJANGO_SETTINGS_MODULE", "url.settings")

 我的项目叫做url,所以在url.setting 改成url.yousettingname即可!

 二:配置uwsgi

官方地址:http://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html

首先安装uwsgi:我们采用的pip安装

1 pip install  uwsgi

 测试我们安装的uwsgi,测试的脚本:

1 # test.py
2 def application(env, start_response):
3     start_response('200 OK', [('Content-Type','text/html')])
4     #return ["Hello World"] # python2
5     return [b"Hello World"] # python3

shell命令行测试命令:

1 uwsgi --http :8001 --plugin python --wsgi-file test.py 

浏览器输入:http://192.168.217.167:8001/

效果:

表示uwsgi 测试成功!

注意:

一般nginx端的配置如下:

1 location / {
2     include uwsgi_params;
3     uwsgi_pass 127.0.0.1:3031;
4 }

 

如上配置说明,每个请求都通过端口为3031的为uwsgi协议的服务器,所以uwsgi的服务启动以--socket形式启动而不是http。

 uwsgi --socket 127.0.0.1:3031 --wsgi-file foobar.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191 

如果前端的代理、webserver、路由是HTTP协议的话,你需要告诉你UWSGI的服务是以http协议进行进行接收nginx的请求,uwsgi服务以如下方式启动:

 uwsgi --http-socket 127.0.0.1:3031 --wsgi-file foobar.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191 

出现的状况:

  • 启动的方式需要注意:是以uwsgi --http :8001 --plugin python --wsgi-file test.py 以http方式。如果使用前端nginx的时候,不要以http方式启动,需要以uwsgi --socket:8001 --plugin python --wsgi-file test.py
  • socket方式启动。这种方式直接访问,是访问不了,需要通过nginx,以uninx  socket的方式访问,nginx配置为:uwsgi_pass localhost:8001;方式访问,不能以http方式启动监听否则报502错误!

测试django:

linux环境安装app:

安装project:

1 django-admin.py  startproject  testdj

 安装应用:

1 python3.5 manage.py  startapp  testuwsgi

 配置url:

1 urlpatterns = [
2     url(r'^admin/', admin.site.urls),
3     url(r'^test/', view.ws),
4 ]

视图配置:

1 from django.shortcuts import render,HttpResponse
2 
3 # Create your views here.
4 def  ws(request):
5     return HttpResponse('ok')

关闭django开发模式和配置:ALLOWED_HOSTS = ['*’]注意是字符串。

启动项目:

1  python3.5  manage.py runserver 0.0.0.0:8888## 注意是0.0.0.0 监听所有地址

 访问:http://192.168.217.167:8888/test/

效果:

然后uwsgi和django结合,需要到django的项目根目录里。执行shell命令:

1 uwsgi --http :8001 --plugin python --module testdj.wsgi

然后访问:http://192.168.217.167:8001/test/

效果:

uwsgi出现日志:

说明配置没问题。注意这时项目的静态文件是不会被加载的,需要用nginx做静态文件代理

 如果这个时候,你不行配置nginx的话,使用uwsgi的话,需要做如下配置:

uwsgi支持文件启动,我们可以在django项目的根目录建立uswgi.ini文件,代理django项目,文件内容如下:

1 [uwsgi]
2 socket = 0.0.0.0:9090
3 chdir = /export/testdj#django的项目的路径。
4 wsgi-file = testdj/wsgi.py#wsgi文件。
5 processes = 4#主进程为4
6 threads = 2#每个进程的线程为2。
7 stats = 127.0.0.1:9191#uwsgi的监控信息监听地址。

shell命令行启动:

1 # uwsgi --ini uwsgi.ini

更详细的参数请参照:https://uwsgi.readthedocs.io/en/latest/Configuration.html

深入讲解uwsgi:

一、并发参数

如上启动只启动一个uwsgi进程来处理nginx请求,当我们的请求并发高的时候,这个时候需要增加uwsgi的进程数来帮忙处理nginx的请求,参数如下:

--processes  进程数  --threads 每个进程的线程数。

1 uwsgi --http :9090 --wsgi-file foobar.py --master --processes 4 --threads 2

将会产生4个进程,每个进程有2个线程,还有一个主进程,作用是当进程死之后,派生子进程以及http路由的作用!!!!

二、监控uwsgi信息

uwsgi还为提供一个json串的监控信息,方便我们进行对uwsgi的监控,但是需要额外启动另外一个监听进行相关的操作:--stats 127.0.0.1:9191

1 uwsgi --http :9090 --wsgi-file foobar.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191

以这种方式进行启动的时候,本地会启动9191的监听,方便我们进行对uwsgi进行相关监控,对于监听视情况而定 是本机监控还是扩服务器而进行不同的地址监听(--stats 0.0.0.0:9191)

用浏览器访问或者Telnet都可以获取目前的监控信息。

方便我们以后进行相关监控的提供api!

三:wsgi.py不存在:

如果文件django中wsgi.py文件不存在的话,你使用django的版本低于1.4,如果是这种情况的话。需要做一些参数添加和修改:

1 uwsgi --socket 127.0.0.1:3031 --chdir /home/foobar/myproject/ --pythonpath .. --env DJANGO_SETTINGS_MODULE=myproject.settings --module "django.core.handlers.wsgi:WSGIHandler()" --processes 4 --threads 2 --stats 127.0.0.1:9191

uwsgi的启动文件变动如下:

1 [uwsgi]
2 socket = 127.0.0.1:3031
3 chdir = /export/testdj
4 pythonpath = ..
5 env = DJANGO_SETTINGS_MODULE=myproject.settings
6 module = django.core.handlers.wsgi:WSGIHandler()
7 processes = 4
8 threads = 2
9 stats = 127.0.0.1:9191

三:配置nginx

nginx这里我们采用yum安装,当然也可以进行编译安装,视情况而定:

1 # yum install -y nginx
2 # /etc/init.d/nginx start
3 Starting nginx: [  OK  ]

 yum安装之后,默认读取的xml文件路径:

1 /etc/nginx/conf.d/default.conf

可以在nginx.conf可以指定:

nginx的配置文件:

 1 # cat  /etc/nginx/conf.d/default.conf 
 2 # the upstream component nginx needs to connect to
 3 upstream django {
 4 #     server unix:///run/uwsgi/stats.sock; # for a file socket
 5     server 127.0.0.1:9090; # for a web port socket (we'll use this first)
 6 }
 7 
 8 # configuration of the server
 9 server {
10     # the port your site will be served on
11     listen      80;
12     # the domain name it will serve for
13     server_name 192.168.217.169; # substitute your machine's IP address or FQDN
14     charset     utf-8;
15 
16     # max upload size
17     client_max_body_size 75M;   # adjust to taste
18 
19     # Django media
20     location /media  {
21         alias /path/to/your/mysite/media;  # your Django project's media files - amend as required
22     }
23 
24     location /static {
25         alias /export/testdj/static; # your Django project's static files - amend as required
26     }
27 
28     # Finally, send all non-media requests to the Django server.
29     location / {
30         uwsgi_pass  django;
31         include     /etc/nginx/uwsgi_params; # the uwsgi_params file you installed
32     }
33 }

 访问:http://192.168.217.169/test/

 uwsgi官方地址:http://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html

 完美!!! 搞定!

 

posted @ 2016-12-28 17:56  evil_liu  阅读(287)  评论(0)    收藏  举报