前言
突击4天,让我一个python小白,完成一个php小项目的python重构,项目是openai的一个小实践,通过socketio与客户端通讯,实现streaming响应,效果如同chantgpt的效果,技术栈包括python🌐, venv🌐, flask🌐, flask-socketio🌐, requests🌐, eventlet🌐, gunicorn🌐, nginx🌐等,本地开发IDE使用PyCharm,创建项目一键完成,所以也不清楚里面的流程步骤,但是项目本地能跑,一直用flask的开发服务器,还算顺利。整到线上生产环境,各种坑,像python版本过低,requests库依赖的openssl版本过低,升级openssl版本后python依然调用低版本openssl,改用eventlet生产web服务器,nginx反向代理配置等,网上的方案五花八门,没有完美适配的,只能挨个测试,好在都逐一解决了,稍后把各个解决方案都整理出来,方便自己,方便大家
1,导出本地依赖列表
pip freeze > requirements.txt
2,打包项目文件并上传至生产环境
# 进入本地项目目录
cd project_dir
# 要排除venv虚拟环境目录
zip -r project.zip * -x './venv/*'
3,生产环境部署
# 将上一步的zip上传到服务器项目目录
$ cd project_dir
$ unzip project.zip
# 修改目录权限及拥有者,让nginx可以读取
$ chmod 0774 -R ./
$ chown www:www -R ./
$ python3 -m venv venv # 创建虚拟环境,此处需要根据系统版本决定
$ . venv/bin/activate # 激活虚拟环境(.和后面的空格不能少)
$ python -m pip install --upgrade pip #建议更新,非必选
$ python -m pip install --upgrade setuptools #建议更新,非必选(经过实践,该项必选,且与本地开发的版本一致)
(venv) $ pip install -r requirements.txt # 安装所有依赖
# 退出虚拟环境使用 deactivate
# 安装完成后启用服务
$ gunicorn -b 127.0.0.1:5000 --worker-class eventlet -w 1 app:app
# -w 1表示1个进程 -b 127.0.0.1:5000表示在内网监听该端口,如果需要外网连接,需要把IP改成0.0.0.0
# gunicorn在负载均衡方面的算法不咋地,所以进程只能开一个
# app:app 前者代表启动程序文件名, 后者为实例化对象命名即 app = Flask(__name__)
4,nginx反向代理
server {
listen 80;
server_name your.domain.com;
underscores_in_headers on;
location / {
include uwsgi_params;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_pass http://127.0.0.1:5000;
}
#不太明白此处的用途,我给注释掉了
location /static {
alias <path-to-your-application>/static;
expires 30d;
}
location /socket.io {
include uwsgi_params;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_pass http://127.0.0.1:5000/socket.io;
}
}
5,基本上,这样就OK了,生产环境跑eventlet服务器,浏览器访问http://your.domain.com就能正常访问服务了。
6,有时候进程开着,但是服务已经中断,这时就需要关闭或重启gunicorn服务,使用pstree查看进程树,然后关掉
$ pstree |grep gunicorn
| \--- 82930 jena grep gunicorn
\-+= 73226 jena /Users/jena/Documents/workplace/WonderBytech/openai-py/venv/bin/python /Users/jena/Documents/workplace/WonderBytech/openai-py/venv/bin/gunicorn -b 127.0.0.1:5000 --worker-class eventlet -w 1 app:app
\--- 73227 jena /Users/jena/Documents/workplace/WonderBytech/openai-py/venv/bin/python /Users/jena/Documents/workplace/WonderBytech/openai-py/venv/bin/gunicorn -b 127.0.0.1:5000 --worker-class eventlet -w 1 app:app
#杀掉进程
$ kill -9 73226
#重启服务
$ kill -HUP 73227
‼️后记:还有很多要处理,像多进程,监听队列,安全认证,进程监控等等,后续再完善吧
参考链接
- https://www.zlkt.net/book/detail/14/366
- https://juejin.cn/post/6844903703078502413
- https://dormousehole.readthedocs.io/en/latest/quickstart.html#id7
- https://blog.csdn.net/william_munch/article/details/103368580
- https://blog.csdn.net/ieeso/article/details/105040207
- https://www.jianshu.com/p/3c3e18456ccc