Nginx+uwsgi+python2.7 on centos7

来自linux中国网wiki
跳到导航 跳到搜索

说在前面

centos7 本身自带 python2.7
安装nignx + mysql  (自己的rpm包),所以 重点是安装uwsgi
nignx 自己的yum 或者源码 (一定要不能有 --without-http_uwsgi_module)

安装基础开发包

yum groupinstall "Development tools"
yum install python-devel  zlib-devel bzip2-devel pcre-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel
# yum install  python-devel  zlib-devel   zlib-devel gcc    bzip2-devel pcre-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel openssl

mysql

#MySQL-python
yum install MySQL-python -y
#方法2
#wget -c https://pypi.python.org/packages/a5/e9/51b544da85a36a68debe7a7091f068d802fc515a3a202652828c73453cad/MySQL-python-1.2.5.zip#md5=654f75b302db6ed8dc5a898c625e030c
wget -c https://pypi.python.org/packages/a5/e9/51b544da85a36a68debe7a7091f068d802fc515a3a202652828c73453cad/MySQL-python-1.2.5.zip
unzip MySQL-python-1.2.5.zip  && cd MySQL-python-1.2.5  && python setup.py  install 

安装pip

修改pip源
mkdir  ~/.pip/
vim ~/.pip/pip.conf
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com

#也可在安装时直接使用pip install -i https://pypi.douban.com/simple package_name

pip安装方法1
##这个要先有py2.7 然后就成功  我用了这个  这个会自动安装setuptools等等
wget https://bootstrap.pypa.io/get-pip.py
python get-pip.py

pip安装方法2
yum -y install epel-release
sudo yum -y install python-pip
sudo yum clean all 

#这些3步是在一开始没有python2.7的centos6上执行,在centos7是不是必要的啦
find / -name "pip*"
/usr/local/python27/bin/pip
ln -s /usr/local/python27/bin/pip /usr/bin/pip

安装Django

# yum install MySQL-python -y  #在前面用了 pip 安装吗 
 pip install Django==1.8.18

#或者下载源码安装 
wget --no-check-certificate -c https://www.djangoproject.com/m/releases/1.8/Django-1.8.18.tar.gz
tar xvf Django-1.8.18.tar.gz  &&  cd Django-1.8.18  && python setup.py install

Installing django-admin.py script to /usr/local/python27/bin
 
测试 django 是否正常,运行:
python -c "import django; print(django.get_version())"
django-admin.py startproject  dj
cd dj
python2.7 manage.py runserver 0.0.0.0:8002
在浏览器内输入:http://127.0.0.1:8002,检查django是否运行正常。

直接配置为mysql 
 
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'django',                      # Or path to database file if using sqlite3.
        'USER': 'root',
        'PASSWORD': '',
        'HOST': 'localhost',                      # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
        'PORT': '3306',                      # Set to empty string for default.
    }
}

uwsgi

安装uwsgi

pip

pip install uwsgi # is good 这个安装没有 启动脚本,手工写一个就行了 
ln -s /usr/bin/uwsgi  /usr/sbin/uwsgi

yum install uwsgi # 注意了 这个有 些参数不能用 还是用这个吧 有启动脚本

vi test.py
def application(env, start_response):
        start_response('200 OK', [('Content-Type','text/html')])
        return "Hello World"
#执行如下代码 yum的不能执行这个脚本
uwsgi --http :8001 --wsgi-file test.py
打开浏览器  youip:8001

yum

yum install epel-release
yum install uwsgi

How to use Django with uWSG

uwsgi: https://pypi.python.org/pypi/uWSGI

官方之如何使用uWSGI 部署Django

uwsgi 参数详解


用uwsgi 运行django

使用 uwsgi 运行项目
 mkdir -p /data/logs/uwsgi/

uwsgi --http :8001 --chdir /path/to/project --home=/path/to/env --module project.wsgi
这样就可以跑了,--home 指定virtualenv 路径,如果没有可以去掉。project.wsgi 指的是 project/wsgi.py 文件

我的 django目录为 /data/hcmdb/  
cat /data/hcmdb/ht_cmdb/settings.py
WSGI_APPLICATION = 'ht_cmdb.wsgi.application'

