IO密集型任务及Vertx框架
发布于2024-09-28 02:25:47,更新于2024-09-30 21:03:16,标签:java vertx 文章会持续修订,转载请注明来源地址:https://meethigher.top/blog一、背景
1.1 铺垫知识
涉及到阻塞式IO、非阻塞式IO、事件驱动等相关知识,可以查看我以往文章。
1.2 瓶颈解决
我之前使用java封装了一个HTTP反向代理的工具http-proxy-boot,主要是方便自己临时测试时使用的。
该工具存在一个问题,高并发的时候,整体响应就会滞后。原因是因为该工具采用bio实现的,即“一连接一线程”。
假如我这个工具,只开放了200个连接。此时有201个请求过来,顺序依次是,200个慢请求(10秒响应),1个快请求(1秒响应)。
实际出现的情况是这200个连接都被前面200个慢请求阻塞了,以至于后面的快请求一直等待,实际20+1秒后才会响应。而我希望的效果是即使我可支配的线程数不变,快请求仍然可以1秒响应。
题外话,PostgreSQL使用的是“一连接一进程”模型,该问题PostgreSQL也同样存在。
计算机任务有很多种分类,以上属于其中IO密集型任务。尽管CPU参与任务处理,但大部分时间在等待IO完成。这中间的时间,CPU完全可以用来做更多的事。
我采用的做法是将bio切换成nio,也就是cpu不用一直等待,而是去做别的事,当传输完成后,通知cpu过来善后。
对于http来说,成熟的框架有很多。
其中,我对比了下两者。WebFlux对Spring的生态支持相当友好,可以说是强耦合,健壮的同时也牺牲了些便捷性。而Vertx就相当轻量了,于是我选择Vertx解决这个问题。
二、计算机任务分类
计算机任务可以根据其特性分为几种类型,主要包括:
- CPU密集型
- IO密集型
- 内存密集型
- 网络密集型
每种类型的任务都有不同的性能瓶颈,了解它们的特点可以帮助我们在设计和优化系统时做出更合适的选择。
2.1 CPU密集型
这类任务主要依赖CPU的处理能力,通常需要大量的计算和复杂的算法。典型的例子包括视频编码、科学计算、数据分析等。
优化方式:并行处理,换用更高性能的CPU。
32线程的CPU同时刻只能跑32个线程。像操作系统里面会有很多线程,几十万个,那是因为其实有很多线程是空闲的,CPU来回轮转,间接达到了上万线程同时运行的效果,比如像下面的这种IO密集型任务。
2.2 IO密集型
这类任务主要依赖于输入/输出操作,通常涉及大量的数据读写,如文件操作、网络请求等。
优化方式:减少IO操作次数、使用异步编程、换用更高性能硬盘。
2.3 内存密集型
这类任务对内存的使用量很大,例如处理大数据集、复杂的数据结构等。内存访问速度较快,但如果内存不足,可能会导致性能瓶颈。
优化方式:优化数据结构、减少内存占用、增加内存。
2.4 网络密集型
这类任务主要依赖网络带宽和延迟,通常涉及大量的数据在网络上传输,如Web服务器、大规模分布式系统等。
优化方式:优化网络协议、使用负载均衡、提高带宽等。