在开发环境,我们一般使用python起一个web服务即可访问,但是对于生产环境来说,我们一般使用nginx+uWSGI的方式进行部署。

使用Nginx优点:

  • 安全:不管什么请求都要经过代理服务器,这样就避免了外部程序直接攻击web服务器
  • 负载均衡:根据请求情况和服务器负载情况,将请求分配给不同的web服务器,保证服务器性能
  • 提高web服务器的IO性能:对于一些静态文件,可以直接由反向代理处理,不经过web服务器

相关概念:

  wsgi web应用程序之间的接口。它的作用就像是桥梁,连接在web服务器和web应用框架之间。
  uwsgi 是一种传输协议,用于定义传输信息的类型。
  uWSGI 是实现了uwsgi协议WSGI的web服务器。

1. 添加测试项目

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
return 'flask project' @app.route("/user/<int:uid>")
def user_profile(uid):
return f'user id:{uid}' if __name__ == '__main__':
app.run()

本项目是基于虚拟环境进行搭建,具体安装查看virtualenv相关博客

2.创建新的虚拟环境,并安装uwsgi

mkvirtualenv flask_env

pip3 install uwsgi

3. 在本项目下创建uwsgi配置文件,添加内容如下:

  [uwsgi]
module = app:app # 相当于命令下的-w 指定模块(wsgi-file,callable 这两个可以被注视掉)
#http = 127.0.0.1:5000
socket = 127.0.0.1:5000 # 支持http+socket两种方式,这里选用socket
virtualenv = /root/python_env/flask_project # 如果使用虚拟环境,需要进行执行
chdir = /data/python_projects/flask_project # 指定项目路径
#wsgi-file = app.py # 项目入口文件
#callable = app # flask应用对象
process = 2 # 进程数
threads = 2 # 每个进程开启的线程数
buffer-size = 32768
master = true # 主进程
daemonize = %(chdir)/uwsgi/uwsgi.log # 指的后台启动 日志输出的地方
pidfile = %(chdir)/uwsgi/uwsgi.pid # 保存主进程的进程号
py-autoreload=1 #热加载开启
 touch-logreopen = %(chdir)/uwsgi/touchforlogrotate # 日志分割监听文件
 stats = 127.0.0.1:9191  # 添加监听  使用nc  127.0.0.1 9191 查看 (nc 安装:yum -y install nmap-ncat)
thunder-lock = true
#防止惊群
harakiri = 60
#超时时间(秒)
vacuum = true  #自动移除unix Socket和pid文件当服务停止的时候 

  

完整配置项:

socket : 地址和端口号,例如:socket = 127.0.0.1:50000

processes : 开启的进程数量

workers : 开启的进程数量,等同于processes(官网的说法是spawn the specified number of  workers / processes)

chdir : 指定运行目录(chdir to specified directory before apps loading)

wsgi-file : 载入wsgi-file(load .wsgi file)

stats : 在指定的地址上,开启状态服务(enable the stats server on the specified address)

threads : 运行线程。由于GIL的存在,我觉得这个真心没啥用。(run each worker in prethreaded mode with the specified number of threads)

master : 允许主进程存在(enable master process)

daemonize : 使进程在后台运行,并将日志打到指定的日志文件或者udp服务器(daemonize uWSGI)。实际上最常用的,还是把运行记录输出到一个本地文件上。

log-maxsize :以固定的文件大小(单位KB),切割日志文件。 例如:log-maxsize = 50000000  就是50M一个日志文件。 

pidfile : 指定pid文件的位置,记录主进程的pid号。

vacuum : 当服务器退出的时候自动清理环境,删除unix socket文件和pid文件(try to remove all of the generated file/sockets)

disable-logging : 不记录请求信息的日志。只记录错误以及uWSGI内部消息到日志中。如果不开启这项,那么你的日志中会大量出现这种记录:

[pid: 347|app: 0|req: 106/367] 117.116.122.172 () {52 vars in 961 bytes} [Thu Jul  7 19:20:56 2016] POST /post => generated 65 bytes in 6 msecs (HTTP/1.1 200) 2 headers in 88 bytes (1 switches on core 0)

log-maxsize: 日志大小,当大于这个大小会进行切分 (Byte)

log-truncate: 当启动时切分日志

4.启动服务

uwsgi --ini config.ini

