Linux部署python web项目Flask + gunicorn + nginx

文章目录

  • 一、安装python&使用虚拟环境
  • 二、python程序重要参数加密
    • 2.1 非对称加密(RSA)
    • 2.2 生成密钥对
    • 2.4 以连接数据库参数加密为例
      • 2.4.1 工具类RSA.py
  • 三、一个简单的Flask项目
  • 四、安装配置gunicorn
  • 4.1 安装
    • 4.2 启动/配置(选择eventlet)
      • 4.2.1 命令行方式配置参数
      • 4.2.2 配置文件方式配置参数
  • 五、安装配置nginx
    • 5.1 安装
    • 5.2 配置
  • 六、运维
    • 6.1 启动gunicorn服务
    • 6.2 停止gunicorn服务

一、安装python&使用虚拟环境

参见Arch Linux 定时运行python脚本(crontab)

二、python程序重要参数加密

2.1 非对称加密(RSA)

用某用户密钥加密后所得的信息,只能用该用户的解密密钥才能解密。如果知道了其中一个,并不能计算出另外一个。因此如果公开了一对密钥中的一个,并不会危害到另外一个的秘密性质。称公开的密钥为公钥;不公开的密钥为私钥。
参考“公钥加密”

  • 生成RSA密钥对
  • 私钥存储在服务器上(运维人员做好秘钥管理)
  • 公钥公开给开发人员,用于代码中进行重要配置加密

2.2 生成密钥对

安装pycryptodome

pip install pycryptodome
from Crypto.PublicKey import RSA

key = RSA.generate(2048)
private_key = key.export_key()
with open("private.pem", "wb") as f:
    f.write(private_key)

public_key = key.publickey().export_key()
with open("public.pem", "wb") as f:
    f.write(public_key)

2.4 以连接数据库参数加密为例

【RSA加密/解密】PKCS1_OAEP和PKCS1_v1_5

2.4.1 工具类RSA.py

from Crypto.Cipher import PKCS1_OAEP as PKCS1_cipher
from Crypto.PublicKey import RSA
# 读取密钥
def get_key(path):
    with open(path) as f:
        pem_data = f.read()
        return RSA.importKey(pem_data)
# 公钥加密
def encrypt(msg, pub_path):
    key = get_key(pub_path)
    cipher = PKCS1_cipher.new(key)
    encrypt_msg = cipher.encrypt(msg.encode("utf-8"))
    return base64.b64encode(encrypt_msg).decode()
# 私钥加密
def decrypt(msg, pri_path):
    key = get_key(pri_path)
    cipher = PKCS1_cipher.new(key)
    decrypt_data = cipher.decrypt(base64.b64decode(msg))
    return decrypt_data.decode("utf-8")
  
if __name__ == '__main__':
    original_msg = "hello world"
    encrypted_data = encrypt(original_msg, "./pub_key.pem")
    print("encrypt_data:", encrypted_data)
    decrypted_data = decrypt(encrypted_data, "./pri_key.pem")
    print("decrypt_data:", decrypted_data)

三、一个简单的Flask项目

pip install Flask

my_first_flask.py

from flask import Flask, render_template

app = Flask(__name__, template_folder="template")

@app.route("/t/hello")
def hello_world():
    return "<p>Hello, World!</p>"
@app.route("/t/index")
def index():
	return render_template('index.html')

template/index.html

<h1>index</h1>

四、安装配置gunicorn

4.1 安装

Web项目开启异步workers

$ pip install gunicorn
# web 项目必须启用 Async Workers(使用eventlet)
$ pip install greenlet            # Required for both
$ pip install eventlet            # For eventlet workers
# web 项目必须启用 Async Workers(使用gevent)
$ pip install greenlet            # Required for both
$ pip install gevent              # For gevent workers

4.2 启动/配置(选择eventlet)

参考博客
配置说明-官网

4.2.1 命令行方式配置参数

# 运行
# -k 配置使用workers 默认sync(同步),异步根据不同安装选择eventlet/gevent
nohup python -m gunicorn -w 5 -k eventlet -b 0.0.0.0:9999 -t 120 my_first_flask:app >> my_first_flask.log 2>&1 &

# 根据进程号优雅关闭
kill -TERM 13078

4.2.2 配置文件方式配置参数

在这里插入图片描述
gunicorn.conf.py


