释放删除

47 阅读3分钟

可执行程序

可执行程序包含:

  1. 可执行程序释放程序
  2. 所有算法相关程序

思路:

  1. 执行可执行程序
  2. 释放算法程序
  3. 执行启动脚本,使得算法程序放入内存执行
  4. 算法程序内部删除 算法文件和启动脚本(所有多线程方案不成立,因为无法保证执行先后)

可执行程序释放程序

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地址