文章目录
1. 环境说明
- 服务器Centos7
- python 3.6
- flask项目
2. 环境准备
- Centos7自带的python版本是2.7,所以需要手动安装python3.6 版本,参考我这篇文章
- https://blog.csdn.net/weixin_44232093/article/details/105248148
3. 搭建虚拟环境
# 下载虚拟环境包
pip3 install virtualenv
# 使用命令新建虚拟环境,我的目录是/usr
# 创建虚拟环境名叫 venv ,如果你是参考我的文章安装的python
# 那么和我的路径保持一致即可,如果在这一步提示bash: virtualenv: 未找到命令...,执行以下命令
# 添加环境变量
vim /etc/profile
# 将下面内容添加到文件的最下面
PATH=$PATH:/usr/local/python3/bin
# 添加后修改 :wq保存退出 配置文件生效命令
source /etc/profile
# 最后查看是否添加成功
echo $PATH
---------------------------------------------------------------------------------------------
# 指定虚拟环境的python版本 这里指定3.6
virtualenv -p /usr/local/bin/python3 venv
# 激活虚拟环境 source后加你自己的venv目录路径 /bin/activate
source venv/bin/activate
# 查看当前虚拟环境的python版本
python -V
# 在虚拟环境中安装flask、uwsgi库
pip install uwsgi
pip install flask
# 也可以指定 requirements.txt 文件批量下载
pip install -r requirements.txt
4. 创建uwsgi配置文件
- 在激活的虚拟环境中
/usr/venv 目录下
创建 uwsgi.ini 配置文件
# 此时的目录为 /usr/venv 当然你在哪创建都行
touch uwsgiconfig.ini
# 编辑配置文件 添加以下内容
vim uwsgiconfig.ini
- 配置文件内容,记得删除注释
[uwsgi]
# uwsgi 启动时所使用的IP地址与端口,0.0.0.0表示所有IP地址都行
socket = 127.0.0.1:5000
# 指向网站目录,也就是你项目根目录
chdir= /usr/flask
# python 你的程序启动文件,如果是app.py那么这里就写app.py
wsgi-file = app.py
# 你的运行程序省略.py后缀的名字
module = app
# 你的启动程序中的 app = Flask(__name__) 变量名,如果是app 那么这里就写app
callable = app
# 进程数量
processes = 5
# 线程数量
threads = 2
#状态检测地址
stats = 127.0.0.1:9191
# 日志输出目录
daemonize = /usr/venv/flask.log
# pid存储文件,启动服务的主进程ID
pidfile = /XXXX/uwsgi.pid
# 启动主进程
master = true
# 请求体大小,这里65536/1024 就是 64M
buffer-size = 65536
5. 安装nginx
# 添加nginx的yum源
sudo rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
# 安装nginx 命令安装比较简单,也可以选择源码安装
sudo yum install -y nginx
- 我的安装后nginx目录在 /etc/nginx ,找到配置文件
/etc/nginx/nginx.conf
配置 - 我这里配置 /etc/nginx/nginx.conf 不生效,配置好几遍访问还是nginx欢迎页面,如果你和我的情况一样,那么看看nginx配置文件的引入路径对应哪个配置文件
5.1 http请求添加如下内容
# default.conf全部内容都在这里 ,我把注释掉的内容都删掉了,一切从简
server {
listen 80;
# 这里改成你自己的IP,如果是域名那么写域名,如果配置成域名,你通过浏览器访问域名的80端口
# 那么就可以转到uwsgi的服务上 127.0.0.1:5000
server_name localhost;
location / {
# 这里是引入的uwsgi_params 注意路径一定要正确,你可以自己找一下
include /etc/nginx/uwsgi_params;
# 前面是固定写法 后面IP+端口号是你自己服务的端口号 只需要和uwsgi的socket保持一致即可
# 记得你主程序中运行需要设置host="0.0.0.0"
# 一定要和uwsgi中的socket保持一致 !!!!!!
uwsgi_pass 127.0.0.1:5000;
# 这里是之前默认的页面 欢迎页面我就没改 ,不需要可以删除
root /usr/share/nginx/html;
index index.html index.htm;
}
# default.conf自带的 错误页面和欢迎页面 不需要可以删除
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
5.2 https请求添加如下内容
阿里云可以申请免费的证书,参考我这篇文章: 免费申请阿里云ssl证书
下载nginx版本的证书即可开始按照如下配置
server {
listen 443 ssl; # 监听的443端口
server_name XXXX.com; # 这里写你的域名
# ssl证书pem文件路径
ssl_certificate cert/XXXX.pem;
# ssl证书key文件路径
ssl_certificate_key cert/XXXX.key;
# 下面这些东西都是一样的 复制就好 都是关于ssl证书的
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
# 引入的uwsgi参数 路径一定要正确
include /usr/local/nginx/conf/uwsgi_params;
# 请求超时时间 和uwsgi的访问地址,一定保持一致
uwsgi_connect_timeout 30;
uwsgi_pass 127.0.0.1:5000;
}
}
- 配置完毕后启动nginx
systemctl start nginx
- 启动uwsgi项目进入文件目录执行 ,
uwsgi uwsgiconfig.ini
- 我测试的这个没添加日志路径,都输出在终端了这样就是启动成功了
- 访问你自己服务器的IP地址 http://xxx.xxx.xxx.xxx
6. 部署时加上nginx做负载均衡
以上教程是正常的 nginx+uwsgi部署flask项目,如果要加上负载均衡的话,那么参考以下配置文件
负载均衡是高可用网络基础架构的关键组件,通常用于将工作负载分布到多个服务器来提高网站、应用、数据库或其他服务的性能和可靠性,我们单单依靠一个服务器部署项目时,如果这个服务器宕机了,那么用户自然也就没办法访问了。另外,如果同时有很多用户试图访问服务器,超过了其能处理的极限,就会出现加载速度缓慢或根本无法连接的情况,那么解决这种问题就需要负载均衡这种技术了
负载均衡器可以处理什么样的请求:
- HTTP
- HTTPS
- TCP
- UDP
负载均衡器如何选择要转发的后端服务器
负载均衡器一般根据两个因素来决定要将请求转发到哪个服务器。首先,确保所选择的服务器能够对请求做出响应,然后根据预先配置的规则从健康服务器池(healthy pool)中进行选择
因为,负载均衡器应当只选择能正常做出响应的后端服务器,因此就需要有一种判断后端服务器是否「健康」的方法。为了监视后台服务器的运行状况,运行状态检查服务会定期尝试使用转发规则定义的协议和端口去连接后端服务器。如果,服务器无法通过健康检查,就会从池中剔除,保证流量不会被转发到该服务器,直到其再次通过健康检查为止
6.1 nginx配置文件
如果我们部署项目需要用到负载均衡,那么首先要准备两台服务器,在两台服务器上都部署上完整的服务,那么我们只在一台机器上部署nginx即可完成负载均衡
完整的nginx负载均衡配置文件
user nobody;
worker_processes 4;
# 错误日志输出位置 logs 和 conf 同级目录
error_log logs/error.log info;
# nginx的pid 线程号存储位置 同上
pid logs/nginx.pid;
events {
worker_connections 1024;
}
# 注意上面教程的 http 和 server是包含关系,如果按照上面配置nginx
# 那么只需要粘贴 http 里面的配置内容就行
# http 中 包含 https请求需要的ssl证书,负载均衡配置,server服务配置(负载均衡用proxy方式转发)
http {
#------------------------------------ nginx常规配置 ------------------------------------
include mime.types;
default_type application/octet-stream;
# nginx 的日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
# 客户端请求体大小 10M,如果这里不设置的话,请求内容如果超出那么flask会报销
client_max_body_size 10m;
# 开启
sendfile on;
# 心跳检测间隔时间配置
keepalive_timeout 65;
#------------------------------------分割线 下面是负载均衡配置 --------------------------------
# 负载均衡配置内容 upstream xxx 需要和下面 http://xxx 一致
# 例如 upstream test = http://test;
upstream test{
# 配置格式: server IP地址:端口号 weight=X (weight总数为10,自己配置即可)
server 127.0.0.1:8020 weight=3;
# 第二个服务配置最好写内网地址
server 170.168.1.125:8030 weight=7;
}
#------------------------------------分割线 下面是server配置 ---------------------------------
server {
# 监听端口,这里我使用的是https请求,所以监听443
listen 443 ssl;
# 你的域名 XXX.XXX.com
server_name XXX.XXX.com;
# 你的ssl证书 pem , key文件位置 一般证书保存的文件夹和nginx/conf 为同一个目录
# 这里可以去申请阿里云的nginx版本的证书即可开始按照如下配置
ssl_certificate cert/XXXX.pem;
ssl_certificate_key cert/XXXX.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
# location配置
location / {
# 注意这里的名字要和 负载均衡的名字保持一致 upstream 后面为 test,
# 所以这里也是 upstream test
proxy_pass http://test;
proxy_redirect off;
# 这里配置的是转发的真实变量
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
}
6.2 uwsgi配置文件
flask项目还是用uwsgi启动,只不过把socket改成 http
配置nginx的机器上,最好写 0.0.0.0
[uwsgi]
# uwsgi 启动时所使用的IP地址与端口,0.0.0.0表示所有IP地址都行
# socket = 0.0.0.0:8020
http = 0.0.0.0:8020
# 指向网站目录,也就是你项目根目录
chdir = /XXX/XXX/XXX/
# python 你的程序启动文件,如果是app.py那么这里就写app.py
wsgi-file = app.py
# 你的运行程序省略.py后缀的名字
module = app
# 你的启动程序中的 app = Flask(__name__) 变量名,如果是app 那么这里就写app
callable = app
# 进程数量
processes = 2
# 线程数量
threads = 6
#状态检测地址
stats = 127.0.0.1:9200
# 请求体大小,这里65536/1024 就是 64M
buffer-size = 65536
# 日志输出目录
daemonize = /XXX/XXX/XXX.log
# pid存储文件,启动服务的主进程ID
pidfile = /XXXX/uwsgi.pid
# 启动主进程
master = true
# 可选
# 先创建worker,然后各种模块都分别加载了一遍,每个worker的环境是独立的,占内存,但模块彼此独立,不会再出现资源竞争报错的情况了
lazy-apps=true
另一台服务器上,写内网地址:端口号
[uwsgi]
# uwsgi 启动时所使用的IP地址与端口,0.0.0.0表示所有IP地址都行 http: 8010
# socket = 170.168.1.125:8030
http = 170.168.1.125:8030
# 指向网站目录,也就是你项目根目录
chdir = /XXX/XXX/XXX/
# python 你的程序启动文件,如果是app.py那么这里就写app.py
wsgi-file = app.py
# 你的运行程序省略.py后缀的名字
module = app
# 你的启动程序中的 app = Flask(__name__) 变量名,如果是app 那么这里就写app
callable = app
# 进程数量
processes = 2
# 线程数量
threads = 6
#状态检测地址
stats = 127.0.0.1:9455
# 请求体大小,这里65536/1024 就是 64M
buffer-size = 65536
# 日志输出目录
daemonize = /XXX/XXX/XXX.log
# pid存储文件,启动服务的主进程ID
pidfile = /XXXX/uwsgi.pid
# 启动主进程
master = true
# 可选
# 先创建worker,然后各种模块都分别加载了一遍,每个worker的环境是独立的,占内存,但模块彼此独立,不会再出现资源竞争报错的情况了
lazy-apps=true
配置完成后启动两台机器的服务观察启动日志,如果日志没错会显示如下
这时访问你配置的域名,就会跟你配置的权重分配请求了,可以在两个服务上做不同的标记,这样用来检测负载均衡是否配置成功
7. 配置常用命令
# 查看端口占用 :
netstat -lnp | grep 端口号
# 查找nginx位置
whereis nginx
# 检查nginx配置文件是否正确
nginx目录下的/sbin/nginx -t
# 如果nginx没有加入到systemctl中 那么重启方式如下
nginx目录下/sbin/nginx -s reload
# 指定配置文件方式启动nginx
/usr/sbin/nginx -c /etc/nginx/nginx.conf
#也可以加入到系统命令里面启动 nginx
systemctl start nginx
#重新启动 nginx
systemctl restart nginx
#关闭 nginx
systemctl stop nginx
#关闭所属所有进程 适用于所有,只需要更改 -9 后面的名字即可
killall -9 nginx
# 把虚拟环境导入到 requirements.txt 文件中
pip freeze > requirements.txt
# 使用 requirements.txt
pip install -r requirements.txt
8. 502访问不到页面
如果你都配置的好好的,但是就是访问的时候提示页面出错,访问不到页面,或者一系列的错误问题,那么你就要考虑端口是否开放的问题了,Centos7有两个安全机制,一个防火墙,一个seLinux,这两个如果你不会调的话,那么直接关闭,只限于测试阶段,如果正式还是要请运维开放服务端口的
# 查看seLinux状态, enforcing为开启、disable为关闭
getenforce
# 临时关闭selinux
setenforce 0
# 永久关闭selinux
vim /etc/selinux/config
把SELINUX=enforcing改为SELINUX=disabled,保存文件重启即可
# 查看防火墙状态
systemctl status firewalld.service
# 关闭防火墙状态
systemctl stop firewalld.service
# 禁止防火墙开机启动
systemctl disable firewalld.service
# 开放5000端口 --zone是作用于 --permanent永久生效
firewall-cmd --zone=public --add-port=5000/tcp --permanent
# 关闭5000端口
firewall-cmd --zone=public --remove-port=5000/tcp --permanent
# 重新加载配置 刷新
firewall-cmd --reload
# 查看所有开放的端口
firewall-cmd --zone=public --list-ports