• nginx+uwsgi+django开发环境搭建


    Nginx+uWSGI+Djangoi开发环境搭建

    Django简介,环境搭建

    uWSGI简介,安装与配置

    Nginx安装与配置

    Nginx+uWSGI+Django原理解析

    1、django简介,环境搭建

    django简介

    Django 是用Python开发的一个免费开源的Web框架,可以用于快速搭建高性能,优雅的网站!

    Django 中提供了开发网站经常用到的模块,常见的代码都为你写好了,通过减少重复的代码,Django 使你能够专注于 web 应用上有 趣的关键性的东西。

    Django的理念是DRY(Don't Repeat Yourself)来鼓励快速开发!

    学Django需要什么基础

    1. Django是 python 语言写的一个Web框架包,所以你得知道一些 Python 基础知识。

    2. 其次你最好有一些做网站的经验,懂一些网页 HTMLCSSJavaScript 的知识。

    没有经验也没有关系,慢慢来就好了,你一定可以学会,Django 很简单!

    django环境搭建

    虚拟软件:Oracle VM VirtualBox

    虚拟机系统:centos 6.4

    Python版本:2.7.13

    Django版本:1.11.16

    本地宿主机是win10,以上是我的环境配置,现在开始搭建Django环境。

    安装Django

    pip install Django==1.11.16

    检查Django 是否安装完成

    如果运行后看到版本号,就证明安装成功了。YEAH

    2、uwsgi简介,安装与配置

    uwsgi简介

    uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。

    要注意 WSGI / uwsgi / uWSGI 这三个概念的区分。

    1. WSGI是一种Web服务器网关接口。它是一个Web服务器(如nginx,uWSGI等服务器)与web应用(如用Flask框架写的程序)通信的一种规范。
    2. uwsgi是一种线路协议而不是通信协议,在此常用于在uWSGI服务器与其他网络服务器的数据通信。
    3. 而uWSGI是实现了uwsgi和WSGI两种协议的Web服务器。
    4. uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型描述,它与WSGI相比是两样东西。

    uwsgi安装

      1)uwsgi原理

      2)uwsgi安装与调试

    pip install uwsgi

    安全uwsgi前,确保已安装 yum -y install libxml2 python-devel gcc gcc-c++等插件

    检查uwsgi是否安装成功

    创建一个python文件 test.py

    def application(env, start_response):
        start_response('200 OK',[('Content-Type','text/html')])
        return ['Hello World']
    

    启动uwsgi,命令uwsgi --http :8000 --wsgi-file test.py

     浏览器或者命令行访问http://127.0.0.1:8000/,如果成功,可以看到打印 Hello World

     uwsgi常用命令选项:

    常用选项:
    
    http : 协议类型和端口号
    
    processes : 开启的进程数量
    
    workers : 开启的进程数量,等同于processes(官网的说法是spawn the specified number ofworkers / processes)
    
    chdir : 指定运行目录(chdir to specified directory before apps loading)
    
    wsgi-file : 载入wsgi-file(load .wsgi file)
    
    stats : 在指定的地址上,开启状态服务(enable the stats server on the specified address)
    
    threads : 运行线程。由于GIL的存在,我觉得这个真心没啥用。(run each worker in prethreaded mode with the specified number of threads)
    
    master : 允许主进程存在(enable master process)
    
    daemonize : 使进程在后台运行,并将日志打到指定的日志文件或者udp服务器(daemonize uWSGI)。实际上最常用的,还是把运行记录输出到一个本地文件上。(肯定要启用,要不刷屏!!)
    
    pidfile : 指定pid文件的位置,记录主进程的pid号。   (生成pid文件,以便stop uwsgi)
    
    vacuum : 当服务器退出的时候自动清理环境,删除unix socket文件和pid文件(try to remove all of the generated file/sockets)

    3)uwsgi with django

     新建一个Django project

    1 django-admin.py startproject project_name
    2 #在 windows 上,如果报错,尝试用 django-admin 代替 django-admin.py
    3 #project_name(你的项目名称)

    django-admin startproject dazhahui,项目目录结构如下:

    1 dazhahui
    2 ├── manage.py
    3 └── dazhahui
    4     ├── __init__.py
    5     ├── settings.py
    6     ├── urls.py
    7     └── wsgi.py

    新建一个applicaiton

    python manage.py createapp app_name

    1 python manage.py createapp app_name
    2 # app_name(应用程序的名称)

    python manage.py startapp app_test,应用程序目录结构如下:

    1 test_app/
    2 ├── __init__.py
    3 ├── admin.py
    4 ├── models.py
    5 ├── tests.py
    6 └── views.py

    测试uwsgi with django是否关联成功

    test_app应用程序下的view.py,新增一个index方法,打印 “欢迎光临 我的django”

    1 # -*- coding: utf-8 -*-
    2 from __future__ import unicode_literals
    3 
    4 from django.shortcuts import render
    5 from django.http import HttpResponse
    6 # Create your views here.
    7 def index(request):
    8  return HttpResponse(u'欢迎光临 我的django')

    dazhahui项目下的urls.py, 添加一行 url(r'^$', test_app_views.index)

     1 """dazhahui URL Configuration
     2 
     3 The `urlpatterns` list routes URLs to views. For more information please see:
     4     https://docs.djangoproject.com/en/1.11/topics/http/urls/
     5 Examples:
     6 Function views
     7     1. Add an import:  from my_app import views
     8     2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
     9 Class-based views
    10     1. Add an import:  from other_app.views import Home
    11     2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
    12 Including another URLconf
    13     1. Import the include() function: from django.conf.urls import url, include
    14     2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
    15 """
    16 from django.conf.urls import url
    17 from django.contrib import admin
    18 from test_app import views as test_app_views
    19 urlpatterns = [
    20     url(r'^$', test_app_views.index),
    21     url(r'^admin/', admin.site.urls),

     如果执行命令后,看到启动日志和访问日志,说明uwsgi和django关联成功

    1 uwsgi --http :8001 --chdir /project/dazhahui/ --wsgi-file dazhahui/wsgi.py

    浏览器中访问  http://127.0.0.1:8001/ 或  curl:http://127.0.0.1:8001,如果看到“欢迎光临 我的jango”,一切正常yeah

    设置uwsgi自启动
    在/etc/init.d/下创建文件,内容如下:

     1 #! /bin/sh  
     2 # chkconfig: 2345 55 25  
     3 # Description: Startup script for uwsgi webserver on Debian. Place in /etc/init.d and  
     4 # run 'update-rc.d -f uwsgi defaults', or use the appropriate command on your  
     5 # distro. For CentOS/Redhat run: 'chkconfig --add uwsgi'  
     6 
     7 ### BEGIN INIT INFO  
     8 # Provides:          uwsgi  
     9 # Required-Start:    $all  
    10 # Required-Stop:      $all  
    11 # Default-Start:      2 3 4 5  
    12 # Default-Stop:     0 1 6  
    13 # Short-Description: starts the uwsgi web server  
    14 # Description:       starts uwsgi using start-stop-daemon  
    15 ### END INIT INFO  
    16 
    17 PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/project/dazhahui
    18 DESC="uwsgi daemon"
    19 NAME=uwsgi
    20 DAEMON=/usr/bin/uwsgi
    21 # CONFIGFILE=/etc/$NAME.ini
    22 CONFIGFILE=/project/dazhahui/$NAME.ini
    23 PIDFILE=/run/$NAME.pid
    24 SCRIPTNAME=/etc/init.d/$NAME
    25 
    26 set -e  
    27 [ -x "$DAEMON" ] || exit 0  
    28 
    29 do_start() {  
    30      $DAEMON $CONFIGFILE || echo -n "uwsgi already running"  
    31 }  
    32 
    33 do_stop() {  
    34      $DAEMON --stop $PIDFILE || echo -n "uwsgi not running"  
    35      rm -f $PIDFILE  
    36      echo "$DAEMON STOPED."  
    37 }  
    38 
    39 do_reload() {  
    40      $DAEMON --reload $PIDFILE || echo -n "uwsgi can't reload"  
    41 }  
    42 
    43 do_status() {  
    44      ps aux|grep $DAEMON  
    45 }  
    46 
    47 case "$1" in  
    48  status)  
    49      echo -en "Status $NAME: 
    "  
    50      do_status  
    51  ;;  
    52  start)  
    53      echo -en "Starting $NAME: 
    "  
    54      do_start  
    55  ;;  
    56  stop)  
    57      echo -en "Stopping $NAME: 
    "  
    58      do_stop  
    59  ;;  
    60  reload|graceful)  
    61      echo -en "Reloading $NAME: 
    "  
    62      do_reload  
    63  ;;  
    64  *)  
    65      echo "Usage: $SCRIPTNAME {status|start|stop|reload}" >&2  
    66      exit 3  
    67  ;;  
    68 esac  
    69 
    70 exit 0

    设置权限 chmod +x uwsgi
    添加开机启动
    chkconfig uwsgi on

    使用service进行管理

    service uwsgi {status|start|stop|reload}

    3、nginx安装与配置

    安装nginx

    使用yum安装nginx

    1 yum install nginx

    nginx常用命令

    service  nginx start

    service nginx stop

    service nginx restart

    service ngixn reload 重新nginx配置文件

    看到nginx启动成功日志,访问curl http://127.0.0.1/   如果看到nginx的欢迎页面Welcome to nginx,说明nginx安装成功

    设置nginx系统自启动

    root用户登录,在 /etc/init.d/目录下新建一个nginx脚本文件。使用vi命令

    vi /etc/init.d/nginx

      1 #!/bin/sh 
      2 # 
      3 # nginx - this script starts and stops the nginx daemon 
      4 # 
      5 # chkconfig:   - 85 15 
      6 # description: Nginx is an HTTP(S) server, HTTP(S) reverse  
      7 #               proxy and IMAP/POP3 proxy server 
      8 # processname: nginx 
      9 # config:      /etc/nginx/nginx.conf 
     10 # config:      /etc/sysconfig/nginx 
     11 # pidfile:     /var/run/nginx.pid 
     12 
     13 # Source function library. 
     14 . /etc/rc.d/init.d/functions 
     15 
     16 # Source networking configuration. 
     17 . /etc/sysconfig/network 
     18 
     19 # Check that networking is up. 
     20 [ "$NETWORKING" = "no" ] && exit 0 
     21 
     22 nginx="/usr/local/nginx/sbin/nginx" 
     23 prog=$(basename $nginx) 
     24 
     25 NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf" 
     26 
     27 [ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx 
     28 
     29 lockfile=/var/lock/subsys/nginx 
     30 
     31 start() { 
     32     [ -x $nginx ] || exit 5 
     33     [ -f $NGINX_CONF_FILE ] || exit 6 
     34     echo -n $"Starting $prog: " 
     35     daemon $nginx -c $NGINX_CONF_FILE 
     36     retval=$? 
     37     echo 
     38     [ $retval -eq 0 ] && touch $lockfile 
     39     return $retval 
     40 } 
     41 
     42 stop() { 
     43     echo -n $"Stopping $prog: " 
     44     killproc $prog -QUIT 
     45     retval=$? 
     46     echo 
     47     [ $retval -eq 0 ] && rm -f $lockfile 
     48     return $retval 
     49 killall -9 nginx 
     50 } 
     51 
     52 restart() { 
     53     configtest || return $? 
     54     stop 
     55     sleep 1 
     56     start 
     57 } 
     58 
     59 reload() { 
     60     configtest || return $? 
     61     echo -n $"Reloading $prog: " 
     62     killproc $nginx -HUP 
     63 RETVAL=$? 
     64     echo 
     65 } 
     66 
     67 force_reload() { 
     68     restart 
     69 } 
     70 
     71 configtest() { 
     72 $nginx -t -c $NGINX_CONF_FILE 
     73 } 
     74 
     75 rh_status() { 
     76     status $prog 
     77 } 
     78 
     79 rh_status_q() { 
     80     rh_status >/dev/null 2>&1 
     81 } 
     82 
     83 case "$1" in 
     84     start) 
     85         rh_status_q && exit 0 
     86     $1 
     87         ;; 
     88     stop) 
     89         rh_status_q || exit 0 
     90         $1 
     91         ;; 
     92     restart|configtest) 
     93         $1 
     94         ;; 
     95     reload) 
     96         rh_status_q || exit 7 
     97         $1 
     98         ;; 
     99     force-reload) 
    100         force_reload 
    101         ;; 
    102     status) 
    103         rh_status 
    104         ;; 
    105     condrestart|try-restart) 
    106         rh_status_q || exit 0 
    107             ;; 
    108     *)    
    109       echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}" 
    110         exit 2 
    111 
    112 esac

    2)nginx with uwsgi

    nginx.conf的目录下有uwsgi_params文件(/usr/local/nginx/conf/uwsgi_params),这个文件很重要,用于与nginx建立关联。

    在自己的工程目录下,建立如dazhahui.conf(/project/dazhahui/dazhahui.conf)的配置文件;复制nginx.conf里面全部的内容,全部写入dazhahui.conf中。
    然后按照下面写的,把dazhahui.conf配置文件中的server段部分全部替换掉。

     1   server {
     2         listen 80;
     3         server_name 192.168.1.103;
     4         charset utf-8;
     5         access_log  /project/dazhahui/logs/nginx_access.log;
     6         error_log   /project/dazhahui/logs/nginx_error.log;
     7 
     8         location / {
     9            uwsgi_connect_timeout 30;
    10            uwsgi_pass  unix:/project/dazhahui/dazhahui.sock;
    11            include     /usr/local/nginx/conf/uwsgi_params; 12 
    13       }
    14         location /media {
    15            alias /project/dazhahui/media;  
    16       }
    17 
    18         location /static {
    19            alias /project/dazhahui/static;   
    20       }
    21     }

    listen 80表示服务器监听80端口;

    server name 可以填写域名或者ip地址,我这里写上我的虚拟机分配的ip 192.168.1.103,在浏览器就用这个ip访问

    access_log和error_log指定nginx的访问日志和错误日志的存放路径

    location /表示项目的根目录,uwsgi_connect_timeout指定链接超时时间30秒,uwsgi_pass可以指定socket文件的绝对路径或者uwsgi监听的ip:端口

    location /media和location /static存放静态文件目录,其中location /static指明项目引用的静态文件目录,浏览器中显示的静态资源所在的根目录名;用户在浏览器中查看到的所有image、css或js资源都是处在http://127.0.0.1/static下.

    与Django settings.py配置文件静态文件目录一致

    STATIC_ROOT = os.path.join(BASE_DIR, "static/")

    每次启动uwsgi都要输一大串命令:uwsgi --http :8001 --chdir /project/dazhahui/ --wsgi-file dazhahui/wsgi.py,建议一个uWSGI配置文件,在自己的工程目录下创建uwsgi.ini

     1 [uwsgi]
     2 #
     3 Django-related settings
     4 #
     5 socket = /project/dazhahui/dazhahui.sock 
     6 chmod-socket=664
     7 
     8 # the base directory (project full path)
     9 chdir = /project/dazhahui/
    10 
    11 # Django's wsgi file
    12 wsgi-file = wsgi.py
    13 #module = dazhahui.wsgi # 新配置
    14 
    15 http=192.168.1.103:8001
    16 
    17 #
    18 process-related settings
    19 #
    20 # master
    21 master = true
    22 
    23 # maximum number of worker processes
    24 processes = 4
    25 
    26 threads = 2
    27 stats = 127.0.0.1:9191
    28 #uid = nobody
    29 #gid = nobody
    30 
    31 harakiri = 30
    32 # run process background and save log to daemonize
    33 daemonize = /project/dazhahui/logs/uwsgi.log
    34 pidfile = /var/run/uwsgi.pid 
    35 #plugins = python
    36 pythonpath = /usr/local/python2.7/lib/python2.7/site-packages/

    socket的字段值/project/dazhahui/dazhahui.sock必须要跟dazhahui.conf的uwsgi_pass的字段值完全一致,否则会出问题。

    chdir指定项目的根目录;

    wsgi-file指的是wsgi.py在自己工程中的相对路径,我的django工程的wsgi.py文件是在”/project/dazhahui/wsgi.py”,
    daemonize指定uWSGI日志的存储路径。

    列举下相关主要的文件路径:

    1 工程路径:                  /project/dazhahui
    2 工程静态文件路径:            /project/dazhahui/static
    3 wsgi.py的路径:             /project/dazhahui/wsgi.py
    4 uwsgi.ini的路径:           /project/dazhahui/uwsgi.ini
    5 uwsgi日志路径:             /project/dazhahui/logs/uwsgi.log
    6 destiny.conf的路径:        /project/dazhahui/dazhahui.conf
    7 uwsgi_params的路径:        /usr/local/nginx/conf/uwsgi_params
    8 nginx访问日志路径:          /project/dazhahui/logs/nginx_access.log
    9 nginx错误日志路径:          /project/dazhahui/logs/nginx_error.log

    可以发现,我几乎把所有有关工程的配置文件和日志文件都放在工程目录下了,方便后期维护与查错。 
    启动uWSGI

    1 uwsgi --ini /project/dazhahui/uwsgi.ini

    启动nginx
    在这之前,我们要先去nginx配置文件的根目录拷贝mime.types(/etc/nginx/conf/mime.types)到工程目录(/wwwroot/destiny/mime.types),和destiny.conf放在一起。
    否则用配置文件启动nginx会报错:

    1 nginx: [emerg] open() "/**/**/**/mime.types" failed (2: No such file or directory)

    当然,如果不想拷贝mime.types文件,也可以将配置文件中“include mime.types;”一项,改成绝对路径“include /etc/nginx/conf/mime.types;”
    如果nginx已经开启,先关闭nginx(service nginx stop或nginx -s stop),再执行以下命令:

    1 nginx -c /project/dazhahui/dazhahui.conf

    这里的-c 表示加载配置文件启动

    4、nginx+uwsgi+django原理解析

                           Nginx+uwsgi+django的结构图

    浏览器发起一个请求,nginx监听端口并接收请求,nginx已加载的dazhahui.conf配置文件通过uwsgi_pass配置项,找到对应的uwsgi暴露的IP和端口,通过uwsgi协议转发给uWsgi Web服务器,uwsgi服务器通过wsgi.py文件的wsgi-file项找到Django项目,

    Django接受并处理浏览器的请求,将处理结果返回给uWsgi Web服务器,uWsgi通知Nginx,Nginx把响应结果返回给浏览器。

      

                        Nginx+uWsgi+Django的通讯关系

     

    参考:

    https://blog.csdn.net/imphp/article/details/38232133

    https://www.jianshu.com/p/1c50b15b143a

    https://blog.csdn.net/ocean20/article/details/80496712

    https://www.cnblogs.com/saolv/p/6963314.html

    https://www.cnblogs.com/qingspace/p/6838747.html

    centos7防火墙https://www.linuxidc.com/Linux/2015-05/117473.htm

  • 相关阅读:
    python入门第十七天_生成器 迭代器
    python入门第十六天__列表生成式
    装饰器补充知识点_ @functools.wraps(func)
    函数练习题2
    函数编程练习题1
    迭代器
    生成器的send方法
    函数写生成器
    斐波那契数列
    生成器
  • 原文地址:https://www.cnblogs.com/taotaoblogs/p/9818321.html
Copyright © 2020-2023  润新知