# **运行配置**

# 并行工作进程数
workers = 4
 
# 指定每个工作者的线程数
threads = 2
 
# 使用nginx反向代理,默认本地访问端口 9999
bind = '127.0.0.1:9999'

## 修改是否重新加载
#reload = True

#
#daemon = True

## 超时时间,默认30
timeout=30

worker_class='eventlet'

# **日志文件配置**
#loglevel="info"
#accesslog="log/access.log"
#errorlog="log/error.log"
logconfig_dict = {
    'version':1,
    'disable_existing_loggers': True,
    "root": {"level": "INFO", "handlers": ["root_handler"]},
    'loggers':{
        "gunicorn.error": {
            "level": "INFO",# 打日志的等级可以换的,下面的同理
            "handlers": ["error_file"], # 对应下面的键
            "propagate": 1,
            "qualname": "gunicorn.error"
        },

        "gunicorn.access": {
            "level": "DEBUG",
            "handlers": ["access_file"],
            "propagate": 0,
            "qualname": "gunicorn.access"
        }
    },
    'handlers':{
        "error_file": {
            "class": "logging.handlers.RotatingFileHandler",
            "backupCount": 3,
           # "when":"D",
           # "interval":1,
            "maxBytes": 1024 * 1024 * 10,
            "formatter": "generic",
            "encoding": "utf-8",
            "filename": "log/gunicorn.error.log"
        },
        "access_file": {
            "class": "logging.handlers.TimedRotatingFileHandler",
            "backupCount": 3,
            "when":"D",
            "interval":1,
            "formatter": "generic",
            "filename": "log/gunicorn.access.log",
        },
        "root_handler":{
            "class": "logging.handlers.TimedRotatingFileHandler",
            "backupCount": 3,
            "when":"D",
            "interval":1,
            "formatter": "generic",
            "filename": "log/gunicorn.root.log",
        }
    },
    'formatters':{
        "generic": {
            "format": "'[%(process)d] [%(asctime)s] %(levelname)s [%(filename)s:%(lineno)s] %(message)s'", # 打日志的格式
            "datefmt": "[%Y-%m-%d %H:%M:%S %z]",# 时间显示方法
            "class": "logging.Formatter"
        },
        "access": {
            "format": "'[%(process)d] [%(asctime)s] %(levelname)s [%(filename)s:%(lineno)s] %(message)s'",
            "class": "logging.Formatter"
        }
    }
}
# gunicorn当前的process id
pidfile="gunicorn.pid"

日志配置参照

五、安装配置nginx

5.1 安装

(1)使用包管理工具

# 安装
sudo pacman -S nginx

# 验证是否安装成功
nginx -v
# 查看当前是否启动nginx(有master,worker)
ps -ef | grep nginx
# 查看当前nginx状态
systemctl status nginx
# 立即启动
systemctl start nginx
# 立即重启
systemctl restart nginx
# 设置开机自启动

(2)使用源码编译(TODO)

5.2 配置

/etc/nginx/nginx.conf

user http;
worker_processes auto;
worker_cpu_affinity auto;

events {
    multi_accept on;
    worker_connections 1024;
}

http {
    charset utf-8;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    server_tokens off;
    log_not_found off;
    types_hash_max_size 4096;
    client_max_body_size 16M;
    log_format test 'upstat=$upstream_status';
    # MIME
    include mime.types;
    default_type application/octet-stream;

    # logging
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log warn;

    # load configs
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;    

    server {
    	listen 9888;
	server_name 172.XXX.XXX.XXX;
	location /test/ {
		proxy_pass http://localhost:9999/t/;
	}
	error_page 400 401 402 403 404 405 406 407 408 409 /40x.html;
	location = /40x.html {
		root /usr/share/nginx/html;
	}
        access_log /var/log/nginx/access_test.log test;
    }
}

假设本机ip地址为:172.XXX.XXX.XXX。
访问:172.XXX.XXX.XXX:9888/test/path1,重定向到localhost:9999/t/path1
访问:172.XXX.XXX.XXX:9888/test/hello,重定向到localhost:9999/t/hello

六、运维

6.1 启动gunicorn服务

文件名:start

#!/bin/bash

if [ "$#" -lt 1 ]; then
	echo "Please provide one argument."