所以运行脚本为 
uwsgi --http :8001 --chdir /data/hcmdb/  --module ht_cmdb.wsgi


uwsgi 配置文件  这个配置文件 有空要再完善些才行 参考原来xml文件 
cat /data/hcmdb/uwsgi.ini
[uwsgi]
socket =127.0.0.1:9005
chdir=/data/hcmdb/
module=ht_cmdb.wsgi:application
master=True
pidfile=/tmp/project-master.pid
vacuum=True
max-requests=5000
daemonize=/data/logs/uwsgi/yourproject.log


uwsgi --ini /data/hcmdb/uwsgi.ini
如果用yum的 应该是可以直接启动 ,但是相关的uwsgi命令是不一样的 还是pip吧

#dj目录此时为 /data/mycmdb/
ln -s /data/mycmdb/uwsgi.ini  /etc/

uwsgi相关命令
启动uwsgi:uwsgi --ini uwsgi.ini
停止uwsgi:uwsgi --stop uwsgi.pid
重新加载配置:uwsgi --reload uwsgi.pid

配置uwsgi 和nginx

cat cmdb.conf
# Django project  
server {
        listen  80;
        server_name testcmdb.com;
  charset utf-8;
        access_log /data/logs/nginx/dj.access.log;
#allow 113.108.232.32/28;
#deny all;
# 日志文件统一记录在uwsgi日志文件 /data/logs/uwsgi/django.com.access.log 
#        index Index.php index.php index.htm index.html;
# 图片不能用nginx缓存,不然会显示不出静态图片、css、js这些
        location ~ ^(.*)\/\.svn\/ {
            deny all;
        }
        location / {
            include    uwsgi_params;
            uwsgi_pass  127.0.0.1:9005;
            uwsgi_param UWSGI_CHDIR  /data/hcmdb/;  #django的代码放的路径
            uwsgi_param UWSGI_SCRIPT uwsgi;  #django的代码的resource_wsgi.py文件
        }
#css目录
 location /static {
        alias /data/hcmdb/static/;
    }

}

cat /data/hcmdb/uwsgi.py

#!/usr/bin/python
# -*- coding: utf8 -*-
# Author: 
# Date : 2017/02/21
# 说明:resource资源管理系统在生成环境的启动配置文件,使用nginx + uwsgi 进行访问 resource资源管理系统
import os
import django

os.environ['DJANGO_SETTINGS_MODULE'] = 'ht_cmdb.settings'  
import django.core.handlers.wsgi 

if django.VERSION < 1.7:
    from django.core.handlers.wsgi import WSGIHandler
    application = WSGIHandler()
else:
    from django.core.wsgi import get_wsgi_application
    application = get_wsgi_application()

uwsgi知识拓展

uwsgi参数说明

[uwsgi]
uid = nginx #使用nginx用户和组
gid = nginx
chdir = /usr/local/myapp #指定项目目录
module = myapp.wsgi #加载myapp/wsgi.py这个模块
master = true  #启动主进程。
processes = 2 #启动2个工作进程
listen = 120 #设置socket的监听队列大小(默认:100)
socket = /test/myapp.sock#指定socket文件
socket = 127.0.0.1:8080
pidfile = /var/run/uwsgi.pid #指定pid文件
vacuum = true #当服务器退出的时候自动删除unixsocket文件和pid文件。
enable-threads = true #允许用内嵌的语言启动线程。这将允许你在app程序中产生一个子线程
buffer-size = 32768 #设置用于uwsgi包解析的内部缓存区大小为64k。默认是4k。
  
reload-mercy = 8 #设置在平滑的重启(直到接收到的请求处理完才重启)一个工作子进程中,等待这个工作结束的最长秒数。这个配置会使在平滑地重启工作子进程中,如果工作进程结束时间超过了8秒就会被强行结束(忽略之前已经接收到的请求而直接结束)
max-requests = 5000 #为每个工作进程设置请求数的上限。当一个工作进程处理的请求数达到这个值,那么该工作进程就会被回收重用(重启)。你可以使用这个选项来默默地对抗内存泄漏
limit-as = 256 #通过使用POSIX/UNIX的setrlimit()函数来限制每个uWSGI进程的虚拟内存使用数。这个配置会限制uWSGI的进程占用虚拟内存不超过256M。如果虚拟内存已经达到256M,并继续申请虚拟内存则会使程序报内存错误,本次的http请求将返回500错误。
harakiri = 60 #一个请求花费的时间超过了这个harakiri超时时间,那么这个请求都会被丢弃,并且当前处理这个请求的工作进程会被回收再利用(即重启)
daemonize= /var/log/myapp_uwsgi.log # 使进程在后台运行,并将日志打到指定的日志文件或者udp服务器



