flask+uwsgi+docker+nginx 云服务器部署测试平台

news2024/11/10 16:24:04

flask+uwsgi+docker+nginx 云服务器部署测试平台

开发环境
本次主要是在腾讯云上进行部署,系统是CentOS 7.9 64位,主要使用的软件如下:

Python 3.9.5
Pycharm
Flask1.0.2
Mysql 5.7
nginx + uwsgi

一 安装Nginx

1.更新yum 源

sudo rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm

2.安装

sudo yum install nginx

3.配置nginx

// 1.设置开机启动
$ sudo systemctl enable nginx
// 2.启动服务
$ sudo systemctl start nginx
// 3.停止服务
$ sudo systemctl restart nginx
// 4.重新加载,因为一般重新配置之后,不希望重启服务,这时可以使用重新加载。
$ sudo systemctl reload nginx

4.docker部署

拉取镜像:docker pull nginx:1.17.9
构建容器 
docker run -d --name nginx -p 8081:80 
--privileged=true --restart always 
-v ${PWD}/nginx/html:/usr/share/nginx/html 
-v ${PWD}/nginx/logs:/var/log/nginx 
nginx:1.17.9

-v ${PWD}/nginx/conf/nginx.conf:/etc/nginx/nginx.conf 
不支持直接挂载文件,可以创建后复制到容器中

5.请求转发

配置nginx

cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak 备份
sudo vim /etc/nginx/nginx.conf 编辑

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    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  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

改为

 user  root;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    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  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
    upstream flask {
    server 101.35.129.200:5001;
     }

    server {

      listen       80;
      server_name  localhost;  #改为自己的域名,如果没有域名就修改为127.0.0.1 或者 localhost
      location / {
         proxy_pass http://101.35.129.200:5001;  # 此处可以写单个主机信息(前面的gunicorn启动的ip地址),也可以写upstream的组名。
         # proxy_pass http://flask;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
     }
   }
}

访问

4.常见问题

// 绑定其他端口
// Nginx 默认绑定的端口是 http 协议的默认端口,端口号为:80,如果需要绑定其他端口,需要注意 SELinux 的配置

// 例如:绑定 8081 端口,但是会发现无法启动,一般的报错如下

// YYYY/MM/DD hh:mm:ss [emerg] 46123#0: bind() to 0.0.0.0:8081 failed (13: Permission denied)
// 此时需要更改 SELinux 的设置。我们使用 SELinux 的管理工具 semanage 进行操作,比较方便。

// 安装 semanage 使用如下命令

sudo yum install policycoreutils-python
// 然后查看是否有其他协议类型使用了此端口

sudo semanage port -l | grep 8081
transproxy_port_t              tcp      8081
// 返回了结果,表明已经被其他类型占用了,类型为 transproxy_port_t。

// 我们还要查看一下 Nginx 的在 SELinux 中的类型 http_port_t 绑定的端口

sudo semanage port -l | grep http_port_t
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t            tcp      5988
// 第一行 http_port_t 中没有包含 8081 这个端口。因此需要修改 8081 端口到 http_port_t 类型中。

sudo semanage port -m -p tcp -t http_port_t 8081
// 如果没有其他协议类型使用想要绑定的端口,如 8001,则我们只要新增到 SELinux 中即可。

sudo semanage port -l | grep 8001
sudo semanage port -a -p tcp -t http_port_t 8001
// 此时,重新启动 Nginx 即可。

二 防火墙操作

1.查看已经开放的端口

firewall-cmd --list-ports

2.开启端口

firewall-cmd --zone=public --add-port=80/tcp --permanent

3.命令含义

–zone #作用域

–add-port=80/tcp #添加端口,格式为:端口/通讯协议

–permanent #永久生效,没有此参数重启后失效

4.重启防火墙

firewall-cmd --reload #重启firewall

systemctl stop firewalld.service #停止firewall

systemctl disable firewalld.service #禁止firewall开机启动

firewall-cmd --state #查看默认防火墙状态(关闭后

作者:Oort
链接:https://www.jianshu.com/p/8012323b60a2
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

三 CentOS 7 安装 Python3.7

1.安装 Python3.7

yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make libffi-devel

这里面有一个包很关键libffi-devel,因为只有3.7才会用到这个包,如果不安装这个包的话,在 make 阶段会出现如下的报错:

ModuleNotFoundError: No module named '_ctypes'

2.安装pip,因为 CentOs 是没有 pip 的。

#运行这个命令添加epel扩展源 
yum -y install epel-release 
#安装pip 
yum install python-pip

3.可以用yum 安装 安装一下 wget

yum -y install wget

4.下载 python3.7的源码包

wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz
#解压缩
tar -zxvf Python-3.7.0.tgz

#进入解压后的目录,依次执行下面命令进行手动编译
./configure prefix=/usr/local/python3 
make && make install

如果最后没提示出错,就代表正确安装了,在/usr/local/目录下就会有python3目录

5.添加软链接

#添加python3的软链接 
ln -s /usr/local/python3/bin/python3.7 /usr/bin/python3.7 
#添加 pip3 的软链接 
ln -s /usr/local/python3/bin/pip3.7 /usr/bin/pip3.7
#测试是否安装成功了 
python -V

6.更改yum配置,因为其要用到python2才能执行,否则会导致yum不能正常使用(不管安装 python3的那个版本,都必须要做的)

vi /usr/bin/yum 
把 #! /usr/bin/python 修改为 #! /usr/bin/python2 
vi /usr/libexec/urlgrabber-ext-down 
把 #! /usr/bin/python 修改为 #! /usr/bin/python2

7.docker安装python

Dockerfile

FROM python:3.6

LABEL maintainer="dasun"

USER root

ARG kdir=/home

WORKDIR $kdir

RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

#映射端口
EXPOSE 5000
CMD ["python -version"]

四 WSGI安装配置

1.WSGI是什么?

WSGI,全称 Web Server Gateway Interface,是为 Python 语言定义的 Web 服务器和 Web 应用程序或框架之间的一种简单而通用的接口。
WSGI就像是一座桥梁,一边连着web服务器,另一边连着用户的应用

2.uwsgi和uWSGI

uwsgi同WSGI一样是一种通信协议。
而uWSGI是实现了uwsgi和WSGI两种协议的Web服务器。

为什么要使用

使用flask写了一个简易的http服务用来提供接口,按照接口文档demo写好以后本地测试一切正常,但是发布到服务器以后有一串警告:WARNING:This is a developnent server. Do not use it in a production deploynent,如下图:
在这里插入图片描述
意思是我的这个启动方式不能在生产环境上使用,然后带着疑问上网查了一下,我的启动方式是

app.run(host="0.0.0.0", port=80)

只适用于开发模式,因为它是单线程的,生产环境影响性能,替代方案是可以用uWSGI或者pywsgi

3.三者的区别如下

1.app.run 启动的是单线程服务,性能很低

2.pywsgi服务器使用的是gevent的pywsgi模块,性能不错,配置也很简单,但是它只是把单线程改造成了单线程异步方式

3.uWSGI性能最好,配置稍微比上面难一点,但是它是支持多进程、多线程、和多协程的方式,简直就是完美,所以我选择尝试使用uWSGI服务器来替代

4.pywsgi方式实现

1.安装gevent模块
pip install gevent

2.在启动类里引入模块
from gevent import pywsgi

3.main方法里将app.run替换
server = pywsgi.WSGIServer(('0.0.0.0', 80), app)
server.serve_forever()

5.uWSGI实现

官方文档 https://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/WSGIquickstart.html#uwsgipython

5.1安装uWSGI模块

 pip install uwsgi

5.2配置文件

在根目录下创建uWSGI配置文件 【uwsgi.ini】

[uwsgi]
# 使用nginx连接时使用
# socket = 0.0.0.0:8080

# 地址端口 直接作为web服务器使用
http = 0.0.0.0:80
# 项目路径
chdir = /root/projectname
# 项目启动文件 适用于flask项目部署
wsgi-file = manage.py
# 项目需要调用的启动类 router
callable = app
# 进程线程设置
processes = 4
threads = 10
# 日志文件
daemonize = /app/logs/uwsgi.log
# 保存主进程pid文件
pidfile = uwsgi.pid
# 是否需要主进程
master = true

