用POST请求在Linux之间传输文件(Python在Linux间传输文件)

背景

实际需求:

  • 已通过iperf和dd命令测试过两台不同区域之间的Linux服务器带宽,均为1000Mb网络。
  • 但发送post请求传输文件至对象存储时,总是卡在14Mb/s。
  • 除了排查区域之间的防火墙,也应该尝试检查Linux(KylinV10)之间是否存在默认系统配置限制了POST请求发送文件的带宽。
  • 因此:须在两台KylinV10之间直接通过POST请求发送文件,通过iftop监控网络带宽,排除操作系统对post带宽限制的可能。

解决:

  • A服务器上使用python编写server端程序,接收post请求,并将文件转存至文件目录。
  • B服务器上创建测试文件,通过post请求发送至A服务器。
  • 在A/B上运行iftop工具监控网络带宽、检查目标目录是否成功转存文件。

扩展:

  • 在禁用ssh和22端口的情况下,可通过rest接口在Linux之间传输大文件。

解决

1.安装python依赖库:flask和request

在A服务器上安装python程序需要的环境

dnf install python3
dnf install python3-pip
pip3 install requests -i https://mirrors.aliyun.com/pypi/simple/
pip3 install flask -i https://mirrors.aliyun.com/pypi/simple/

离线安装python和pip模块时,可下载我整理的rpm和whl压缩包(资源已上传,等待审核,需要区分不同操作系统版本),上传至Linux服务器解压后执行以下命令:
若有需要下载不同python版本(python3.6和3.7)对应的库,可使用以下命令:

pip3 download requests -i https://mirrors.aliyun.com/pypi/simple/
pip3 download flask -i https://mirrors.aliyun.com/pypi/simple/
#然后再打包至离线环境使用

离线安装python module模块的命令:

# 模块有依赖包的把所有包放在一个文件夹下,执行以下命令安装
pip install --no-index --find-link=./python-whl flask
##--no-index   不检查包索引中可用信息
##--find-links  从指定的目录下找离线包

KylinV10-SP2(sword)参考以下命令:

#使用本地repo源安装python
tar -zxvf czm-231108-KylinV10-PythonREST.tgz 
cp python-rpm/python.repo /etc/yum.repos.d/
sudo dnf install python3
sudo dnf install python3-pip
#pip安装本地whl模块
cd pip-module/
ll
total 1216
-rw-r--r-- 1 sysma sysma 158334 Nov  8 14:40 certifi-2023.7.22-py3-none-any.whl
-rw-r--r-- 1 sysma sysma 136822 Nov  8 14:40 charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
-rw-r--r-- 1 sysma sysma  97941 Nov  8 14:40 click-8.1.7-py3-none-any.whl
-rw-r--r-- 1 sysma sysma 101817 Nov  8 14:40 Flask-2.2.5-py3-none-any.whl
-rw-r--r-- 1 sysma sysma  61538 Nov  8 14:40 idna-3.4-py3-none-any.whl
-rw-r--r-- 1 sysma sysma  22934 Nov  8 14:40 importlib_metadata-6.7.0-py3-none-any.whl
-rw-r--r-- 1 sysma sysma  15749 Nov  8 14:40 itsdangerous-2.1.2-py3-none-any.whl
-rw-r--r-- 1 sysma sysma 133101 Nov  8 14:40 Jinja2-3.1.2-py3-none-any.whl
-rw-r--r-- 1 sysma sysma  25427 Nov  8 14:40 MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
-rw-r--r-- 1 sysma sysma  62574 Nov  8 14:39 requests-2.31.0-py3-none-any.whl
-rw-r--r-- 1 sysma sysma  33232 Nov  8 14:40 typing_extensions-4.7.1-py3-none-any.whl
-rw-r--r-- 1 sysma sysma 124213 Nov  8 14:40 urllib3-2.0.7-py3-none-any.whl
-rw-r--r-- 1 sysma sysma 233551 Nov  8 14:40 Werkzeug-2.2.3-py3-none-any.whl
-rw-r--r-- 1 sysma sysma   6758 Nov  8 14:40 zipp-3.15.0-py3-none-any.whl

pip install --no-index --find-link=. flask

