昨晚心血来潮,尝试用python写了一个ftp文件传输服务,可以接收指令,从远程ftp服务器同步指定目录数据,最后没用上,开源出来。

https://github.com/jadepeng/ftp_transfer_service.git

运行原理

  • 'task_server' 是一个web服务器,可以接收传入任务,接收到任务后,将task写入mysql
  • 启动任务后,'task_server'会扫描ftp文件列表,写入redis队列
  • transfer_client 是传输执行程序,可以多点部署,该程序会读取redis队列,进行文件下载

使用

配置

修改 .env 文件, 配置mysql和redis地址

  1. REDIS_SERVER=""
  2. REDIS_PORT=6380
  3. REDIS_PASSWORD=""
  4. MYSQL_HOST=""
  5. MYSQL_PORT=3306
  6. MYSQL_PASSWORD=""
  7. MYSQL_USER=""
  8. MYSQL_DB=""

启动服务

server 端

  1. python3 task_server.py

传输端,可以部署多个

  1. python3 transfer_client.py

接收任务

POST /task/

  1. {
  2. "taskId": "9",
  3. "serverPath": "/weblog",
  4. "storagePath": "/data",
  5. "host": "ftpServer",
  6. "port": 21,
  7. "user": "user",
  8. "password": "password"
  9. }

启动传输

GET /task/{taskId}/start

查看进度

GET /task/{taskId}/progress

实现简介

第一次用fastapi来写web服务,这里记录下有意思的地方。

配置

可以通过配置类实现app的配置参数,pydantic还可以加载env文件更新配置

setting.py

  1. from pydantic import BaseSettings
  2. class APISettings(BaseSettings):
  3. mysql_host: str = "127.0.0.1"
  4. mysql_port: int = 3306
  5. mysql_password: str
  6. mysql_user: str
  7. mysql_db: str
  8. redis_server: str = "127.0.0.1"
  9. redis_port: int = 6380
  10. redis_password: str
  11. max_wait_time_count: int = 10
  12. class Config:
  13. env_file = ".env"
  14. env_file_encoding = 'utf-8'

redis 队列

通过list实现队列,rpush,blpop

  1. import redis
  2. class RedisQueue(object):
  3. def __init__(self, name, namespace='queue', **redis_kwargs):
  4. self.__db= redis.Redis(**redis_kwargs)
  5. self.key = '%s:%s' %(namespace, name)
  6. def qsize(self):
  7. return self.__db.llen(self.key) # 返回队列里面list内元素的数量
  8. def put(self, item):
  9. self.__db.rpush(self.key, item) # 添加新元素到队列最右方
  10. def get_wait(self, timeout=None):
  11. item = self.__db.blpop(self.key, timeout=timeout)
  12. return item
  13. def get_nowait(self):
  14. item = self.__db.lpop(self.key)
  15. return item

redis BloomFilter

BloomFilter 可以用来去重

  1. import mmh3
  2. import redis
  3. class BloomFilter(object):
  4. def __init__(self, bf_key, bit_size=2000000, hash_count=4, start_seed=41, **redis_kwargs):
  5. self.bit_size = bit_size
  6. self.hash_count = hash_count
  7. self.start_seed = start_seed
  8. self.client = redis.Redis(**redis_kwargs)
  9. self.bf_key = bf_key
  10. def add(self, data):
  11. bit_points = self._get_hash_points(data)
  12. for index in bit_points:
  13. self.client.setbit(self.bf_key, index, 1)
  14. def madd(self, m_data):
  15. if isinstance(m_data, list):
  16. for data in m_data:
  17. self.add(data)
  18. else:
  19. self.add(m_data)
  20. def exists(self, data):
  21. bit_points = self._get_hash_points(data)
  22. result = [
  23. self.client.getbit(self.bf_key, index) for index in bit_points
  24. ]
  25. return all(result)
  26. def mexists(self, m_data):
  27. result = {}
  28. if isinstance(m_data, list):
  29. for data in m_data:
  30. result[data] = self.exists(data)
  31. else:
  32. result[m_data] = self.exists[m_data]
  33. return result
  34. def _get_hash_points(self, data):
  35. return [
  36. mmh3.hash(data, index) % self.bit_size
  37. for index in range(self.start_seed, self.start_seed +
  38. self.hash_count)
  39. ]

python的orm框架sqlalchemy

sqlalchemy 需要先定义ORM类

  1. class TransferTask(Base):
  2. __tablename__ = 'transfer_task'
  3. taskId = Column(String(255), primary_key=True, index=True)
  4. serverPath = Column(String(255), nullable=False)
  5. storagePath = Column(String(255), nullable=False)
  6. host = Column(String(255), nullable=False)
  7. port = Column(Integer, nullable=False)
  8. user = Column(String(255), nullable=False)
  9. password = Column(String(255), nullable=False)
  10. time = Column(DateTime, nullable=False, default=datetime.now)
  11. class TransferFailedFile(Base):
  12. __tablename__ = 'transfer_failed_file'
  13. id = Column(Integer, primary_key=True, index=True, autoincrement=True)
  14. taskId = Column(String(255), index=True)
  15. filePath = Column(String(1024), nullable=False)
  16. time = Column(DateTime, nullable=False, default=datetime.now)
  17. class TransferProgress(Base):
  18. __tablename__ = 'transfer_task_progress'
  19. taskId = Column(String(255), primary_key=True, index=True)
  20. total = Column(Integer, nullable=False)
  21. status = Column(Integer, nullable=False)
  22. finished = Column(Integer, nullable=False)
  23. failed = Column(Integer, nullable=False)
  24. time = Column(DateTime, nullable=False, default=datetime.now)
  25. if __name__ == '__main__':
  26. settings = APISettings()
  27. db = Database(settings.mysql_host, settings.mysql_port, settings.mysql_user, settings.mysql_password,
  28. settings.mysql_db)
  29. Base.metadata.create_all(db.engine)