[root@rpmbuild demosite]# cat /etc/uwsgi9090.ini 
[uwsgi]
socket = 127.0.0.1:9090
master = true         //主进程
vhost = true          //多站模式
no-site = true        //多站模式时不设置入口模块和文件
workers = 2           //子进程数
reload-mercy = 10     
vacuum = true         //退出、重启时清理文件
max-requests = 1000   
limit-as = 512
buffer-size = 30000
pidfile = /var/run/uwsgi9090.pid    
daemonize = /data/logs/uwsgi9090.log


安装Python包管理
#这个我没用呢 
easy_install 包 https://pypi.python.org/pypi/distribute
安装步骤:
cd ~
wget https://pypi.python.org/packages/source/d/distribute/distribute-0.6.49.tar.gz
tar xf distribute-0.6.49.tar.gz
cd distribute-0.6.49
python2.7 setup.py install
easy_install --version

wget -c https://pypi.python.org/packages/11/b6/abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/pip-9.0.1.tar.gz#md5=35f01da33009719497f01a4ba69d63c9

Pip安装和使用
https://wiki.linuxchina.net/index.php?title=Pip%E5%AE%89%E8%A3%85%E5%92%8C%E4%BD%BF%E7%94%A8

rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
yum install -y python-pip

为uwsgi配置多个站点

为了让多个站点共享一个uwsgi服务,必须把uwsgi运行成虚拟站点:去掉“-w myapp”加上”–vhost”:

uwsgi -s :9090 -M -p 4 -t 30 --limit-as 128 -R 10000 -d uwsgi.log --vhost 
然后必须配置virtualenv,virtualenv是Python的一个很有用的虚拟环境工具,这样安装:

apt-get install Python-setuptools  
easy_install virtualenv 
然后设置一个/多个app基准环境:

快速部署Python应用:Nginx+uWSGI配置详解
http://developer.51cto.com/art/201010/229615_all.htm

Nginx+uwsgi+python2.7 on centos6

uwsgi自启动

sysv

vi /etc/init.d/uwsgi

#!/bin/bash
uwsgi=/usr/bin/uwsgi
#api_conf=/etc/uwsgi/apps-enabled/project-api.ini
web_conf=/data/mycmdb/uwsgi.ini

case $1 in
    start)
        echo -n "Starting uWsgi"
        nohup $uwsgi -i $web_conf >/data/logs/uwsgi/cmdb.log 2>&1 &
        #nohup $uwsgi -i $api_conf >/var/log/uwsgi/project-web.log 2>&1 &
        echo " done"
    ;;

    stop)
        echo -n "Stopping uWsgi"
        killall -9 uwsgi
        echo " done"
    ;;

    restart)
        $0 stop
        $0 start
    ;;

    show)
        ps -ef|grep uwsgi
    ;;

    *)
        echo -n "Usage: $0 {start|restart|stop|show}"
    ;;

esac


chmod +x  /etc/init.d/uwsgi

脚本监控

#!/bin/bsh
# */2 * * * *  /root/check >/dev/null 2>&1 
#sysd 启动不成功 只能脚本监控了 
#if [ `netstat  -nlpt | grep 9005` ]
#netstat  -nlpt | grep 9005
if [ `netstat  -nlpt | grep 9005` ]
#if [ $? == 0 ]
then 
#:
echo "ok"
else
/etc/init.d/uwsgi start
#echo "no"
fi

安装 supervisor

安装 supervisor, 一个专门用来管理进程的工具,我们用它来管理 uwsgi 进程,如果用yum install uwsgi 这个应该用不上的

trouble shooting

1.
[root@localhost hosts]# /usr/sbin/uwsgi  /data/hcmdb/uwsgi.xml
unable to load configuration from /data/hcmdb/uwsgi.xml
改为ini配置文件格式 

