IO密集型服务提升性能的三种方法

提高 I/O 密集型服务性能的三种方法:
1 .批处理:合并 I/O 请求、减少网络往返并减少延迟。
例如,将多个解密请求合并为一个。
注意:并非所有IO都适合批处理。

2 缓存:存储经常使用的数据并减少对慢速内存的访问。
例如,使用Guava或Redis缓存。
注意:保证数据的一致性。

3 多线程:并行处理任务并使用CPU的计算能力。
例如,使用Java的ExecutorService来管理线程。
注意:处理并发问题。

将三者结合起来,根据需求和环境选择来优化 I/O 密集型服务的性能。

面试官:公司项目中Java的多线程一般用在哪些场景?

嗯,你的总结很全面。
真正把Java多线程的应用场景和陷阱讲清楚了。
但让我告诉你,我走过的恐怖和我看到的景象可能与你的总结不同。
我再给大家补充一些生动的例子。

以您提到的 Web 服务器容器级多线程为例。
2 02 3 年,我在上海的一个购物中心做的一个项目中使用了Tomcat 9 .0。
此时客户端需要更高的并发能力。
在我们的测试过程中,我们发现原来的线程池配置确实可持续,但是当并发数增加时就崩溃了。
后来我们调整了参数,将maxThreads调整为2 00,并将队列大小增加到1 00后,就稳定下来了。
但稍后如果单个请求中有数据库操作和IO文件。
我发现并行性不能简单粗暴的区分。
例如,2 02 3 年夏天,我们举办了一个活动,查询了三个数据库,同时读写文件。
结果CPU就升高了。
后来,我改用单线程串行处理。
虽然速度较慢,但​​系统更稳定。
这意味着什么?并非所有 I/O 操作都适合并行化;这取决于您的具体业务情况。

我们来谈谈并发任务。
你说的记录和消息推送情况是我2 02 2 年在深圳看到的,我有一个电商项目,记录是直接写入数据库的。
结果,数据库在高峰期被阻塞。
后来我改用异步写入,并使用ScheduledExecutorService创建专门的日志线程池并批量写入,解决了问题。
但有一个缺点是异步消息推送不能简单地完成线程池。
去年我在上海帮助调试了一个金融客户。
我使用 FutureTask 发送电子邮件。
当同种货币价格非常高时;邮件服务器直接挂了。
后来Redis改成了队列,批量推送,效果就更好了。

您关于资源优化的看法是正确的。
2 02 3 年,我对杭州的游戏服务器进行了窃听,玩家访问量很多。
最初我们想做N线程处理,但是上下文的变化让CPU像过山车一样上升。
后来我改用了消息队列+事件驱动,建立了独立的网络I/O线程池。
结果,系统的性能得到了很大的提高。
但重点关注你提到的ConcurrentLinkedQueue。
2 02 2 年在北京看到一个项目在用,结果高相关下不停。
后来我用分片锁解决了这个问题。

总的来说,多线程并不是灵丹妙药。
如果使用得当,可以事半功倍。
如果你很穷,你就会受苦。
关键是要看情况,不要失去方向。
例如,在缓存状态下,您总结的FutureTask解决方案非常出色;但是我在2 02 3 年在上海看到一个项目,他们用Redis Cluster来做分布式缓存,效果比自己写异步缓存好很多。
但这些技术选择需要与实际业务结合,需要大量的测试才可靠。