设为首页 收藏本站
查看: 965|回复: 0

[经验分享] Nginx + uWSGI + Python + Django部署实例

[复制链接]

尚未签到

发表于 2018-8-5 08:07:07 | 显示全部楼层 |阅读模式
  
  Nginx
  Nginx 是一个高性能的 Web 和反向代理服务器, 它具有有很多非常优越的特性:
  作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 Nginx 尤其受到虚拟主机提供商的欢迎。能够支持高达 50,000 个并发连接数的响应,感谢 Nginx 为我们选择了 epoll and kqueue 作为开发模型.
  作为负载均衡服务器:Nginx 既可以在内部直接支持 Rails 和 PHP,也可以支持作为 HTTP代理服务器 对外进行服务。Nginx 用 C 编写, 不论是系统资源开销还是 CPU 使用效率都比 Perlbal 要好的多。
  作为邮件代理服务器: Nginx 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器),Last.fm 描述了成功并且美妙的使用经验。
  Nginx 安装非常的简单,配置文件 非常简洁(还能够支持perl语法),Bugs非常少的服务器: Nginx 启动特别容易,并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够在 不间断服务的情况下进行软件版本的升级。
  uWSGI:

  •   APP(应用程序),就是开发者写的应用程序,例如django,bottle这些。记录怎么处理客户端发来的请求的逻辑部分。
  •   WSGI,是一个协议,Python用于Web开发的协议
  •   uWSGI,是一个程序,充当Web服务器或中间件。
  •   如果架构是Nginx+uWSGI+APP,uWSGI是一个中间件
  •   如果架构是uWSGI+APP,uWSGI是一个服务器
  •   uwsgi,是uWSGI程序实现的一个自有的协议。
  Web协议出现顺序:
  CGI -> FCGI -> WSGI -> uwsgi

  •   CGI,最早的协议
  •   FCGI,比CGI快
  •   WSGI,Python专用的协议
  •   uwsgi,比FCGI和WSGI都快,是uWSGI项目自有的协议,主要特征是采用二进制来存储数据,之前的协议都是使用字符串,所以在存储空间和解析速度上,都优于字符串型协议.
  Django:
  
  Django(维基百科) Django是一个开放源代码的Web应用框架,由Python写成。采用了MVC的软件设计模式,即模型M,视图V和控制器C。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的。并于2005年7月在BSD许可证下发布。这套框架是以比利时的吉普赛爵士吉他手Django Reinhardt来命名的。
  Django的主要目标是使得开发复杂的、数据库驱动的网站变得简单。Django注重组件的重用性和“可插拔性”,敏捷开发和DRY法则(Don't Repeat Yourself)。在Django中Python被普遍使用,甚至包括配置文件和数据模型。
  Django框架的核心包括:一个 面向对象 的映射器,用作数据模型(以Python类的形式定义)和关联性数据库间的媒介;一个基于正则表达式的URL分发器;一个视图系统,用于处理请求;以及一个模板系统。
  核心框架中还包括:
  l 一个轻量级的、独立的Web服务器,用于开发和测试。
  l 一个表单序列化及验证系统,用于HTML表单和适于数据库存储的数据之间的转换。
  l 一个缓存框架,并有几种缓存方式可供选择。
  l 中间件支持,允许对请求处理的各个阶段进行干涉。
  l 内置的分发系统允许应用程序中的组件采用预定义的信号进行相互间的通信。
  l 一个序列化系统,能够生成或读取采用XML或JSON表示的Django模型实例。
  l 一个用于扩展模板引擎的能力的系统。
  Django主要特点

  • Django“自备军需”(Batteries-Included)
  Django基于“自备军需”的理念,您不必使用单独的库来实现常见功能,例如身份验证,URL路由,模板系统,对象关系映射器(ORM)和数据库模型迁移。 如果您正在使用或曾经用过Flask,您一定注意到了它需要调用其他库,如Flask-Login来执行用户身份验证。 Django不是这样。

  •   自由的API
  使用Django,很容易根据您的模型生成Python API。 只需一个简单的命令,不需要额外的编码就足以开始生成API了。

  •   独特的管理页面
  即使在网站完全构建之前,您也可以从外部贡献者处获取有关信息。 这就是Django的力量。 该框架使您能够快速轻松地从应用模型生成管理站点。

  •   代码设计
  与大多数 Web 框架相反,Django 通过使用称为 app 的东西,更容易地将新功能添加到产品中。 因此,开发者可以感受到 Django 鼓励大家编写模块化的代码。

  •   Django对ORM的完善支持
  Django的对象关系映射 (ORM) 对数据库进行了完善的支持。所以,它用于查询数据库所需的数据时,没有处理结构化查询语言(SQL)的麻烦。 与许多通过SQL直接在数据库上工作的Python框架不同,Django开发人员有一个独特的选择来操纵相应的Python的Model对象。 Django对于PostgreSQL,MySQL,SQLite和Oracle等数据库都能做到开箱即用。

  •   强大的内置模板系统
  基于继承系统,Django 的模板允许开发人员通过非常少量的前端代码构建整个动态网站。这得益于使用其他上下文特定元素替换模板的某些元素的选项。 想象一下,你知道你网站的每个页面都会有一个页眉和一个页脚。 现在,您首先需要在网站的基本模板中编写代码。 然后,您可以从应用程序的其他部分动态地更改这两个内容之间的组件。

  •   简单可读的网址
  很难正确阅读在PHP os ASP中开发的URL? 使用 Django,您可以创建简单易读的 URL,这对人和搜索引擎都有好处。 您也可以使用其他框架创建可读 URL,但没有一个与 Django 一样容易进行 URL 构造
  Django是一个Python编写的,高级的,MVC风格的开源库。 Django也被称为“完美主义者的最终框架”,它最初是为新闻网站设计的,因为它允许开发人员编写数据库驱动的Web应用程序,而无需从头开始编码。
  除了更快完成常见的Web开发任务,Django还可以保持设计干净且实用。 Django是Python Web开发新人的最佳选择,因为官方文档和教程是几个(同类)软件开发框架中最好的。
  技术市场充斥着一系列网络框架,但Django在最受欢迎的服务器端Web框架里处于顶峰位置。设计Django背后的座右铭很简单:避免重复。 Django是用Python编写的,因此其减少了太多中间层代码并突出提高了效率。Django可以支持云平台,使其成为Web开发中更受欢迎的选择。
  部署 Nginx + uWSGI + Python + Django
  nginx版本:1.5.9
  Django版本:1.4.9
  uwsgi版本:2.0.4
  Python版本:2.6.6
  安装,Django,nginx,uwsgi,MySQL,采用编译安装,便于维护
[root@kurol ~]# mkdir -p /data/logs  
[root@kurol ~]# yum -y install gcc cc gcc-c++
  
[root@kurol ~]# tar -zxvf pcre-8.34.tar.gz
  
[root@kurol ~]# cd pcre-8.34
  
[root@kurol pcre-8.34]# ./configure
  
[root@kurol pcre-8.34]# make && make install
  
[root@kurol pcre-8.34]# cd ..
  
[root@kurol ~]# wget http://nginx.org/download/nginx-1.5.9.tar.gz
  
[root@kurol ~]# tar -zxvf nginx-1.5.9.tar.gz
  
[root@kurol ~]# cd nginx-1.5.9
  
[root@kurol nginx-1.5.9]# ./configure  --prefix=/usr/local/nginx --with-http_stub_status_module --without-http_gzip_module
  
[root@kurol nginx-1.5.9]# make && make install
  
[root@kurol nginx-1.5.9]# cd ..
  
[root@kurol ~]# yum -y install MySQL-python mysql mysql-devel mysql-server
  
[root@kurol ~]# yum -y install libxml2 python-devel
  
[root@kurol ~]# wget http://projects.unbit.it/downloads/uwsgi-2.0.4.tar.gz
  
[root@kurol ~]# tar -zxvf uwsgi-2.0.4.tar.gz
  
[root@kurol ~]# cd uwsgi-2.0.4
  
[root@kurol uwsgi-2.0.4]# make
  
[root@kurol uwsgi-2.0.4]# cp uwsgi /usr/bin
  
[root@kurol uwsgi-2.0.4]# cd ..
  
[root@kurol ~]# wget https://www.djangoproject.com/m/releases/1.4/Django-1.4.9.tar.gz --no-check-certificate
  
[root@kurol ~]# tar -zvxf Django-1.4.9.tar.gz
  
[root@kurol ~]# cd Django-1.4.9
  
[root@kurol Django-1.4.9]# python setup.py install
  配置Nginx.
【/usr/local/nginx/conf/nginx.conf】  
server{
  
    listen 80;
  
    server_name www.mykurol.com;
  

  
    location / {
  
        uwsgi_pass 127.0.0.1:9001;
  
        include uwsgi_params;
  
        uwsgi_param UWSGI_CHDIR /data/www/board;
  
        uwsgi_param UWSGI_SCRIPT django_wsgi;
  
        access_log off;
  
}
  

  
    location ~* ^.+\.(mpg|avi|mp3|swf|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|txt|tar|mid|midi|wav|rtf|mpeg)$ {
  
        root /data/www/board/static;
  
        access_log off;
  
    }
  
}
  配置uwsgi.
【/usr/local/nginx/conf/uwsgi.ini】  
[uwsgi]
  
socket = 0.0.0.0:9001
  
master = true
  
pidfile = /usr/local/nginx/uwsgi.pid
  
processes = 8
  
chdir = /data/www/board
  
pythonpath = /data/www
  
profiler = true
  
memory-report = true
  
enable-threads = true
  
logdate = true
  
limit-as = 6048
  
daemonize = /data/logs/django.log
  启动项目board
[root@kurol logs]# cd /data/www/  
[root@kurol www]# django-admin.py startproject board
  
[root@kurol www]# cd board/
  
[root@kurol board]# vim django_wsgi.py
  
#!/usr/bin python
  
# coding: utf-8
  
import os
  
import sys
  
reload(sys)
  
sys.setdefaultencoding('utf8')
  
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "board.settings")
  