2.
err log 
*** Operational MODE: single process ***
ImportError: No module named ht_cmdb.wsgi
unable to load app 0 (mountpoint='') (callable not found or import error)

#多了一个目录 结果是好了 不过样式全乱了呢 
uwsgi --http :8001 --chdir /data/hcmdb/hcmdb  --module ht_cmdb.wsgi

3.
In file included from plugins/python/pyutils.c:1:0:
plugins/python/uwsgi_python.h:2:20: 致命错误:Python.h:没有那个文件或目录
 #include <Python.h>
                    ^
In file included from plugins/python/python_plugin.c:1:0:
plugins/python/uwsgi_python.h:2:20: 致命错误:Python.h:没有那个文件或目录
 #include <Python.h>

plugins/python/uwsgi_python.h:2:20: 致命错误:Python.h:没有那个文件或目录
   #include <Python.h>
                     ^
  编译中断。
  ----------------------------------------
  Failed building wheel for uWSGI

sudo yum install epel-release
sudo yum install python-devel nginx


4.
uwsgi_python.h:2:20: 致命错误:Python.h:没有那个文件或目录 

yum install python-devel

5. A server error occurred. Please contact the administrator.

DisallowedHost: Invalid HTTP_HOST header: '192.168.50.209:8002'. You may need to add u'192.168.50.209' to ALLOWED_HOSTS.


改进

centos7 启动脚本路径  /usr/lib/systemd/system/nginx.service
相对于 [Nginx+uwsgi+python2.7 on centos6] uwsgi 配置文件从xml改为ini 因为官方 本身就是建议ini格式  by evan 20171014

如果要用到线上 还有两个地方要完善 第一 uwsgi 加上启动脚本 现在 是sysd的不行 那就暂时用sysv吧 第二 uwsgi的配置脚本还有等写得更加完善些 很多 项没写呢 例如uid gid

参考

Gunicorn+Nginx+Django+supervisor+Virtualenv

自强学堂的

如何配置nginx+uwsgi+django

How To Serve Django Applications with uWSGI and Nginx on CentOS 7

http://uwsgi-docs.readthedocs.io/en/latest/Install.html

http://uwsgi-docs-cn.readthedocs.io/zh_CN/latest/WSGIquickstart.html

how-to-serve-flask-applications-with-uwsgi-and-nginx-on-centos-7

Python部署web开发程序的几种方法

Django + Uwsgi + Nginx 实现生产环境部署

othre

[root@centos7 ~]# cat /usr/lib/systemd/system/uwsgi.service 
[Unit]
Description=uWSGI Emperor Service
After=syslog.target

[Service]
EnvironmentFile=-/etc/sysconfig/uwsgi
ExecStartPre=/bin/mkdir -p /run/uwsgi
ExecStartPre=/bin/chown uwsgi:uwsgi /run/uwsgi
ExecStart=/usr/sbin/uwsgi --ini /etc/uwsgi.ini
ExecReload=/bin/kill -HUP $MAINPID
KillSignal=SIGINT
Restart=always
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target








django-admin startproject dj

cd dj


解决了么?明显是没找到应用的路径.检查下PATH和PYTHONPATH
import sys
sys.path
将你的应用的路径添加到python path

>>> sys.path
['', '/usr/lib64/python27.zip', '/usr/lib64/python2.7', '/usr/lib64/python2.7/plat-linux2', '/usr/lib64/python2.7/lib-tk', '/usr/lib64/python2.7/lib-old', '/usr/lib64/python2.7/lib-dynload', '/usr/lib64/python2.7/site-packages', '/usr/lib/python2.7/site-packages']


添加到PYTHONPATH)。具体做法如下:
a. 假设所需要的python模块(或包)位于/home/lxc/software/program/python
b. 把/home/lxc/software/program/python添加到PYTHONPATH,语法与shell里面的PATH一样:
export PYTHONPATH=$PYTHONPATH:/home/lxc/software/program/py

export PYTHONPATH=$PYTHONPATH:/data/mycmdb/

vi /etc/profile
在最后添加 export PYTHONPATH=/usr/lib/python2.5/site-packages/