CentOS-7.6.1810参考以下命令:

#解压已准备好的repo本地文件包
tar -zxvf czm-231109-CentOS.pythonRest.tgz 
cd /home/sysma/czm-231109-CentOS.pythonRest/

#复制repo文件到系统目录
cp CentOS-Python.repo /etc/yum.repos.d/

#安装python3和pip3
yum install python3 -y

#安装下载至本地的flask库
cd /home/sysma/czm-231109-CentOS.pythonRest/python-whl/
pip3 install --no-index --find-link=. flask

2.编写server端程序:接收post传输文件请求

在A服务器上创建python程序文件,直接复制后续代码,存储为xxx.py文件即可运行,此处我命名为01-PostReciveFile.py

具体程序代码如下:

from flask import Flask, request

app = Flask(__name__)

@app.route('/upload', methods=['POST'])		#指定接口名称为upload,指定请求方法为POST
def upload_file():
    if 'file' not in request.files:
        return 'No file part in the request', 400
    file = request.files['file']
    if file.filename == '':
        return 'No selected file', 400
    if file:
        file.save('/opt/' + file.filename)   #将接收的文件转存至/opt目录,可以改为任意目录,但要保证程序运行所属用户对目录有写权限。
        return 'File uploaded successfully', 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)	#指定程序使用的端口,可改为其它任意非系统端口。

然后即可直接运行程序 python 01-PostReciveFile.py,示例如下:

[root@jenkins ~]# python 01-PostReciveFile.py 
 * Serving Flask app '01-PostReciveFile'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000
 * Running on http://10.42.40.27:5000
Press CTRL+C to quit

出现上述内容即表明程序已经启动,监听端口为5000,上传接口为/upload。

3.创建测试文件:dd创建文件

在B服务器上创建测试文件,执行dd命令即可。of指定了testfile-2GB.mp4是要创建的文件名,bs=1M表示每个块的大小为1MBcount=2048表示要创建2048个块,可根据需要创建不同大小的文件。示例如下

dd if=/dev/zero of=testfile-2GB.mp4 bs=1M count=2048	#创建一个2GB文件
dd if=/dev/zero of=testfile-100MB.mp4 bs=1M count=100	#创建一个100MB文件

4.发起post请求传输文件

file=@后填入将要传输的测试文件,带路径也行,然后发送请求到运行server端程序的A服务器:
此处我的A(server端)服务器是10.42.40.27

 curl -X POST -F "[email protected] " http://10.42.40.27:5000/upload

5.监控网络带宽,检查文件转存状态

kylinV10\RockyLinux9\CentOS7都没有默认安装iftop命令,使用默认安装包源,使用yumdnf都没办法直接安装的话,直接下载这个安装包【iftop-1.0-0.21.pre4.el7.x86-64.rpm】,然后执行rpm -ivh 即可,确认该安装包可在el7和el8上安装。

rpm -ivh iftop-1.0-0.21.pre4.el7.x86_64.rpm 
[root@localhost python-rpm]# rpm -ivh iftop-1.0-0.21.pre4.el7.x86_64.rpm 
警告:iftop-1.0-0.21.pre4.el7.x86_64.rpm: 头V3 RSA/SHA256 Signature, 密钥 ID 352c64e5: NOKEY
Verifying...                          ################################# [100%]
准备中...                          ################################# [100%]
正在升级/安装...
   1:iftop-1.0-0.21.pre4.el7          ################################# [100%]
[root@localhost python-rpm]# 

用POST请求在Linux之间传输文件(Python在Linux间传输文件)_第1张图片
用POST请求在Linux之间传输文件(Python在Linux间传输文件)_第2张图片

结束

结论: post直接传输文件时,网络带宽没有限制。至少验证了KylinV10没有对POST请求带宽做限制。
进一步排查: 已确认2台不通区域Linux之间访问带宽低的问题原因是物理防火墙策略造成,已处理。

扩展

突然反应过除了测试,还有一个更好的使用场景:
在Linux的22端口被关闭、ssh协议被禁用的情况下,SCP命令无法使用的情况下,你可以通过REST接口指定其它TCP端口来传输文件了,朋友。

你可能感兴趣的:(linux,python,运维)