语言教育项目实战之二:Python管理多并发Web服务

liftword2周前 (06-04)技术文章4

背景

基于#python# Python的 Flask写了一个WEB服务,可以用来将文本转为语音。现在要发布到生产环境,需要启动多个进程并行服务,并再故障后能够自动恢复。初步考虑使用Gunicorn和Supervisor来管理此Web服务。在此之前找LLM 们咨询下,确定可行性和先进性。




大体而言,方案在中小规模服务上可行,后期可结合nginx做负载均衡,以及用celery进行异步任务会更加高效。下面介绍使用Gunicorn和#supervisor#管理服务进程。

Gunicorn

# 安装
pip install gunicorn

# 支持异步
pip install gevent

# 命令行运行flask web服务
gunicorn -w 4 -k gevent -b 0.0.0.0:8000 \
  --timeout 120 \  # 超时时间(处理长语音)
  --access-logfile /var/log/gunicorn/access.log \
  --error-logfile /var/log/gunicorn/error.log \
  app:app
  
  # 也可以写一个配置文件,然后通过-c参数指定启动
  gunicorn -c gunicorn.conf.py app:app
  
  # 调试完毕后,可以让其后台运行
  gunicorn -c gunicorn.conf.py app:app --daemon
  
  

配置文件内容如下:

# 绑定的IP和端口
bind = "127.0.0.1:5000"

# 工作进程数
workers = 1

# 每个工作进程的线程数
threads = 2

# 工作模式,默认为sync同步模式
worker_class = "sync"

# 日志级别
loglevel = "info"

# 日志文件路径
accesslog = "log/access.log"
errorlog = "log/error.log"

# 设置超时时间
timeout = 60

# 设置最大请求数
max_requests = 1000

# 设置每个工作进程的最大请求数
max_requests_jitter = 50

# 设置是否守护进程模式
daemon = False

# 设置pid文件路径
pidfile = "tmp/gunicorn.pid"

手动启动、停止gunicorn服务,需要结合启动的flask服务名。如下,编制一个sh脚本:

#!/usr/bin/bash 

# 用gunicorn启动本项目服务,项目默认运行在项目根目录下,引用包应该以此为运行目录
DIR="${HOME}/code/pywebsvr"

# 检查python环境,虚拟环境是否已经创建,如果没有需要创建
init_python_env(){

	echo "INIT *** venv *** "

	if [ -d "${DIR}/venv" ]; then
		echo "python venv has been initted."
       	else
 		cd $DIR; 
		python3 -m venv venv ;
	fi
}


# 停止服务
stop_flask_service(){
	echo "STOP *** $SVR *** , the running processes : " $@
	for pid in $@
	do
		echo "Killing process with PID : $pid"
		kill -9 $pid
		sleep 3
	done 

}

# 启动服务
start_flask_service(){
	echo "START *** $SVR ***"
	cd $DIR
	init_python_env
	source venv/bin/activate ;
  # pip install -r requirements.txt;
  gunicorn -c dat/gunicorn_config.py $SVR --daemon
}
# 检查服务是否已经启动,如果没有,启动服务;如果有,则退出
check_flask_service_and_start(){
	echo "$ CHECK ***$SVR in $DIR running *** "

	flask_pid=$(pgrep -f "$SVR"|grep -v $)


	if [ -z "$flask_pid" ]; then
		echo -e "*** $SVR ***  is not running."
		start_flask_service
	else
		echo -e "*** $SVR *** is running."
	fi
}

# 检查服务是否已经启动,如果没有,启动服务;如果有,则重启服务
check_flask_service_and_restart(){
	echo "$ CHECK ***$SVR running *** "

	flask_pid=$(pgrep -f "$SVR" |grep -v $)


	if [ -z "$flask_pid" ]; then
		echo -e "*** $SVR ***  is not running."
		start_flask_service
	else
		echo -e "*** $SVR *** is running."
		stop_flask_service $flask_pid
		start_flask_service
	fi
}
# 检查服务是否已经启动,如果没有,什么都不做;如果有,则停止服务
check_flask_service_and_stop(){
	echo "$ CHECK ***$SVR  running *** "

	flask_pid=$(pgrep -f "$SVR"|grep -v $)


	if [ -z "$flask_pid" ]; then
		echo -e "*** $SVR ***  is not running."
	else
		echo -e "*** $SVR *** is running."
		stop_flask_service $flask_pid
	fi
}

然后编写start,stop,restart脚本

## start.sh
#!/usr/bin/bash 

#此脚本负责启动falsk服务。 可将实际的服务路径目录,和服务名修改即可;
SVR="src.main:app"


# !!! 不用修改下面的代码
script_path=$(dirname "$(readlink -f "$0")")
cd $script_path; source ./function_v2.sh ;
check_flask_service_and_start 


## stop.sh
#!/usr/bin/bash 

#此脚本负责启动falsk服务。 可将实际的服务路径目录,和服务名修改即可;
SVR="src.main:app"
#SVR="demo.gql_crud_users:app"

# !!! 不用修改下面的代码
script_path=$(dirname "$(readlink -f "$0")")
cd $script_path; source ./function_v2.sh ;
check_flask_service_and_stop


Supervisor

安装supervisor,#supervisor#可以用来管理各种服务和命令行程序。

# 安装
sudo apt-get install supervisor

编写配置文件,可参考下面的关键部分


[program:flask_app]
command=/home/release/bin/gunicorn -c /path/to/gunicorn.conf.py app:app
directory=/home/release/app
user=www-data  # 运行用户
autostart=true  # 系统启动时自动启动
autorestart=true  # 崩溃后自动重启
stderr_logfile=/var/log/flask_app.err.log
stdout_logfile=/var/log/flask_app.out.log

加载配置、启动、停止、查看状态

# 加载配置
sudo supervisorctl reread
sudo supervisorctl update

# 启动服务
sudo supervisorctl start flask_app

# 查看状态
sudo supervisorctl status flask_app

相关文章

Django后台管理系统(admin)的使用

Django自带的admin系统Django最强大的部分之一是自动生成的Admin界面。它读取模型数据来提供一个强大的、生产环境就绪的界面,使内容提供者能立即用它向站点中添加内容。它可以快速的开发出一...

利用Python监控儿子每天在电脑上面做了些什么

继打游戏、看视频等摸鱼行为被监控后,现在打工人离职倾向也会被监 控。有网友爆料称知乎正在低调裁员,视频相关部门几乎要裁掉一半。而在知乎裁员的讨论区,有网友表示企业安装了行为感知系统,该系统可以提前获知...

搭建Django后台管理前端API接口(本地)

一,创建Django项目我是使用的PyCharm创建的Django项目,如下图所示new_django.jpg二,关联Github首先在Github上创建一个新的项目,test_server。然后从P...

ubuntu部署python脚本为系统服务

以下是将Python脚本设置为Ubuntu系统服务的完整步骤:1. 创建系统服务文件创建一个新的systemd服务单元文件:sudo nano /etc/systemd/system/wechat_m...

Python每日一库|Celery (二)

在我之前的文章中,我向你介绍了 Celery 并进行了一些实际操作。如果你还没有阅读我之前的帖子,请阅读。Python每日一库|Celery (一)在这篇文章中,我们将讨论我们Celery的使用场景跟...

第13天|Django3.0项目实战,Django有后台?

如果实现销售管理系统,还要想实现部门管理系统那么狼狈的话,那要Django有啥用了?你要知道,Django可是号称:只要很少的代码,程序员就可以轻松轻松地完成一个后台管理系统所需要的大部分内容,并进一...