5.配置nginx代理转发

        location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:5000;
}

因为转发之后的通信是使用的uwsgi://127.0.0.1:5000进行通信,所以uwsgi配置socket方式

如果使用http的方式进行通信的话:
location / {
proxy_pass http://127.0.0.1:5000;
}

其他命令:

# 重启uwsgi服务
uwsgi --reload uwsgi.pid # 停止uwsgi服务
uwsgi --stop uwsgi.pid

命令下的 服务启动:

$ uwsgi -s /tmp/yourapplication.sock --manage-script-name --mount /yourapplication=myapp:app
--manage-script-name 会把 SCRIPT_NAME 处理移向 uwsgi , 因为 uwsgi 会更智能一些。与 --mount 联用可以把向 /yourapplication 发送的请求 重定向到 myapp:app 。如果应用可以在根级别访问,那么可以使用单个 / 来代替 /yourapplication 。 myapp 指 flask 应用的文件名称(不含扩展 名)或者提供 app 的模块名称。 app 在应用内部可被调用(通常是 app = Flask(__name__) )。 如果要把应用部署于一个虚拟环境,则还需要加上 --virtualenv /path/to/virtual/environment 。可能还需要根据项目所使用的 Python 版本相应地加上 --plugin python 或者 --plugin python3 。

添加日志分割:

  uwsgi没有提供按天的日志切割配置,只提供了一个log-maxsize配置,当文件达到多大的时候自动切分,对于查找历史日志还是很不方便。

这里可以用mv+touch-logreopen参数,移动日志文件后,让uwsgi重新打开日志记录,不过需要配合sh+crontab
配置文件添加:
touch-logreopen = %d./touchforlogrotat #指定监听文件,修改后重新打开日志

这里我们指定日志文件就在项目目录下叫uwsgi.daemonize.log,监听项目目录下的touchforlogrotat文件,如果文件发生变化,就重新打开日志,我们可以先将当前的uwsgi.daemonize.log文件移动到别的地发,再touch一下touchforlogrotat,之前的文件便停止写入,重新生成了一个叫uwsgi.daemonize.log文件。

在当前项目下新建一个touchforlogrotate.sh,并新建日志文件备份的日志,这里就放在项目中的logs文件夹

#!/bin/bash

DIR=`echo $(cd "$(dirname "$0")"; pwd)`
LOGDIR="${DIR}/logs" sourcelogpath="${DIR}/uwsgi.daemonize.log"
touchfile="${DIR}/touchforlogrotate" DATE=`date -d "yesterday" +"%Y%m%d"`
destlogpath="${LOGDIR}/uwsgi.daemonize.${DATE}.log" mv $sourcelogpath $destlogpath
touch $touchfile

crontab定时调用

0 0 * * * sh /projectpath/touchforlogrotate.sh

注意点:

  1.请务必把 app.run() 放在 if __name__ == '__main__': 内部或者放在单独 的文件中,这样可以保证它不会被调用。因为,每调用一次就会开启一个本地 WSGI 服务器。当我们使用 uWSGI 部署应用时,不需要使用本地服务器。

