【发布时间】:2019-01-16 14:34:08
【问题描述】:
我创建的并且目前在 PROD 中运行的 Java 项目是 I/O 密集型的。我想重构它以优化性能——不是我被要求这样做,但我觉得仍有改进的余地。所以在为时已晚之前处理它。很少有步骤可以并行化并更好地利用多个内核。
什么服务?
它是一个网络服务,它简单地摄取一个文件并通过网络将它们 sftp-ies 到远程 sftp 服务器(通过互联网而不是公司内部网)。有 2 个 sftp 站点。因此,服务通过请求本身发送的元数据来决定向哪个服务器进行 sftp。它还有 2 个定期运行的作业,这些作业在这 2 个 sftp 站点上以 5 分钟的定时延迟进行轮询,并拉取 zip 文件(如果有)。
做什么工作: 作业将所有可用的 zip 一个一个拉到本地文件夹。然后开始处理每个 zip(通过循环 zips 集合)。首先它提取 zip,然后获取 1 个 pdf 文件并发送到公司网络内的另一个 web 服务(比如服务 1)。然后它获取一个 xml 文件,对其进行解析并从中提取某些数据,然后将该数据提供给另一个服务(例如服务 2)。
我打算做什么? 一项工作要做的工作量太大了。 我计划将其拆分 -> 作业只会将 zip 拉入本地文件夹并将名称推送到 BlockingQueue 中,这将启动另一个作业并由它完成处理,即提取 zip 可以与从远程 sftp 服务器拉取 zip 并行处理。现在我的查询是,将 zip 从远程拉到本地和在本地处理 zip 实际上都是 I/O 操作,但是 因为首先是网络上的 I/O 和另一个本地文件 I/O,我认为使用的数据通道/总线是不同的. 因此,如果我将它们并行化,它将提高性能。 我需要这样做,因为在未来,拉链的数量会增加,例如 1000 个拉链,这非常慢与当前的实施。
还将为 sftp 连接实现连接池(目前没有,我意识到这是必须的)。也适用于 2 个提议的工作
1)从远程拉拉链和
2) 在本地处理 zip
我将使用线程池(根据教程Parallel and Asynchronous Programming ,如果服务是 I/O 密集型服务,线程数甚至可以达到核心的 10 倍。需要进行离线基准测试。但从概念上讲,这对正面来说是有好处的开始)。
这种重组有意义吗?还能做什么?
【问题讨论】:
标签: java multithreading architecture threadpool sftp