python flask 如何用多线程执行ssh并拷贝文件?

发布于 2022-09-05 04:36:01 字数 2190 浏览 26 评论 0

因为不知如何简化问题,这里就直接贴问题与代码了:

目前在做一个CMS系统,可以在线编辑一个表单,表单会生成一个JSON数据并保存到数据库中,当我点击发布的时候,这个JSON数据会先写入到本地文件,并通过SSH登录到几台服务器中,然后把这个文件拷贝到各个服务器的一个路径下。

目前存在的问题是:当一个用户点击发布的时候,执行时间比较长,因为要登录好几个服务器,这个时候其他人点击的时候要等待这个逻辑处理完才会继续处理。

不知道大家有什么优化方法,我能想到的是多线程,比如整个逻辑放到一个线程里面去做,或者发布时,向每个服务器发布放到不同线程里?

另外,因为是python新手,不清楚应该在哪里创建线程,在API层?还是service层?

下面是简化的代码流程:

首先是API层面,调用service层的publish_detail方法:

# api.py
@bp.route('/activity/publish', methods=['POST'])
def detail_publish():
    detail_service = DetailService()
    activity_id = int(request.form['activity_id'])
    result = detail_service.publish_detail( activity_id )
    return jsonify_with_data('')

然后转到service,精简过程如下:

class DetailService( object ):

    def publish_detail( id ):
        # 获取数据详情
        detail = DetailModel.query.filter_by( id = id ).one()
        # 服务器信息
        servers = ['192.168.10.20', '192.168.10.21', '192.168.10.22']
        root_path = '/home/work/cms_data'
        # 将数据写入到本地文件
        save_res = self.__save_json_to_file( activity_id )
        pub_path, file_name, file_path = save_res
        # 执行发布流程
        process_res = self.__send_file_to_server( servers, root_path, pub_path, file_name, file_path )
        return True

最后是发布流程,过程继续简化一下:

# 发布流程
def __send_file_to_server( self, servers, root_path, pub_path, file_name, file_path ):
    # 循环发布
    for host in servers:
        # 1、ssh登录
        login_res = ssh_client.connect( host )
        # 2、创建文件夹
        mkdir_res = ssh_client.do('mkdir -p' + ' ' + target_path)
        # 3、scp拷贝文件到服务器
        send_res = ssh_client.send_to( file_path, target_path + file_name )
        # 4、远程文件备份
        cp_res = ssh_client.do('cp' + ' ' + target_path + target_file_name + ' ' + target_backup_path + file_name)
        # 5、文件重命名
        mv_res = ssh_client.do('mv' + ' ' + target_path + file_name + ' ' + target_path + target_file_name )
        # 6、关闭链接
        ssh_client.close()
        # 7、记录发布成功的机器
        sended_server_arr.append( server )
    # 删除本地文件
    os.remove( file_path )
    return True

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

澜川若宁 2022-09-12 04:36:01

这类场景是ansible的强项

永言不败 2022-09-12 04:36:01

使用celery类似的队列。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文