项目目录结构
讲解:
1、README是执行手册,相当于说明书
2、requirements记录的是项目所需依赖包版本信息
3、main是入口执行文件,用来开启服务
4、static存放的是前端文件
5、log是日志文件目录
6、libs/linux存放的是依赖包文件,离线开发时可以参考
7、.gitignore项目忽略文件,不记录到git版本库
8、monitor实际的项目主文件
- application是一个app(应用),entry逻辑封装文件,api数据交互文件
- Util是一个工具包,code定义code码,log日志文件,sql数据库文件,tool通用工具文件
打包部署目录结构
在项目目录结构的基础上增加build.py、install_monitor.sh、monitor.conf、setup.py
讲解:
9、setup收集TAR包信息
10、build打whl、tgz包
11、monitor.conf配置monitor服务信息(项目以supervisor进行托管,所以样式遵循supervisor标准写入样式)
12、install_monitor解压部署项目到指定路径并将服务加载到supervisor系统配置中
一、代码录入
##此文章只是做打包演示,README、.gitignore等文件不做过多编辑。查询更多setup打包信息
http://www.imooc.com/article/253042
https://blog.konghy.cn/2018/04/29/setup-dot-py/
- main.py
import uvicorn
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from monitor.application import entry
# 创建FastAPI对象
app = FastAPI()
# 注册FastAPI蓝图
app.include_router(entry.router, prefix="/api")
# 绑定前端文件文件
app.mount("/", StaticFiles(directory="static"), name="static")
if __name__ == "__main__":
uvicorn.run(
app=app,
host="0.0.0.0",
port=9238
)
- entry.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/test")
def test():
return "Hello World"
- setup.py
setup脚本是python使用Distutils来构建、分发以及安装模块活动的中心。它的目的是使软件正确安装
# cython是python的一个扩展,使得python具有能够兼容C/C++的能力,目的还是为了弥补python在执行效率上的短板, 此外也可以通过cython对核心模块进行编译起到一定的代码保护作用。它既可以编译.pyx文件也可以编译.py文件
from Cython.Build import cythonize
from Cython.Distutils import build_ext
from setuptools import setup
from setuptools.extension import Extension
setup(
# 下面4行内容可以写进setup.cfg文件中,如果setup.py和setup.cfg均有相同key,那么以setup.py中的值为准
name="monitor",
version="1.0.0",
description="description",
install_requires=[],
ext_modules=cythonize(
[
# 空文件不写也是可以的,为了演示效果,第一个参数名字(多种写法,其它写法请自行百度),第二个参数文件路径
Extension("__init__", ["monitor/__init__.py"]),
Extension("__init__", ["monitor/application/__init__.py"]),
Extension("entry", ["monitor/application/entry.py"])
],
build_dir="build",
language_level=3,
compiler_directives=dict(always_allow_keywords=True)
),
cmdclass=dict(build_ext=build_ext),
packages=[] # 打包后的wheel文件中不含源码(.py)
)
- build.py
import os
import shutil
import subprocess
#名称版本与setup文件中对应
version = "1.0.0"
name = "monitor"
# 1、执行后生成文件夹[build、dist、{项目名,此处就是monitor}.egg-info]
ret=subprocess.run(["/usr/local/bin/python3.7", "setup.py", "bdist_wheel"], stderr=subprocess.STDOUT)
print(ret.stdout)
# 2、建一个纯净目录,存放步骤一未收录的文件&文件夹
# 一、删除上一次打包后的遗留
ret=subprocess.run(["rm", "-rf", f"dist/{name}-{version}"], stderr=subprocess.STDOUT)
print(ret.stdout)
# 二、新建文件夹
if not os.path.exists(f"dist/{name}-{vaersion}"): os.mkdir(f"dist/{name}-{version}")
# 三、移动未收录文件
shutil.copyfile("main.py", f"dist/{name}-{version}/main.py")
shutil.copyfile("README.md", f"dist/{name}-{version}/README.md")
shutil.copyfile("requirements.txt", f"dist/{name}-{version}/requirements.txt")
shutil.copyfile("static", f"dist/{name}-{version}/static")
ret=shutil.copyfile("log", f"dist/{name}-{version}/log")
print(ret.stdout)
# 3、建虚拟环境、装包、tar包
# 一、切换当前位置;创建虚拟环境
os.chdir(f"dist/{name}-{version}")
ret=subprocess.run("/usr/local/bin/python3.7 -m venv venv", shell=True, stderr=subprocess.STDOUT)
print(ret.stdout)
ret=subprocess.run("venv/bin/pip install ../../libs/linux/*.whl", shell=True, stderr=subprocess.STDOUT)
print(ret.stdout)
# 二、安装步骤一生成的whl包
ret=subprocess.run(["venv/bin/pip", "install", f"--target=../{name}-{version}-cp37-cp37m-linux_x86_64.whl"], shell=True, stderr=subprocess.STDOUT)
print(ret.stdout)
# 三、清除原遗留并tar新包
os.chdir("..")
if os.path.exists(f"{name}-{version}.tgz"): os.remove(f"{name}-{version}.tgz")
ret=subprocess.run(["tar", "-zcf", f"{name}-{version}.tgz", f"{name}-{version}/"],stderr=subprocess.STDOUT)
print("tar ok.")
- monitor.conf
[program:monitor]
# 与install_monitor文件中解压后的路径对应
directory=/opt/monitor/monitor-1.0.0
# 启动服务的命令行,main.py存在目录即为directory对应目录
commmand=/opt/momnitor/monitor-1.0.0/venv/bin/python3.7 main.py
autostart=true
autorestart=true
# stopsignal=TERM
startsecs=5
user=root
stdout_logfile=None
stderr_logfile=None
- install_monitor.sh
#!/bin/bash
# check whether run the script with root user
if [`echo $USER` != "root"];then
echo -e "\033[31mYou are not root. Please switch to root and run this script again.\033[0m"
exit 0
fi
echo "start installing."
echo "installing monitor"
mkdir /opt/monitor
tar -xvf dist/monitor-1.0.0.tgz -C /opt/monitor/
cp monitor.conf /etc/supervisor/conf.d/
supervisorctl update
# supervisorctl reload
supervisorctl status
# supervisorctl stop monitor
# supervisorctl start monitor
# supervisorctl restart monitor
echo "ALL is ok."
二、使用步骤
1.python执行build.py
python3.7 build.py
1.执行install_monitor.sh
sh ./install_monitor.sh