FTP 文件传输服务的更多相关文章

  1. FTP文件传输服务

    FTP文件传输服务 一 .FTP 连接及传输的模式 l  控制连接:TCP21,用于发送FTP命令信息. l  数据连接:TCP 20, 用于上传下载数据. · 数据连接建立的类型: ·主动模式: 服 ...

  2. FTP文件传输服务!

    一.FTP  连接及传输模式 1.控制连接:TCP 21,用于发送 FTP 命令信息2.数据连接:TCP 20,用于上传.下载数据3.数据连接的建立类型: (1)主动模式:服务器主动发起数据连接 (2 ...

  3. 网站优化与Cdn文件传输服务

    网站优化与Cdn文件传输服务 如今互联网无处不在,其方便快捷.性质和低成本的经济特点,已经逐渐成为商务贸易.信息分发和数据交付的一个重要渠道.要想让数据的分发带来巨大的效益,那么网民的满意是唯一的办法 ...

  4. 【RL-TCPnet网络教程】第35章 FTP文件传输协议基础知识

    第35章      FTP文件传输协议基础知识 本章节为大家讲解FTP(File Transfer Protocol,文件传输协议)的基础知识,方便后面章节的实战操作. (本章的知识点主要整理自网络) ...

  5. FTP文件传输服务器原理

    FTP服务器,全称File Transfer Protocol Server,是在互联网上提供文件存储和访问服务的计算机,它们依照FTP协议提供服务.FTP,文件传输协议(File Transfer ...

  6. Python实现终端FTP文件传输

    实现终端FTP文件传输 代码结构: .├── client.py├── readme.txt└── server.py 运行截图: readme.txt tftp文件服务器 项目功能: * 客户端有简 ...

  7. WCF大文件传输服务

    由于项目需要,自己写一个基于WCF的大文件传输服务雏形.觉得有一定的参考价值,因此放在网上分享. 目前版本为v1.1特点如下: 1.文件传输端口为18650 2.上传和下载文件 3.支持获取文件传输状 ...

  8. SSIS 学习之旅 FTP文件传输-脚本任务

    这一章主要讲解一下用脚本怎么把CSV文件抛送到FTP服务器上 设计:   通过Demon库的Users表数据生成CSV文件.   生成后的CSV文件抛送到FTP指定目录下. 控件的使用这里就不做详细讲 ...

  9. Python自带HTTP文件传输服务

    一行命令搭建一个基于python的http文件传输服务 由于今天朋友想要一个文件,而我恰好有,因为这个文件比较大,网速不是很给力,所以想到了python自己有这么一个功能,这样不仅不需要下载其他软件, ...

随机推荐

  1. Mybatis实现简单的CRUD(增删改查)原理及实例分析

    Mybatis实现简单的CRUD(增删改查) 用到的数据库: CREATE DATABASE `mybatis`; USE `mybatis`; DROP TABLE IF EXISTS `user` ...

  2. java性能优化常用工具jps、jstat、jinfo

    jps:虚拟机进程状况工具 jps可以用来查看虚拟机进程,基本等同于ps -ef|grep java #查看jps的使用文档 [root@localhost script]# jps -help us ...

  3. 基于消息队列 RocketMQ 的大型分布式应用上云最佳实践

    作者|绍舒 审核&校对:岁月.佳佳 编辑&排版:雯燕 前言 消息队列是分布式互联网架构的重要基础设施,在以下场景都有着重要的应用: 应用解耦 削峰填谷 异步通知 分布式事务 大数据处理 ...

  4. matlab 图像保存时去除白边

    很是讨厌MATLAB输出图像时自带的白边,尤其是当导出.eps格式时,很难通过编辑图片来去掉白边.网上有很多代码但是没有注释,有很多坑要填.这里提供一个去除白边的代码,自己在别人的基础上修改了而且加了 ...

  5. java+selenium+testNG+Allure报表【新增截图到报表功能】

    1.pom.xml配置 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://w ...

  6. 攻防世界 WEB 高手进阶区 unserialize3 Writeup

    攻防世界 WEB 高手进阶区 unserialize3 Writeup 题目介绍 题目考点 PHP反序列化 __wakeup漏洞 Writeup 题名 unserialize 是反序列化函数名 了解一 ...

  7. Linux ns 6. Network Namespace 详解

    文章目录 1. 简介 1.1 Docker Network 桥接模式配置 2. 代码解析 2.1 copy_net_ns() 2.2 pernet_list 2.2.1 loopback_net_op ...

  8. LiteFlow 2.6.4版本发行注记,里程碑版本!

    一 这个版本做的很折腾.期间几个issue推翻重做了好几次. 但我最终还是带来了LiteFlow 2.6.4这个重要版本. 虽然版本是小版本号升级,但是带来的更新可一点也不少.并完全向下兼容. 如果你 ...

  9. Linux驱动实践:带你一步一步编译内核驱动程序

    作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...

  10. 菜鸡的Java笔记 - java 双向一对多映射

    双向一对多映射    two-way    开发要求:        根据数据表的结构进行简单java类的转换:        要求实现如下的输出信息:            可以根据课程取得全部参与 ...