5.3相关命令

使用uwsgi服务器启动 : uwsgi --ini uwsgi.ini
停止 : uwsgi --stop uwsgi.pid
停止 : pkill -f uwsgi -9

uwsgi --http-socket :6005 --http-websockets --wsgi-file app.py --callable app --master --processes 4 --threads 2 --stats 127.0.0.1:9191

5.4配置选项

master = true  #启动主进程,来管理其他进程,其它的uwsgi进程都是这个master进程的子进程,如果kill这个master进程,相当于重启所有的uwsgi进程。

chdir = /web/www/mysite  #在app加载前切换到当前目录, 指定运行目录

module = mysite.wsgi  # 加载一个WSGI模块,这里加载mysite/wsgi.py这个模块

py-autoreload=1  #监控python模块mtime来触发重载 (只在开发时使用)

lazy-apps=true  #在每个worker而不是master中加载应用

socket = /test/myapp.sock  #指定socket文件,也可以指定为127.0.0.1:9000,这样就会监听到网络套接字

processes = 2 #启动2个工作进程,生成指定数目的worker/进程

buffer-size = 32768   #设置用于uwsgi包解析的内部缓存区大小为64k。默认是4k。

daemonize = /var/log/myapp_uwsgi.log  # 使进程在后台运行,并将日志打到指定的日志文件或者udp服务器

log-maxsize = 5000000 #设置最大日志文件大小

disable-logging = true #禁用请求日志记录

vacuum = true #当服务器退出的时候自动删除unix socket文件和pid文件。

listen = 120 #设置socket的监听队列大小(默认:100)

pidfile = /var/run/uwsgi.pid  #指定pid文件

enable-threads = true  #允许用内嵌的语言启动线程。这将允许你在app程序中产生一个子线程

reload-mercy = 8  #设置在平滑的重启(直到接收到的请求处理完才重启)一个工作子进程中,等待这个工作结束的最长秒数。这个配置会使在平滑地重启工作子进程中,如果工作进程结束时间超过了8秒就会被强行结束(忽略之前已经接收到的请求而直接结束)

max-requests = 5000  #为每个工作进程设置请求数的上限。当一个工作进程处理的请求数达到这个值,那么该工作进程就会被回收重用(重启)。你可以使用这个选项来默默地对抗内存泄漏

limit-as = 256  #通过使用POSIX/UNIX的setrlimit()函数来限制每个uWSGI进程的虚拟内存使用数。这个配置会限制uWSGI的进程占用虚拟内存不超过256M。如果虚拟内存已经达到256M,并继续申请虚拟内存则会使程序报内存错误,本次的http请求将返回500错误。

harakiri = 60  #一个请求花费的时间超过了这个harakiri超时时间,那么这个请求都会被丢弃,并且当前处理这个请求的工作进程会被回收再利用(即重启)

5.5运行

查看进程 : ps -aux | grep uwsgi
root     14281  0.4  2.3 272640 42000 ?        S    16:06   0:00 uwsgi --ini uwsgi.ini
root     14370  0.0  2.1 936228 37452 ?        Sl   16:06   0:00 uwsgi --ini uwsgi.ini
root     14371  0.0  2.1 936228 37456 ?        Sl   16:06   0:00 uwsgi --ini uwsgi.ini
root     14381  0.0  2.1 936228 37452 ?        Sl   16:06   0:00 uwsgi --ini uwsgi.ini
root     14382  0.0  2.1 936228 37456 ?        Sl   16:06   0:00 uwsgi --ini uwsgi.ini
root     14383  0.0  2.0 273124 37096 ?        S    16:06   0:00 uwsgi --ini uwsgi.ini
root     18126  0.0  0.0 112824   980 pts/0    S+   16:07   0:00 grep --color=auto uwsgi
S代表一个主进程, Sl代表四个子进程

常见问题总结

运行uwsgi时出错 open(“./python_plugin.so”)

运行uwsgi时出错:
open(“./python_plugin.so”): No such file or directory [core/utils.c line 3713]
UNABLE to load uWSGI plugin: ./python_plugin.so: cannot open shared object file: No such file or directory!
原因:这可能是uwsgi的配置问题
解决:1. 若是使用的uwsgi 的配置文件是 .ini 类型时,注释