else
	source ../bin/activate
	python -m gunicorn --check-config $1 
	python -m gunicorn -c gunicorn.conf.py $1 -D
	deactivate
fi
[rebecca@study src]$. start my_first_flask:app

6.2 停止gunicorn服务

文件名:stop

#!/bin/bash

head -n 1 gunicorn.pid | xargs kill -TERM 

[rebecca@study src]$. stop

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue打包exe之electron-quick-start的npm install 报错

vue打包exe之electron-quick-start的npm install 报错 1、github地址2、问题3、解决4、其他(打包exe)参考 1、github地址 https://github.com/electron/electron-quick-start2、问题 我使用的pnpm install正常安装&#xff0c;执行npm start提示错误 3、解决 在package.js…

【LLM多模态】文生视频综述From Sora What We Can See: A Survey of Text-to-Video Generation

note 现在很多主流的文生视频应该还是Diffusion-based 基于扩散模型的方法这篇综述将现有研究按照三个维度进行分类&#xff1a;进化生成器&#xff08;Evolutionary Generators&#xff09;、卓越追求&#xff08;Excellent Pursuit&#xff09;、现实全景&#xff08;Realis…

【学习笔记】MIPI

MIPI介绍 MIPI是由ARM、Nokia、ST、IT等公司成立的一个联盟&#xff0c;旨在把手机内部的接口如存储接口&#xff0c;显示接口&#xff0c;射频/基带接口等标准化&#xff0c;减少兼容性问题并简化设计。 MIPI联盟通过不同的工作组&#xff0c;分别定义一系列手机内部的接口标…

植物大战僵尸杂交版V2.5.1下载(最新版)

2.5.1版本更新公告&#xff1a; 在最新的2.5.1版本中&#xff0c;游戏对“两面夹击”关卡进行了多项重要调整。出怪倍率和种类均有所降低&#xff0c;部分关卡的初始阳光量也得到了调整&#xff0c;以增强玩家的策略性。同时&#xff0c;玩家可以在这些关卡中使用投手类植物&a…

sysbench 命令:跨平台的基准测试工具

一、命令简介 sysbench 是一个跨平台的基准测试工具&#xff0c;用于评估系统性能&#xff0c;包括 CPU、内存、文件 I/O、数据库等性能。 ‍ 比较同类测试工具 bench.sh 在上文 bench.sh&#xff1a;Linux 服务器基准测试中介绍了 bench.sh 一键测试脚本&#xff0c;它对…

RabbitMQ下载安装运行环境搭建

RabbitMQ运行环境搭建 1、Erlang及RabbitMQ安装版本的选择2、下载安装Erlang2.1、下载Erlang2.2、安装Erlang2.2.1、安装Erlang前先安装Linux依赖库2.2.2、解压Erlang压缩包文件2.2.3、配置2.2.4、编译2.2.5、安装2.2.6、验证erlang是否安装成功 3、RabbitMQ下载安装3.1、下载3…

FortiGate 无线组网

无线管理与配置 FortiAP 连接 internal 接口之后自动获得 ip 地址&#xff1a;192.168.1.xxx/24在 FortiGate 中创建 SSIDFortiGate 自动发现 FortiAP&#xff0c;将 FortiAP 添加到 FortiGate将 SSID 和 FortiAP 关联创建防火墙策略 下面我们就来一起看看在 FortiGate 中该如…

MT6765/MT6762(R/D/M)/MT6761(MT8766)安卓核心板参数比较_MTK联发科4G智能模块

联发科Helio P35 MT6765安卓核心板 MediaTek Helio P35 MT6765是智能手机的主流ARM SoC&#xff0c;于2018年末推出。它在两个集群中集成了8个ARM Cortex-A53内核&#xff08;big.LITTLE&#xff09;。四个性能内核的频率高达2.3GHz。集成显卡为PowerVR GE8320&#xff0c;频率…

前端——js基础

一、JavaScript &#xff08;简称js&#xff09;——js可以给网页实现一个动态效果 1.JavaScript 组成 - 核心语法 ECMScipt 简称(es): 规范js的基本语法 1.es是js的语法规范 管理者 2.js是es的实现 操作者 - DOM > 文档对象 提供js操作 (例如…

Golang | Leetcode Golang题解之第423题从英文中重建数字

