nginx+uwsgi+flask

为什么要使用nginx+uwsgi+flask

因为标准python只能是单线程,无法并发,而uwsgi/gunicorn通过多进程池达成了并发。

安装uwsgi

安装uwsgi之前先安装python-devel(centos下)

使用pip install uwsgi,即可安装uwsgi

使用命令find / -name uwsgi可以查看uwsgi的地点

使用uwsgi --version可以查看uwsgi的版本

2.0.17.1

uwsgi有多种配置可用:

1.ini

2.xml

3.json

4.yaml

测试uwsgi

首先写一个hello world的wsgi应用,并保存在"server.py"文件中:

def application(environ, start_response):

    status = '200 OK'

    output = 'Hello World!'

    response_headers = [('Content-type', 'text/plain'),

    ('Content-Length', str(len(output)))]

    start_response(status, response_headers)

    return [output]

然后在uwsgi中运行它,执行命令:

uwsgi --http :9090 --wsgi-file server.py

然后打开浏览器,访问"http://localhost:9090",就可以看到'hello world!'

或者使用curl -v 

tip:uwsig可以配置参数

(使用pip install uwsgi可能会报错:

     #include <Python.h>

                        ^

    compilation terminated.

解决方法:

找不到python.h,这是因为没有安装python-dev

使用yum search python | grep devel

找到可用版本:

python-devel.x86_64 : The libraries and header files needed for Python

                                   : development

执行yum install python-devel.x86_64进行安装

安装成功后,python.h出现了

再次pip install uwsgi即可

如果pip安装uwsgi后没有找到uwsgi(使用不了),使用指令:

find / -name uwsgi

如果只有一个/usr/local/python3/bin/uwsgi

可以把/usr/local/python3/bin/uwsgi复制到/usr/local/bin/uwsgi

(还有一种方法是,使用pip下载完uwsgi然后再使用yum下载uwsgi,使用find / -name uwsgi,将yum的uwsgi软连接到pip的uwsgi,之后直接使用uwsgi就可以使用)

删除uwsgi的方法:

如果是yum删除uwsgi的话就是:yum remove uwsgi

如果是pip删除uwsgi的话就是:pip uninstall uwsgi

然后再使用命令fins / -name uwsgi,将找到的uwsgi删除

安装nginx(centos)

1.检查并安装所需的依赖软件

    1.gcc: nginx编译依赖gcc环境

centos 安装命令:yum install gcc-c++

    2.pcre: (perl compatible regular expressions)是一个perl库,包括perl兼容的正则表达式库。nginx的http模块使用pcre来解析正则表达式。

centos 安装命令:yum install -y pcre pcre-devel

    3.zlib: 该库提供了很多中压缩和解压缩的方式,nginx使用zlib对http包的内容进行gzip。

centos 安装命令:yum install -y zlib zlib-devel

    4.openssl: 一个强大安全套接字层密码库,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测是或其它目的的使用。nginx不仅支持http协议,还支持https(即在ssl协议上传输的http)

centos 安装命令:yum install -y openssl openssl-devel

2.下载nginx源码包

    下载命令:wget http://nginx.org/download/nginx-1.12.0.tar.gz

    可根据不同版本下载不同的nginx

3.解压源码包

    1.解压:tar -zxvf nginx-1.12.0.tar.gz

    2.进入解压后的文件夹:cd nginx-1.12.0

4.配置编译参数命令:(可以使用./configure --help查询详细参数)

安装之前需要手动创建上面指定的nginx文件即/var/temp、/var/temp/nginx、/var/run/nginx文件夹,否则会启动时报错

5.编译并安装

先使用./configure

    然后进行编译安装:

1.make

2.make install

6.查找安装路径并将安装路径添加到环境变量:

1.whereis nginx(查出nginx的安装路径)

2.vim ~/.bashrc加上一句export PATH=$PATH:/usr/local/nginx/sbin/

    (路径即为whereis 找到的路径)

3.source ~/.bashrc(保存退出)

安装nginx(ubuntu)

1.检查并安装所需的依赖软件

    1.安装gcc g++的依赖库

        sudo apt-get install gcc

        sudo apt-get install build-essential -y

        sudo apt-get install libtool

    2.安装pcre依赖库

        sudo apt-get update

        sudo apt-get install libpcre3 libpcre3-dev

        apt-get install libncurses5-dev libncursesw5-dev libreadline6-dev -y

        apt-get install libdb5.3-dev libgdbm-dev libsqlite3-dev libssl-dev -y

    3.安装zlib依赖库

        sudo apt-get install zliblg-dev

        sudo apt-get install libbz2-dev libexpat1-dev liblzma-dev zlib1g-dev -y

    4.安装ssl依赖库

         sudo apt-get install openssl

2.下载nginx源码包

下载命令:wget http://nginx.org/download/nginx-1.13.6.tar.gz

3.解压源码包

    tar -zxvf nginx-1.13.6.tar.gz

    cd nginx-1.13.6

4.编译

    ./configure --prefix=/usr/local/nginx

    make

    sudo make install

5.开启nginx

    sudo /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

    注意:-c指定配置文件的路径,不加的话,nginx会自动加载默认路径的配置文件,可以通过-h查看帮助命令。

6.查找安装路径并将安装路径添加到环境变量:

1.whereis nginx(查出nginx的安装路径)

2.vim ~/.bashrc加上一句export PATH=$PATH:/usr/local/nginx/sbin/

    (路径即为whereis 找到的路径)

3.source ~/.bashrc(保存退出)

ps:

然后就可以直接使用命令:

启动/停止nginx

nginx

nginx -s stop

nginx -s quit

nginx -s reload

nginx -s quit:此方法停止步骤是待nginx处理任务完毕后进行停止。

nginx -s stop:此方法相当于先查出nginx进程id再使用kill命令强制杀掉进程。

查看nginx是否开启:netstat -nutlp

如果出现了一个名为nginx:master监听80端口就证明已经开启

或者使用ps aux | grep nginx

如果出现nginx:worker process & nginx: master process /usr/local/nginx/sbin/nginx

实现nginx开机自启动

1、在系统服务目录里创建nginx.service文件

vim /lib/systemd/system/nginx.service

添加内容入下:

[Unit]

Description=nginx

After=network.target


[Service]

Type=forking

ExecStart=/usr/local/nginx/sbin/nginx

ExecReload=/usr/local/nginx/sbin/nginx -s reload

ExecStop=/usr/local/nginx/sbin/nginx -s quit

PrivateTmp=true


[Install]

WantedBy=multi-user.target

tip:添加文件的说明

[Unit]:服务的说明

Description:描述服务

After:描述服务类别

[Service]:服务运行参数的设置

Type:forking    是后台运行的形式

ExesStart为服务的具体运行命令

ExesReload  为重启命令

ExesStop  为停止命令

Private Tmp = True  表示给服务分配独立的临时空间

注意:

[Service]    的启动、重启、停止命令全部要求使用绝对路径

[Install]    运行级别下服务安装的相关设置,可以设置成多用户,即系统运行级别为3

保存退出

2、设置开机启动

systemctl enable nginx.service

3、其他命令

启动nginx服务

systemctl start nginx.service

查看服务当前状态

systemctl status nginx.service

重新启动服务

systemctl restart nginx.service

查看所有已经启动的服务

systemctl list-units --type=service

停止开机自启动

systemctl disable nginx.service

nginx启动或者重启失败的原因

1.因为配置文件出错:

可以使用nginx-t方法查看配置文件出错的地方

也可以用过查看nginx日志文件定位到nginx重启失败的原因,nginx日志文件的路径一般在:/var/log/nginx下

2.端口被占用

可以通过查看电脑端口的使用情况                                                  

netstat -aon | findstr ":80"                  windows下

firewall-cmd --query-port=80/tcp     linux下

ps:如果使用wget下载的nginx,如果想要删除直接使用命令:

find / -name nginx

将列出的都删除掉

部署flask项目

当安装好uwsgi & nginx以后就可以使用它们部署flask

1.首先在项目中新建一个配置文件uwsgiconfig.ini,用来设置uwsgi相关的参数:

[uwsgi]

socket = 127.0.0.1:5051

pythonpath = /home/zt/loan_app_indonesia

module = manage

wsgi-file = /home/zt/loan_app_indonesia/manage.py

callable = app

processes = 4

threads = 2

daemonize = /home/zt/loan_app_indonesia/server.log

tip:配置文件中的各字段的意义

socket:指出了一个套接字,相当于为外界留出一个uwsgi服务器的接口

pythonpath:指出项目的目录

module:指出项目启动模块

wsgi-file:指出了真正的脚本文件名

callable:指出的是具体执行.run方法的那个实体的名字,一般而言都是app = Flask(__name__)

processes:指出启动uwsgi服务器之后,服务器会打开几个并行的进程

threads:指出每个进程会开几条线程来等待处理请求

(注意:processes & threads的配置应该合理,太小会使得处理性能不好而太大则会给服务器本身带来很大困扰)

daemonize:表示把uwsgi服务器作为后台进程启动,其值指向一个文件表明后台中的所有输出都重定向到这个日志中。

ps:关于socket和http的差别。从概念上来说,socket本身不是协议,而是一种具体的tcp/ip实现方式,而http是一种协议且基于tcp/ip。具体到配置,如果只配了socket = 127.0.0.1:5051,通过浏览器

或者其他http手段是无法访问成功的。而在uwsgi的日志里面会提示请求包的长度超过了最大固定长度。另一方面,如果配置的是http = 127.0.0.1:5051的话,那么就可以通过一般的http手段来访问目标。但这样会引起nginx无法正常工作。正确的做法是:如果有nginx在uwsgi之前作为代理的话应该配socket,如果想让请求直接甩给uwsgi的话就要配http。

使用命令uwsgi uwsgiconfig.ini

[uWSGI] getting INI configuration from uwsgiconfig.ini

然后使用netstat -nutlp查看

tcp        0      0 127.0.0.1:5051          0.0.0.0:*               LISTEN      70711/uwsgi

也可以使用ps aux | grep uwsgi查看

root      70711  0.0  1.3 355740 52280 ?        Sl   15:51   0:01 uwsgi uwsgiconfig.ini

root      70713  0.0  1.2 355484 49028 ?        Sl   15:51   0:00 uwsgi uwsgiconfig.ini

root      70714  0.0  1.2 355476 48820 ?        Sl   15:51   0:00 uwsgi uwsgiconfig.ini

root      70716  0.0  1.2 356176 49516 ?        Sl   15:51   0:00 uwsgi uwsgiconfig.ini

root      72114  0.0  0.0 112704   972 pts/7    S+   16:18   0:00 grep --color=auto uwsgi

如果配置了daemonize的话可以查看日志

tip:使用killall -9 uwsgi可以终止守护进程

(注意:在centos下如果没有killall命令就用yum install psmisc)

2.配置nginx参数

使用find / -name nginx.conf

/usr/local/bin/nginx-1.12.0/conf/nginx.conf

/usr/local/nginx/conf/nginx.conf

然后vim /usr/local/nginx/conf/nginx.conf修改配置

    server {

listen7777;

server_namelocalhost;

access_log /home/zt/loan_app_indonesia/access.log;

error_log /home/zt/loan_app_indonesia/error.log;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {

           # root   html;

            include uwsgi_params;

uwsgi_pass 127.0.0.1:5051;

uwsgi_param UWSGI_CHDIR /home/zt/loan_app_indonesia;

uwsgi_param UWSGI_SCRIPT manage:app;

            #index  index.html index.htm;

        }

配置的解释:

listen//web访问的端口

server_name  //服务器名

access_log //服务器接受的请求日志

error_log//错误日志(nginx部分中发生的错误)

include  uwsgi_params  //导入uwsgi配置

uwsgi_pass  //需要和uwsgi配置文件中的socket地址相同

uwsgi_param UWSGI_CHDIR //项目根目录

uwsgi_param UWSGI_SCRIPT//启动项目的主程序

这样配置完,当外部有一个7777端口的请求发送到本机后,先让nginx处理。nginx进行一些处理之后转发给配置的uwsgi_pass地址,传给uwsgi处理。再由uwsgi来调用项目中的代码处理请求返回。

(如果仅仅配置了一个http而没有配置socket的话,就会导致虽然启动顺利,但是发请求给7777端口超时)

注意:如果uwsgi直接通过http方式对外提供服务,那么nginx中需要配置proxy_pass,指出http服务具体套接字,从而实现请求的转发。而如果将uwsgi配置为socket,通过socket对外提供服务(由于socket不涉及具体的协议,外部没法直接通过uwsgi端口访问服务也更加安全一点。比如可以在nginx中配置一些url的拒接防止sql注入之类等等...),那么nginx配置就应该得是uwsgi_pass来实现请求的转发。proxy_pass配置的时候写http://,即表示是走http协议的;uwsgi_pass的时候未指出协议,表示走socket。

配置nginx.conf完成后重启nginx

然后使用netstat -nutlp查看

tcp        0      0 0.0.0.0:7777            0.0.0.0:*               LISTEN      71733/nginx: master

最后访问项目

ps:在一个nginx服务器上配置多个访问站点的方法

当客户需要使用一个nginx服务器,访问多个不同的站点,例如使用:

http://localhost/a

能够访问

http://www.baidu.com

使用:

http://localhost/b

能够访问

http://www.163.com

需要这样操作:

server{

        location /a/ {

            proxy_pass http://www.baidu.com/;

        }

        location /b/{

            proxy_pass http://www.163.com/;

        }

    }

需要注意的是:"/a/"、"/b/"中最后的斜杠"/",以及"http://www.baidu.com/"、"http://www.163.com/"中最后的斜杠"/"都是不能去掉的,否则会出现问题。

配置后使用systemctl restart nginx.service & nginx -s reload

查看状态systemctl status nginx.service

ps:在nginx上同一域名不同端口部署多个项目

在nginx.conf中配置两个server

    server {

listen7776;

server_namelocalhost;

access_log /home/zt/test_app/access.log;

error_log /home/zt/test_app/error.log;

        location / {

            include uwsgi_params;

uwsgi_pass 127.0.0.1:5053;

uwsgi_param UWSGI_CHDIR /home/zt/test_app;

uwsgi_param UWSGI_SCRIPT main:app;

        }

        error_page   500 502 503 504  /50x.html;

        location = /50x.html {

            root   html;

        }

   }


    server {

listen7777;

server_namelocalhost;

access_log /home/YHJ/creditech_navigation1/access.log;

error_log /home/YHJ/creditech_navigation1/error.log;

        location / {

            include uwsgi_params;

uwsgi_pass 127.0.0.1:5052;

uwsgi_param UWSGI_CHDIR /home/YHJ/creditech_navigation1;

uwsgi_param UWSGI_SCRIPT manage:app;

        }

        error_page   500 502 503 504  /50x.html;

        location = /50x.html {

            root   html;

        }

   }

配置后使用systemctl restart nginx.service & nginx -s reload

查看状态systemctl status nginx.service

使用命令netstat -nutlp | grep nginx会查到两条

(分别对应的nginx两个端口7776&7777)

tcp        0      0 0.0.0.0:7776            0.0.0.0:*               LISTEN      11610/nginx: master

tcp        0      0 0.0.0.0:7777            0.0.0.0:*               LISTEN      11610/nginx: master

使用命令netstat -nutlp | grep uwsgi会查到两条

(分别对应的uwsgi两个端口5052&5053)

tcp        0      0 127.0.0.1:5052          0.0.0.0:*               LISTEN      19719/uwsgi         

tcp        0      0 127.0.0.1:5053          0.0.0.0:*               LISTEN      19670/uwsgi    

多个项目也是如出一辙,增加server就可以

注意:

如果使用killall -9 uwsgi就会把所有的uwsgi kill掉

然后访问项目的地址即可。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容