结合uWSGI和Nginx部署flask项目的更多相关文章

  1. 通过Nginx部署flask项目

    用Flask开发之后,很多人,喜欢用nohup python manage.py & 这样的形式,放到后台运行,其实这样只是个发开模式,很简陋,无法支持并发,进程监控等功能.所以采用nginx ...

  2. centOS+uwsgi+nginx 部署flask项目,问题记录

    用flask做的项目想要部署到centOS系统上,填了一些坑,终于成功了,记录一下遇到的问题: 此次部署主要是按照这个博客进行的 https://www.cnblogs.com/Ray-liang/p ...

  3. uwsgi+anaconda+nginx部署django项目(ubuntu下)

    conda 环境不必多说: conda(或source)  activate  test 进入test虚拟环境 接下来安装uwsgi: pip install uwsgi 在conda环境下大概率安装 ...

  4. 使用Flask+uwsgi+Nginx部署Flask正式环境

    环境准备 在开始正式讲解之前,我们将首先进行环境准备. Step1:安装Python,pip以及nginx: sudo apt-get update sudo apt-get install pyth ...

  5. 使用Nginx和uwsgi部署Flask项目

    前言   之前用Flask框架开发了一个Python的Web项目,使用Nginx和uWSGI部署起来感觉挺麻烦,过程中还因为对Flask框架的不熟悉,花了好长时间才把应用完全部署起来.下面分享部署成功 ...

  6. 使用uWSGI+nginx部署Django项目

    最近使用django写了一些项目,不过部署到服务器上碰到一些问题,还有静态文件什么的一堆问题,这里总结一下碰到的问题和解决方案,总体思路是按照官方文档走的. 原文地址:http://uwsgi-doc ...

  7. CentOS 下部署Nginx+Gunicorn+Supervisor部署Flask项目

    原本之前有一部分东西是在Windows Server,但是由于Gunicorn不支持Windows部署起来颇为麻烦.最近转战CentOS,折腾一段时间,终于简单部署成功.CentOS新手,作为一个总结 ...

  8. liunx部署flask项目

    如何在linux上部署flask项目 Python3.7 + virtualenv + uwsgi + git + mysql-5.6.45 + nginx 源码编译安装所需要的环境 yum inst ...

  9. Ubantu下部署Flask项目安装与配置

    1.nginx 安装 sudo apt-get install nginx 启动,停止和重启 sudo /etc/init.d/nginx start sudo /etc/init.d/nginx s ...

  10. 部署Flask项目到腾讯云服务器CentOS7

    部署Flask项目到腾讯云服务器CentOS7 安装git yum install git 安装依赖包 支持SSL传输协议 解压功能 C语言解析XML文档的 安装gdbm数据库 实现自动补全功能 sq ...

随机推荐

  1. Goby漏洞发布 | CVE-2024-38856 Apache OFbiz /ProgramExport 命令执行漏洞【已复现】

    漏洞名称:Apache OFbiz /ProgramExport 命令执行漏洞(CVE-2024-38856) English Name:Apache OFbiz /ProgramExport Com ...

  2. EF Core – ExecuteUpdate and ExecuteDelete (Bulk updates 批量更新和删除)

    前言 EF Core 在 SaveChanges 之后会一句一句的去更新和删除数据. 有时候这个效率是很差的. 而 SQL 本来就支持批量更新和删除, 所以是 EF Core 的缺失. 在 EF Co ...

  3. CSS – Tailwind CSS

    前言 很多时候 CSS 未必是需要管理的, 比如做网站, Landing Page (类似宣传单). 很多时候做了 > 用了 > 丢 > 再做新的. 它没有 "维护&quo ...

  4. FFmpeg开发笔记(五十三)移动端的国产直播录制工具EasyPusher

    ​EasyPusher是一款国产的RTSP直播录制推流客户端工具,它支持Windows.Linux.Android.iOS等操作系统.EasyPusher采用RTSP推流协议,其中安卓版EasyPus ...

  5. Kubernetes Pod生命周期(十七)

    前面我们已经了解了 Pod 的设计原理,接下来我们来了解下 Pod 的生命周期.下图展示了一个 Pod 的完整生命周期过程,其中包含 Init Container.Pod Hook.健康检查 三个主要 ...

  6. 使用duxapp开发 React Native App 事半功倍

    Taro的React Native端开发提供了两种开发方式,一种是将壳和代码分离,一种是将壳和代码合并在一起开发 壳是用来打包调试版或者发版安装包使用的 代码是运行在壳上的js代码 Taro壳子的代码 ...

  7. 腾讯自研Git客户端,助力每个人都可以轻松使用Git

    工具介绍 UGit是一款腾讯自研的Git客户端,为了让每个人都可以轻松使用Git,从而提高开发效率和团队协作的流畅性.支持工蜂MR/CR,工蜂议题管理,另外对于Git的原生特性有着深度支持. 支持的系 ...

  8. TCP 与 UDP 的区别有哪些

    什么是 TCP TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议 什么是 UDP UDP(User Datagra ...

  9. Blazor Hybrid 实战体验:那些你可能没预料到的坑没预料到的坑

    前言 昨天写了一篇介绍 Blazor Hybrid 技术的文章,但限于篇幅,一些问题未能深入探讨.今天,我想继续记录使用 Blazor Hybrid 过程中遇到的几个问题,以及这个技术目前的一些局限性 ...

  10. docker部署Prometheus与Grafana

    prometheus部署 建立文件 mkdir -p /ops/prometheus-data && cd /ops/prometheus-data vi /ops/prometheu ...