题目&#xff1a; 题解&#xff1a; func originalDigits(s string) string {c : map[rune]int{}for _, ch : range s {c[ch]}cnt : [10]int{}cnt[0] c[z]cnt[2] c[w]cnt[4] c[u]cnt[6] c[x]cnt[8] c[g]cnt[3] c[h] - cnt[8]cnt[5] c[f] - cnt[4]cnt[7] c[s] - cnt[6]…

jq实现:点击图片时弹出详情弹窗,判断拖动图片时不弹出

1.需求分析: 要实现点击图片时弹出详情弹窗,但在拖动时不弹出,可以使用 jQuery 来判断用户的操作。可以通过设置一个标志变量来判断用户是否在拖动图片。 并且在鼠标拖动某个图片时将其层级设置为最上面,可以使用 jQuery 结合 CSS 的 z-index 属性 说明 : 标志变量:使用…

传输层TCP协议

一、TCP协议格式 我们看到报头固定有20字节&#xff0c;最后选项大小不固定。 4位首部长度&#xff08;二进制0000 ~ 1111&#xff0c;十进制范围[0, 15]&#xff09;单位是4字节&#xff08;存放字节大小范围[0, 60]&#xff09;包括了20字节固定长度 选项长度。若选项大小为…

PWA(Progressive web APPs,渐进式 Web 应用): manifest.json、 Service Worker

文章目录 引言I 什么是 PWA功能特性技术上分为三个部分:II Web 应用清单将Web 应用清单文件链接到站点manifest.json字段说明III Service WorkerService worker 本质Service worker 运行在 worker 上下文注册服务辅助角色扩展知识将 PWA 作为脱机应用定义当前文档与被链接文档…

用Python实现运筹学——Day 4: 线性规划的几何表示

一、学习内容 线性规划的几何表示&#xff1a; 线性规划问题的解通常位于一个凸多边形&#xff08;即可行解空间&#xff09;的顶点上&#xff0c;这意味着在求解线性规划问题时&#xff0c;只需要找到可行解空间中的顶点并计算出目标函数值&#xff0c;再选择其中的最优解。 可…

C++之分割字符串的两种方式

方式一 #include <string> #include <vector> #include <sstream> #include <iostream>std::vector<std::string> split(const std::string& str, char delim) {std::stringstream ss(str);std::string item;std::vector<std::string>…

C语言贪吃蛇小游戏演示和说明

C语言贪吃蛇小游戏演示和说明 设计贪吃蛇游戏的主要目的是让大家夯实C语言基础&#xff0c;训练编程思维&#xff0c;培养解决问题的思路&#xff0c;领略多姿多彩的C语言。 游戏开始后&#xff0c;会在中间位置出现一条只有三个节点的贪吃蛇&#xff0c;并随机出现一个食物&am…

keepalived+lvs集群,实现高可用

环境准备&#xff1a;两台虚拟机&#xff0c;关闭防火墙&#xff0c;selinux,配置阿里云仓库&#xff0c;配置epel 192.168.88.21 dr1 负载均衡器 master 192.168.88.22 dr2 负载均衡器 backup 192.168.88.23 rs1 web1 192.168.88.24 rs2 web2 实验说明&…

项目启动错误

说明&#xff1a;记录一次项目启动&#xff0c;报数据库访问错误&#xff0c;如下&#xff1a; 错误信息&#xff1a;Invalid default&#xff1a;public abstract java.lang.Class tk.mybatis.spring.annotation.MapperScan.fatoryBean() 解决 没有引入mybatis依赖&#xff…

通信工程学习:什么是VIM虚拟化基础设施管理器

VIM:虚拟化基础设施管理器 VIM(Virtualized Infrastructure Manager)虚拟化基础设施管理器,是一种负责管理和控制虚拟化环境中所有虚拟资源的工具和系统。以下是关于VIM虚拟化基础设施管理器的详细解释: 一、定义与功能 VIM是网络功能虚拟化(NFV)架构中…

HarmonyOS---权限和http/Axios网络请求

网络请求(http,axios) 目录 一、应用权限管理1.1权限的等级1.2授权方式1.3声明权限的配置1.4如何向用户进行申请 二、内置http请求使用三、Axios请求使用&#xff08;建议&#xff09;3.1 使用方式一3.2 使用方式二&#xff08;建议&#xff09; 一、应用权限管理 应用权限保护…