from django.core.handlers.wsgi import WSGIHandler
  
application = WSGIHandler()
  
[root@kurol www]# ls
  
board
  
[root@kurol www]# tree
  
.
  
`-- board
  
    |-- board
  
    |   |-- __init__.py
  
    |   |-- settings.py
  
    |   |-- urls.py
  
    |   `-- wsgi.py
  
    `-- manage.py
  
2 directories, 5 files
  启动uwsgi和nginx服务.,其中uwsgi使用自定义位置配置文件
[root@kurol ~]# /usr/bin/uwsgi --ini /usr/local/nginx/conf/uwsgi.ini  
/usr/bin/uwsgi: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory
  
[root@kurol ~]# ln -s /usr/local/lib/libpcre.so.1 /lib64
  
[root@kurol ~]# /usr/bin/uwsgi --ini /usr/local/nginx/conf/uwsgi.ini
  
[root@kurol ~]# /usr/local/nginx/sbin/nginx
  
[root@kurol ~]# netstat -ltunp
  
Active Internet connections (only servers)
  
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name
  
tcp        0      0 0.0.0.0:9001                0.0.0.0:*                   LISTEN      15243/uwsgi
  
tcp        0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN      15423/nginx
  
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      868/sshd
  
tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN      957/master
  方便服务管理,创建nginx和uwsgi启动脚本.
  nginx:
[root@kurol board]# touch /etc/init.d/nginx  
[root@kurol board]# chmod 775 /etc/init.d/nginx
  
[root@kurol board]# vim /etc/init.d/nginx
  
#!/bin/sh
  
       #
  
       set -e
  
       PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
  
       DESC="nginx daemon"
  
       NAME=nginx
  
       DAEMON=/usr/local/nginx/sbin/nginx
  
       CONFIGFILE=/usr/local/nginx/conf/nginx.conf
  
       PIDFILE=/usr/local/nginx/logs/nginx.pid
  
       SCRIPTNAME=/etc/init.d/nginx
  

  
       # If the daemon file is not found, terminate the script.
  
       test -x $DAEMON || exit 0
  
       d_start(){
  
           $DAEMON -c $CONFIGFILE || echo -n " already running"
  
       }
  
       d_stop(){
  
           kill -QUIT `cat $PIDFILE` || echo -n " no running"
  
       }
  
       d_reload(){
  
           kill -HUP `cat $PIDFILE` || echo -n " could not reload"
  
       }
  
       case "$1" in
  
           start)
  
               echo -n "Starting $DESC: $NAME"
  
               d_start
  
               echo "."
  
               ;;
  
           stop)
  
               echo -n "Stopping $DESC: $NAME"
  
               d_stop
  
               echo "."
  
               ;;
  
           reload)
  
               echo -n "Reloading $DESC configuration..."
  
               d_reload
  
               echo "Reloaded."
  
               ;;
  
           restart)
  
               echo -n "Restarting $DESC: $NAME"
  
               d_stop
  
               # Sleep for two seconds before starting again, this should give the nginx daemon some time to perform a graceful stop
  
               sleep 2
  
               d_start
  
               echo "."
  
               ;;
  
           *)
  
               echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload)" >&2
  
               exit 3
  
               ;;
  
       esac
  
       exit 0
  uwsgi:
[root@kurol board]# touch /etc/init.d/uwsgi  
[root@kurol board]# chmod 775 /etc/init.d/uwsgi
  
[root@kurol board]# vim /etc/init.d/uwsgi
  
#!/bin/sh
  
       #
  
       set -e
  
       PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
  
       DESC="uwsgi daemon"
  
       NAME=uwsgi
  
       DAEMON=/usr/bin/uwsgi
  
       CONFIGFILE=/usr/local/nginx/conf/uwsgi.ini
  
       PIDFILE=/usr/local/nginx/uwsgi.pid
  
       SCRIPTNAME=/etc/init.d/uwsgi
  

  
       # If the daemon file is not found, terminate the script.
  
       test -x $DAEMON || exit 0
  
       d_start(){
  
           $DAEMON --ini $CONFIGFILE || echo -n " already running"
  
       }
  
       d_stop(){
  
           kill -QUIT `cat $PIDFILE` || echo -n " no running"
  
       }
  
       d_reload(){
  
           kill -HUP `cat $PIDFILE` || echo -n " could not reload"
  
       }
  
       case "$1" in
  
           start)
  
               echo -n "Starting $DESC: $NAME"
  
               d_start
  
               echo "."
  
               ;;
  
           stop)
  
               echo -n "Stopping $DESC: $NAME"
  
               d_stop
  
               echo "."
  
               ;;
  
           reload)
  
               echo -n "Reloading $DESC configuration..."
  
               d_reload
  
               echo "Reloaded."
  
               ;;
  
           restart)
  
               echo -n "Restarting $DESC: $NAME"
  
               d_stop
  
               # Sleep for two seconds before starting again, this should give the nginx daemon some time to perform a graceful stop
  
               sleep 2
  
               d_start
  
               echo "."
  
               ;;
  
           *)
  
               echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload)" >&2
  
               exit 3
  
               ;;
  
       esac
  
       exit 0
  创建数据模型:
[root@kurol board]# cd /data/www/board/webserver/  
[root@kurol webserver]# vim models.py
from django.db import models  
class webserver(models.Model):
  
username = models.CharField('用户名',max_length=30)
  
password = models.CharField('密码',max_length=30)
  
email = models.EmailField('电子邮件',blank=True)
  
desc = models.TextField('描述',max_length=500,blank=True)
  
class Meta:
  
        db_table = u'board_webserver'
  
def __unicode__(self):
  
return self.username
[root@kurol webserver]# vim /data/www/board/board/settings.py  
DATABASES = {
  
    'default': {
  
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
  
        'NAME': 'OBServer',                      # Or path to database file if using sqlite3.
  
        'USER': 'root',                      # Not used with sqlite3.
  
        'PASSWORD': '******',                  # Not used with sqlite3.
  
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
  
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
  
    }
  
}
  
INSTALLED_APPS = (
  
    'django.contrib.auth',
  
    'django.contrib.contenttypes',
  
    'django.contrib.sessions',
  
    'django.contrib.sites',
  
    'django.contrib.messages',
  
    'django.contrib.staticfiles',
  
    'webserver',
  
    # Uncomment the next line to enable the admin:
  
    # 'django.contrib.admin',
  
    # Uncomment the next line to enable admin documentation:
  
    # 'django.contrib.admindocs',
  
)
[root@kurol board]# export LC_ALL=en_US.UTF-8  
[root@kurol board]# python manage.py sqlall webserver    #检查sql语句
  
BEGIN;
  
CREATE TABLE `board_webserver` (
  
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
  
    `username` varchar(30) NOT NULL,
  
    `password` varchar(30) NOT NULL,
  
    `email` varchar(75) NOT NULL,
  
    `desc` longtext NOT NULL
  
)
  
;
  
COMMIT;
  SQL语句没问题,继续执行
  #在Django 1.9及未来的版本种使用migrate代替syscdb.
  syncdb会创建在setting.py下配置的INSTALL_APPS下的所有app,创建其对应的数据表到指定的数据库,但只创建不存在的表比如上面
        'django.contrib.auth',  
    'django.contrib.contenttypes',
  
    'django.contrib.sessions',
  
    'django.contrib.sites',
  
    'django.contrib.messages',
  
    'django.contrib.staticfiles',
  
    'webserver',
  都会创建一个对应的表。
[root@kurol board]# python manage.py syncdb  
Creating tables ...
  
Creating table board_webserver
  
Installing custom SQL ...
  
Installing indexes ...
  
Installed 0 object(s) from 0 fixture(s)
  报错问题
  [root@kurol board]# python manage.py syncdb
  TypeError: decode() argument 1 must be string, not None
  解决:
  将export LC_ALL=en_US.UTF-8写入到profile或者.bashrc中即可。
  [root@kurol board]# export LC_ALL=en_US.UTF-8
  生成应用,修改urls指定页面,添加views视图
[root@kurol webserver]# cd /data/www/board/  
[root@kurol board]# python manage.py startapp webserver
  
[root@kurol board]# vim board/urls.py
  
from django.conf.urls import patterns, include, url
  
urlpatterns = patterns('',
  
    (r'^$', 'board.views.index'),
  
    (r'^board/', include('webserver.urls')),
  
)
  
[root@kurol board]# cd webserver/
  
[root@kurol webserver]# touch urls.py
  
[root@kurol webserver]# vim urls.py
  
from  django.conf.urls.defaults import *
  
urlpatterns = patterns('',
  
    (r'^$', 'webserver.views.index'),
  
    (r'^random_number/$', 'webserver.views.random_number'),
  
)
  
[root@kurol webserver]# cd ..
  
[root@kurol board]# cd board
  
[root@kurol board]# vim views.py
  
# Create your views here.
  
from django.http import HttpResponse
  
def index(request):
  
    html = """<html>
  
                <title>Main</title>
  
                <body>
  
                    <h1>Main Page</h1><hr>
  
                </body>
  
              </html>"""
  
    return HttpResponse(html)
  浏览器打开,显示Main Page就是成功部署了。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-546738-1-1.html 上篇帖子: Python32 Socket Server 下篇帖子: Python多线程编程实例
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表