gpt4 book ai didi

java - 使用线程池和 BlockingQueue 重新架构 I/O 密集型 Java Web 服务

转载 作者:行者123 更新时间:2023-12-02 10:23:14 24 4
gpt4 key购买 nike

我创建的一个 Java 项目目前在 PROD 中运行,它是 I/O 密集型项目。我想重构它以优化性能 - 并不是我被要求这样做,但我觉得仍然有改进的空间。所以在为时已晚之前处理它。很少有步骤可以并行化并更好地利用多个内核。

什么服务?

它是一个 Web 服务,它只是摄取文件并通过网络(通过互联网而不是在公司内部网内)将它们发送到远程 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 我认为使用的数据通道/总线是不同的. 因此,如果我将它们并行化,将会提高性能。我需要这样做,因为在未来,zip 的数量将会增加,比如一次性增加 1000 个 zip,这是非常慢的目前的实现情况。

还将实现 sftp 连接的连接池(目前没有,我意识到这是必须的)。还有 2 个拟议职位

1)从远程拉 zipper 并

2)在本地处理 zip

我将使用线程池(按照教程 Parallel and Asynchronous Programming 如果服务是 I/O 密集型,线程数量甚至可以达到核心的 10 倍。需要进行 Offcourse 基准测试。但只是从概念上讲,这对于正面思考是有好处的开始)。

这种重组有意义吗?还能做什么?

最佳答案

我会根据 Activity 类型定义许多线程池执行器:

  • 一个用于 CPU 密集型作业,大小为 Runtime.getRuntime().availableProcessors()
  • 一个用于磁盘 I/O 密集型作业,尺寸较小 (1..3)。 HDD 在顺序模式下性能最佳。对于 SSD,您可以尝试增加池大小,但无论如何在执行并行磁盘 I/O 时使用大量缓冲(1MB+),
  • 主要用于网络 I/O 密集型作业(4..20,取决于网络带宽和传输距离)。

然后根据任务的性质将流程拆分为子任务。完成后,结束每个任务会将其结果移交给相应池中的新任务。

我还会实现 backpressure mechanism不要让队列变得太大(默认情况下,ThreadPoolExecutor 会愉快地对无限数量的作业进行排队)并密切关注堆和磁盘空间的使用情况。磁盘(HDD)通常是最大的瓶颈,尝试在内存中做更多的事情。

关于java - 使用线程池和 BlockingQueue 重新架构 I/O 密集型 Java Web 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54179425/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com