# plugin = python
  1. 若是配置文件是 .xml 类型时,删除 python 。

  2. 其他配置文件类型还有 .json 及 .yaml 文件。

  3. 若是以上配置文件没问题,那么就是没有安装好 uwsgi 或者uwsgi 服务没有启动,启动uwsgi 服务:

systemctl start uwsgi
再次运行命令是否可行。若还是不可行,那么按照以下步骤:

首先查询是否已存在uwsgi,并卸载:

rpm -qa|grep uwsgi
yum remove -y uwsgi*
若之前是pip 安装的话,执行:

pip uninstall uwsgi
重新安装:

Ubuntu 的Python3 :

apt-get install -y uwsgi-plugin-python3
注:这里可能还有个所有可用的plugin:sudo apt-get install uwsgi-plugins-all

centos环境:

sudo yum install -y uwsgi-plugin-python
查看 uwsgi 服务是否启动:

systemctl status uwsgi
若没有则启动之。

server配置
from wsgiref.simple_server import make_server
server = make_server('127.0.0.1', 5000, app)
server.serve_forever()
app.run(host='127.0.0.1',port=5000)

Docker容器一起动就退出的解决方案
docker run -dit --name testplatformapi --network testplatform -p 5001:5001 testplatformapi:v1 /bin/bash
添加-it 参数交互运行
添加-d 参数后台运行
这样就能启动一个一直停留在后台运行的Centos了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/709140.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Java+Swing+Mysql图书信息管理系统

基于JavaSwingMysql图书信息管理系统 一、系统介绍二、功能展示1.主页2.新增图书信息3.删除图书信息 三、数据库四、其他系统实现五、获取源码 一、系统介绍 该系统实现了查看图书列表、新增图书信息、删除图书信息 运行环境:eclipse、idea、jdk1.8 二、功能展示…

TCP的三次握手,四次挥手

1.TCP协议介绍 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。由IETF的RFC 793 [1] 定义…

云之道知识付费v2 3.1.1独立版小程序系统源码

云之道知识付费v2 3.1.1独立版小程序系统源码 很不错的一款知识丰富小程序,感兴趣的可以自己下载搭建尝试一下。

Java官方笔记13集合

Storing Data The Collections Framework is the most widely used API of the JDK. 集合不是数据类型,它是JDK的API,可以用来存储数据等,相当于数据结构。 the Collections Framework is a set of interfaces that models different way of …

chatgpt赋能python:用Python做中文词云

用Python做中文词云 介绍 中文词云是一种常见的数据可视化方式,通过将文本中出现频率较高的关键词以图形的形式展现出来,让人一眼就能了解文本内容的主题和关键词。在搜索引擎优化(SEO)方面,中文词云也常被用来帮助分…

【python】使用Antlr4实现识别sql中的表或视图名

前言 先上成果预览图吧 作为一个数据库sql开发者,肯定有很多人和我一样,想要有一个工具,能传入任意sql,解析出sql中的所有表。 我之前有一篇文章【AIO】将任意查询sql转换成带远程数据库DBLINK的sql 中就提到了,使用纯文本硬解析会存在很多不确定因素,比如oracle新版本…

截取屏幕中指定区域的图像pyautogui.screenshot(区域)

