可执行程序
可执行程序包含:
- 可执行程序释放程序
- 所有算法相关程序
思路:
- 执行可执行程序
- 释放算法程序
- 执行启动脚本,使得算法程序放入内存执行
- 算法程序内部删除 算法文件和启动脚本(所有多线程方案不成立,因为无法保证执行先后)
可执行程序释放程序
import os
import pathlib
# 复制文件
def copy_file(file1, file2):
f1 = open(file1, "rb") # 以读取模式打开file1
f2 = open(file2, "wb") # 以清空写模式打开file2
content = f1.readline() # 将第一行数据赋给content
while len(content) > 0: # 如果读取到的数据长度不为0则循环执行
f2.write(content) # 在file2里写下content
content = f1.readline() # 再读一行赋给content
f1.close() # 关闭file1
f2.close()
# 复制路径
def copy_dir(dir1, dir2):
# 获取被复制目录中的所有文件信息
dlist = os.listdir(dir1) # 以列表模式赋给dlist
# 创建新目录
os.mkdir(dir2) # 创建新文件夹dir2
# 遍历所有文件并执行文件复制
for f in dlist: # 让f在dlist中遍历
# 为遍历的文件添加目录路径
file1 = os.path.join(dir1, f) # 将f遍历出的文件名给file1(dir1+f即路径+文件名)
file2 = os.path.join(dir2, f) # 同样也给file2
# 判断是否是文件
if os.path.isfile(file1): # 判断是否为文件的方式为os库中的函数 os.path.isfile(文件名)
copy_file(file1, file2) # 调用自定义的copy_file函数复制文件
if os.path.isdir(
file1):
# 如果是文件夹的话 那就调用自身(自身就是复制文件夹嘛)e而处理的不是dir1,dir2,是file1,file2,因为此时文件夹同文件一起被f遍历,此处判断的就是f遍历出的是文件还是文件夹
copy_dir(file1, file2) # 调用自身 递归思想
folder = pathlib.Path(__file__).parent.resolve() # 当前路径
# 将当前文件夹的文件释放到对应位置
copy_file(f"{folder}/employee.py","/home/app/employee.py")
copy_file(f"{folder}/start.sh","/home/app/start.sh")
# 使用启动脚本
os.system("bash /home/app/start.sh")
启动脚本
#!/bin/bash
python /home/app/employee.py
算法程序程序执行清空操作
from flask import Flask
class MyFlaskApp(Flask):
def run(self, host=None, port=None, debug=None, load_dotenv=True, **options):
if not self.debug or os.getenv('WERKZEUG_RUN_MAIN') == 'true':
with self.app_context():
# 想要执行的代码,因为已经将代码放入内存中,所以可以删除
os.system("rm -rf /home/app/employee.py")
super(MyFlaskApp, self).run(host=host, port=port, debug=debug, load_dotenv=load_dotenv, **options)
app = MyFlaskApp(__name__)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
将可执行程序打包
打包
pyinstaller --add-data "resource/*:." --onefile start.py
将数据文件全部放入可执行程序,并将数据文件和可执行文件打包成一个文件,否则它会将程序和数据分开放
书写Dockerfile
FROM python:3.9
# 升级apt-get
RUN apt-get update && apt-get install -y \
libgl1-mesa-glx \
libglib2.0-0 \
libsm6 \
libxext6 \
libxrender1
# 换源
RUN pip3 config set global.index-url https://mirror.baidu.com/pypi/simple
RUN pip3 config set global.extra-index-url 'https://pypi.org/simple https://mirrors.aliyun.com/pypi/simple/ https://pypi.tuna.tsinghua.edu.cn/simple'
# 升级pip
RUN pip install --upgrade pip
# 嘎嘎装环境
RUN pip install pyschedule \
pulp==2.0 \
vim \
pandas \
flask \
openpyxl
# 创建目录
RUN mkdir -p /home/app
# set default dir so that next commands executes in /home/app dir
# 将当前文件放入image的/home/app下
COPY . /home/app/
# 设置工作目录
WORKDIR /home/app
# 暴露接口
# EXPOSE 5000
# 执行启动程序,多条启动程序只执行最后一条
# CMD ["cd","/home/app"]
#CMD ["bash","./start.sh"]
CMD ["./my_app"]
将可执行文件和Dockerfile放到同一个路径下面
构建镜像
用当前路径下的Dockerfile创建镜像docker build -t 镜像名:版本号 .
运行容器
docker run -d --name 容器名 -p 3000:80 镜像名:版本号
查看执行情况
docker logs 容器名
监听接口
ssh -p 端口号 -N -f -L 127.0.0.1:3001:localhost:3000 用户名@IP地址