为什么要使用nginx+uwsgi+flask
因为标准python只能是单线程,无法并发,而uwsgi/gunicorn通过多进程池达成了并发。
安装uwsgi之前先安装python-devel(centos下)
使用pip install uwsgi,即可安装uwsgi
使用命令find / -name uwsgi可以查看uwsgi的地点
使用uwsgi --version可以查看uwsgi的版本
2.0.17.1
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/b
能够访问
需要这样操作:
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掉
然后访问项目的地址即可。