【小白从小学Python、C、Java】 【等级考试500强双证书考研】 【Python-数据分析】 截取屏幕中指定区域的图像 pyautogui.screenshot(区域) [太阳]选择题 关于以下代码说法错误的是: import pyautogui print("【执行】pyautogui.screenshot(region(0,0,2…

麦语言入门~001课

麦语言是一种编程语言,它是由麦肯锡公司开发的一种专门用于数据分析和统计建模的语言。麦语言具有类似于R和Python的功能,并提供了一组丰富的数据处理、统计分析和机器学习的工具。麦语言主要用于解决复杂的商业和统计分析问题,并被广泛应用于…

CRM系统能帮助外贸企业提高哪些工作效率?

外贸企业的业务和客户遍布世界各地,更涉及不同的语言和文化。因此,管理客户信息、提高服务质量、扩大市场份额成为了外贸企业亟待解决的问题。针对这些情况,不少企业开始使用CRM客户管理系统。下面说说,外贸企业为什么要用CRM系统…

Spring面试题--Spring的bean的生命周期

这个问题比较困难,设计到了spring的底层,但是通过这个的学习,可以帮助我们了解Spring容器是如何管理和创建bean实例,以及方便调试和解决问题。 BeanDefinition bean的定义信息,Spring容器在进行实例化时,…

11-C++算法01-枚举排序

📖 C算法 在编程中,算法是解决问题的一系列步骤或规则。在C中,提供了丰富的算法库,可以方便地进行各种常见的算法操作。本篇学习笔记将介绍一些常见的排序算法,帮助你理解和应用这些算法。 🚀 枚举 &…

C语言VS Code 开发环境搭建

文章目录 官方文档安装拓展生成c_cpp_properties.json生成tasks.json生成launch.json测试Debug如何让程序debug完不退出?Windows版本的配置GDB和LLDB的区别 由于之前使用VS Code较少,缺少在VS Code上开发C程序的经验。本篇博文主要记录使用VS Code开发C程…

基于Tars高并发IM系统的设计与实现-基础篇2

基于Tars高并发IM系统的设计与实现-基础篇2 三大指标 高可用 分为服务高可用与存储高可用。 服务高可用 服务高可用要做到高可用必须具备两个特点: 负载均衡可横行扩展 当服务的请求量比较高的时候,一台服务不能满足需求,这时候需要多…

sklearn.preprocessing模块介绍

数据预处理 Binarizer: 二值化 用于将数值特征二值化。它将特征值与给定的阈值进行比较,并将特征值转换为布尔值(0 或 1),取决于特征值是否超过阈值 Binarizer(*, threshold0.0, copyTrue)参数: threshold&#xf…

AGI—从GPT和大型语言模型中汲取的经验教训

点击蓝字 关注我们 关注并星标 从此不迷路 计算机视觉研究院 公众号ID|计算机视觉研究院 学习群|扫码在主页获取加入方式 论文地址:https://arxiv.org/pdf/2306.08641.pdf 计算机视觉研究院专栏 Column of Computer Vision Institute 人工智能…

【计算机视觉 | 图像分类】arxiv 计算机视觉关于图像分类的学术速递(6月 29 日论文合集)

文章目录 一、分类|识别相关(12篇)1.1 Pseudo-Bag Mixup Augmentation for Multiple Instance Learning Based Whole Slide Image Classification1.2 Improving Primate Sounds Classification using Binary Presorting for Deep Learning1.3 Challenges of Zero-Shot Recognit…

万物分割SAM家族 越发壮大!HQ-SAM、FastSAM 和 FasterSAM(MobileSAM)

卧剿,6万字!30个方向130篇!CVPR 2023 最全 AIGC 论文!一口气读完。 1、(更高质量)Segment Anything in High Quality 最近的 Segment Anything Model (SAM) 代表了分割模型的一大飞跃,有强大的零…

从零实现深度学习框架——Seq2Seq机器翻译实战

引言 本着“凡我不能创造的,我就不能理解”的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导。 💡系列文章完整目录: 👉点此👈 要深入理解…

【你哥电力电子】 THE BUCK-BOOST 升降压斩波电路2

BUCK-BOOST电路2 2023年1月30日 nige in Tongji University #elecEngeneer 上链 文章目录 BUCK-BOOST电路26. CCM非理想能量守恒平均分析6.1 CCM非理想大信号平均模型6.2 CCM等效大信号平均模型6.3 CCM的DC电路模型6.4 CCM的小信号线性电路模型6.5 CCM非理想小信号传递函数6.…

【SaaS】多租户系统设计

文章目录 多租户系统设计一、SaaS 的系统分级二、应用程序必须支持多租户三、数据隔离方案3.1、独立应用独立库3.2、同一个应用程序,每个租户一个库3.3、同一个应用程序,同一个数据库3.4、分片多租户 四、我们的模型选择4.1、开发实践4.2、元数据/配置驱…