Java NIO Java 虚拟线程(微线程)与 Go 协程的运行原理不同 为何Go 能在低配机器上承接10万 Websocket 协议连接

什么是Java NIO?

Java NIO(New Input/Output) 是Java 1.4(2002年)引入的一种非阻塞、面向缓冲区的输入输出框架,旨在提升Java在高性能和高并发场景下的I/O处理能力。它相比传统的 Java IO(java.io包)更加高效,尤其在网络编程中,例如需要处理大量连接的服务器(如WebSocket、HTTP或TCP服务器)。

Java NIO的核心组件

  • Channel(通道):类似传统IO中的流,但支持非阻塞操作,例如SocketChannel和ServerSocketChannel。

  • Buffer(缓冲区):高效的数据容器,如ByteBuffer,用于读写数据。

  • Selector(选择器):实现多路复用,允许一个线程监控多个通道的事件(如连接建立、数据可读、可写)。

  • Asynchronous Channel(异步通道)(Java 7+):如AsynchronousSocketChannel,提供真正的异步I/O支持。

Java NIO的优势

  • 非阻塞I/O:一个线程可以处理多个连接,不必为每个连接分配独立线程。

  • 多路复用:通过Selector,一个线程可以管理成千上万的连接,减少线程开销。

  • 高效性:Buffer优化了数据传输,减少了内存拷贝。

  • 适用场景:特别适合WebSocket这种需要维持大量长连接的协议。

简单来说,Java NIO通过非阻塞和多路复用技术,为高并发网络应用提供了强大的支持。


在没有NIO之前,Java如何处理类似WebSocket协议下的10万连接?

背景说明:WebSocket协议是2011年才标准化(RFC 6455),而Java NIO早在2002年就已推出。因此,在没有NIO之前(即Java 1.4之前),并不存在WebSocket协议。但我们可以假设问题是指“类似WebSocket的高并发长连接场景”,例如基于TCP的自定义协议或HTTP长轮询。

在没有NIO的情况下,Java使用的是 传统Java IO(java.io包)和 线程-per-连接(thread-per-connection) 模型来处理网络连接。

传统Java IO的特点

  • 阻塞式I/O:每个连接的读写操作都是阻塞的,线程在I/O完成前无法处理其他任务。

  • 线程-per-连接模型:为每个客户端连接分配一个独立线程,线程负责该连接的所有I/O操作和业务逻辑。

处理10万连接的挑战

如果要支持10万并发连接,每个连接一个线程,会遇到以下问题:

  • 内存开销:每个Java线程默认栈内存约1MB(可通过-Xss调至256KB)。10万线程需要约100,000 * 256KB = 25GB的栈内存,加上JVM堆内存和缓冲区,总内存需求可能达到35-45GB。

  • CPU负担:10万线程会导致频繁的上下文切换,CPU利用率下降,延迟增加。

  • 系统限制:操作系统对线程数和文件描述符有限制(如Linux默认线程数上限几千到几万,文件描述符默认1024),需要大幅调整配置。

  • 性能瓶颈:线程调度和资源竞争使服务器性能随连接数增加而快速下降。

当时的解决方案

在没有NIO的情况下,开发者可能会尝试以下方法,但效果有限:

  • 线程池:用固定大小的线程池处理连接,但并发数受限于线程池大小,超出的连接只能排队或被拒绝。

  • 多进程:启动多个进程分担连接,但进程间通信复杂,资源利用率低。

  • 手动异步:通过复杂逻辑实现伪异步,但开发难度高且不稳定。

总之,在传统Java IO下,处理10万连接极其困难,几乎不可行。


在没有NIO之前,支持10万连接需要多少硬件支持?

在传统线程-per-连接模型下,支持10万连接对硬件要求极高,以下是估算:

硬件需求分析

  1. 内存:

    • 每个线程栈内存:假设-Xss256k,即256KB。

    • 10万线程:100,000 * 256KB ≈ 25GB。

    • 额外开销:JVM堆内存、连接缓冲区等,约10-20GB。

    • 总内存:35-45GB。

  2. CPU:

    • 10万线程的上下文切换需要大量CPU资源。

    • 假设连接活性较低,CPU利用率可能在50-80%。

    • 建议配置:8-16核CPU,甚至更高。

  3. 网络带宽:

    • 假设每个连接平均1KB/s(低活性),总带宽为100,000 * 1KB/s = 100MB/s ≈ 800Mbps。

    • 网卡:至少1Gbps。

  4. 操作系统调整:

    • 文件描述符:每个连接占用一个,需设置ulimit -n为100,000+。

    • 线程上限:调整Linux的/proc/sys/kernel/threads-max。

具体硬件配置

  • 单机:高配服务器,例如32-64核CPU,64GB+内存,1Gbps网卡。

  • 多机集群:单机难以承受10万线程,需10台服务器,每台处理1万连接(每台约16GB内存、8核CPU)。

  • 成本:硬件和运维成本极高,且性能不佳(延迟高、稳定性差)。

可行性

即使硬件能支持,10万线程的调度开销和内存压力会导致系统效率低下。在没有NIO的时代,Java并不适合这种超高并发场景,开发者可能会转向其他语言(如C的epoll)。


NIO的改进(补充说明)

相比之下,Java NIO通过非阻塞I/O和Selector多路复用,极大降低了资源需求:

  • 线程数:只需少量线程(例如8-16个),内存降至几GB。

  • 硬件:普通服务器(4-8核CPU、8-16GB内存)即可支持10万连接。

  • 效率:性能提升数倍,成本大幅降低。

阿里巴巴的NIO使用

证据显示,阿里巴巴使用Netty框架(基于Java NIO)来管理数十亿连接,适合双11近1亿人同时发起请求的场景。

具体实现细节未公开,但NIO的多路复用和非阻塞特性似乎是关键。

阿里巴巴的电商平台如淘宝和天猫在双11期间需要处理数十亿请求,这需要高度可扩展的架构。Java NIO通过非阻塞I/O和选择器(Selectors)允许多个连接由少量线程管理,非常适合这种高并发场景。

技术使用

  • Java NIO的作用:NIO通过选择器监控多个通道(连接),一个线程可以处理成千上万的连接,减少线程开销。

  • Netty框架:阿里巴巴使用Netty(基于NIO)来构建高性能网络服务器,Netty支持多线程事件循环和高效内存管理,适合双11的高并发需求。

Go 协程和Netty的事件循环差异

Netty 的事件循环

Netty 是一个基于 Java NIO 的网络框架,其事件循环(Event Loop)采用 Reactor 模式。一个 EventLoop 由一个线程管理,通过选择器(Selector)监控多个连接(Channel),处理 I/O 事件(如数据可读、可写)。它特别适合高并发场景,如 WebSocket 服务器,一个线程能处理成千上万的连接。

Go 协程的事件循环

Go 的 goroutine 是轻量级并发单元,由 Go 运行时管理,事件循环是隐式的。当 goroutine 执行 I/O 操作时,如果阻塞,运行时会自动挂起该 goroutine,调度其他 goroutine 运行。Go 适合 CPU 和 I/O 混合任务,易于开发高并发网络服务。

主要区别

  • 线程模型:Netty 用单线程 EventLoop 处理多个 Channel,Go 用多个 OS 线程调度 goroutine。

  • I/O 处理:Netty 使用非阻塞 I/O,Go goroutine 可阻塞,运行时自动管理。

  • 适用场景:Netty 优化高并发网络,Go 适合通用并发任务。

Netty和Java虚拟线程之间的关系

研究表明,Netty 和 Java 虚拟线程在高并发网络应用中有潜在的互补关系,但目前 Netty 尚未完全支持虚拟线程。

Netty 的作用:Netty 是一个基于 Java NIO 的高性能网络框架,适合处理大量连接。

虚拟线程的优势:Java 虚拟线程(从 Java 21 开始正式支持)是轻量级线程,能简化高并发编程,减少资源消耗。

两者结合:虚拟线程可以与 Netty 一起使用,可能简化开发,但需要社区进一步支持。

Netty 是一个异步事件驱动的网络框架,擅长处理高并发场景,如 WebSocket 服务器。它使用少量线程通过事件循环管理大量连接,适合需要高性能的网络应用。

Java 虚拟线程允许创建数百万个轻量级线程,特别适合 I/O 密集型任务。当线程阻塞时,JVM 会自动挂起它,释放资源,适合高吞吐量应用。

Netty 是虚拟线程出现前的过渡产品?

研究表明,Netty 在 Java 虚拟线程出现前确实是一种过渡性解决方案,主要解决平台线程在高并发场景下的问题。

Netty 基于 Java NIO,提供非阻塞 I/O 和事件驱动模型,适合处理大量连接。

虚拟线程(从 Java 21 开始)简化了高并发编程,可能是未来更直接的解决方案,但 Netty 仍具价值。

Netty 是一个高性能网络框架,设计用于处理高并发网络任务,如 WebSocket 服务器。它通过少量线程管理大量连接,解决了平台线程资源开销大的问题。

Java 虚拟线程允许创建轻量级线程,适合高并发场景,减少了资源消耗。它们让开发者可以用阻塞式代码处理高并发,简化了开发。

在虚拟线程出现前,Netty 是处理高并发的关键工具。现在,虚拟线程可能减少对 Netty 的依赖,但 Netty 在特定场景(如复杂网络协议)仍很重要。

虚拟线程与Go协程在低配机器上处理10万连接的区别

研究表明,Go协程在低配机器上处理10万连接更具优势,主要是内存开销低和运行时高效。

Java虚拟线程也适合高并发,但JVM的开销可能在低配机器上成为瓶颈。

两者的区别在于内存使用、CPU效率和生态系统,Go更适合资源有限的场景。

内存使用

Go协程每个约2KB内存,10万连接需200MB,适合低配机器(如2GB内存)。Java虚拟线程内存开销低,但JVM可能需1.5GB以上,资源紧张时表现不如Go。

CPU和调度效率

Go的调度器用户态实现,效率高,适合低配CPU。Java虚拟线程依赖JVM,调度开销稍高,低配CPU可能受GC影响。

实际表现

测试显示Go在低配机器上处理10万连接更高效,Java虚拟线程在高端硬件上更强,但低配场景可能受限。

 为什么在高端硬件上虚拟线程表现会比Go好?

CPU密集型任务:Java的即时编译器(JIT)能针对高端硬件生成高度优化的机器代码,利用多核和高级指令集(如AVX-512),提升性能。例如,科学计算中的矩阵运算可能受益于此。

复杂计算和生态系统整合:Java有成熟的库(如Apache Spark、TensorFlow),虚拟线程能高效并发执行这些库的任务,同时利用JVM的优化。

高内存分配场景:Java的高级垃圾回收(如G1、ZGC)在高端硬件上能高效处理高内存分配,适合长运行应用。

例如,在一个需要复杂计算和大量并发的科学计算应用中,虚拟线程可能比Go协程更快,因为JVM能更好地利用高端硬件的资源。

Go协程的优势

但需要注意的是,Go协程在高并发I/O任务中通常表现更优,特别是在需要快速创建大量任务时(如Web服务器)。Go的运行时更简单,内存开销低(每个Goroutine约2KB),在某些基准测试中(如处理100万任务),Go比Java虚拟线程快(4.911秒 vs. 10.73秒)。

总结

总体来说,虚拟线程在高端硬件上可能在特定CPU密集型或生态系统依赖的场景下表现更好,但Go协程在一般高并发任务中更高效。选择哪种技术取决于具体应用需求和开发者的熟悉程度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/902236.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

go环境安装mac

下载go安装包:https://golang.google.cn/dl/ 找到对应自己环境的版本下载。 注意有二进制的包,也有图形界面安装的包。图形界面直接傻瓜式点就行了。 二进制的按照下面操作: 1、下载二进制包。 2、将下载的二进制包解压至 /usr/local目录…

LVGL源码(9):学会控件的使用(自定义弹窗)

LVGL版本:8.3 LVGL的控件各式各样,每种控件都有自己的一些特性,当我们想要使用一个LVGL控件时,我们首先可以通过官网去了解控件的一些基本特性,官网链接如下: LVGL Basics — LVGL documentation&#xf…

《软件设计师》复习笔记(1)——考试介绍【新】

目录 一、考试介绍 证书价值 考试要求 二、【新】计算机与软件工程知识 三、软件设计 一、考试介绍 >考试科目>考题形式>考试时长>合格标准计算机与软件工程知识75道单选题(每题1分,总分75分)2023年11月改革机试后&#…

MCU中的BSS和data都占用SRAM空间吗?

在MCU中,BSS段和data段都占用SRAM空间,但它们的存储方式和用途有所不同。‌ BSS段 BSS段(Block Started by Symbol)用于存储未初始化的全局变量和静态变量。这些变量在程序启动时会被清零,因此它们不占用Flash空间&a…

Ubuntu 22.04 更换 Nvidia 显卡后启动无法进入桌面问题的解决

原显卡为 R7 240, 更换为 3060Ti 后, 开机进桌面时卡在了黑屏界面, 键盘有反应, 但是无法进入 shell. 解决方案为 https://askubuntu.com/questions/1538108/cant-install-rtx-4060-ti-on-ubuntu-22-04-lts 启动后在开机菜单中(如果没有开机菜单, 需要按shift键), 进入recove…

Python爬虫-爬取猫眼演出数据

前言 本文是该专栏的第53篇,后面会持续分享python爬虫干货知识,记得关注。 猫眼平台除了有影院信息之外,它还涵盖了演出信息,比如说“演唱会,音乐节,话剧音乐剧,脱口秀,音乐会,戏曲艺术,相声”等等各种演出相关信息。 而本文,笔者将以猫眼平台为例,基于Python爬虫…

人工智能-机器学习(线性回归,逻辑回归,聚类)

人工智能概述 人工智能分为:符号学习,机器学习。 机器学习是实现人工智能的一种方法,深度学习是实现机器学习的一种技术。 机器学习:使用算法来解析数据,从中学习,然后对真实世界中是事务进行决策和预测。如垃圾邮件检…

FPGA学习(五)——DDS信号发生器设计

FPGA学习(五)——DDS信号发生器设计 目录 FPGA学习(五)——DDS信号发生器设计一、FPGA开发中常用IP核——ROM/RAM/FIFO1、ROM简介2、ROM文件的设置(1)直接编辑法(2)用C语言等软件生成初始化文件 3、ROM IP核配置调用 二、DDS信号发…

【Vue】从 MVC 到 MVVM:前端架构演变与 Vue 的实践之路

个人博客:haichenyi.com。感谢关注 一. 目录 一–目录二–架构模式的演变背景​三–MVC:经典的分层起点​四–MVP:面向接口的解耦尝试​五–MVVM:数据驱动的终极形态​​六–Vue:MVVM 的现代化实践​​​ 二. 架构模…

【算法】快速排序、归并排序(非递归版)

目录 一、快速排序&#xff08;非递归&#xff09; 1.原理 2.实现 2.1 stack 2.2 partition(array,left,right) 2.3 pivot - 1 > left 二、归并排序&#xff08;非递归&#xff09; 1.原理 2.实现 2.1 gap 2.1.1 i 2*gap 2.1.2 gap * 2 2.1.3 gap < array.…

CasualLanguage Model和Seq2Seq模型的区别

**问题1&#xff1a;**Causal Language Modeling 和 Conditional Generation 、Sequence Classification 的区别是什么&#xff1f; 因果语言模型(Causal Language Model)&#xff1a; 预测给定文本序列中的下一个字符&#xff0c;一般用于文本生成、补全句子等&#xff0c;模型…

【计算机视觉】三维视觉项目 - Colmap二维图像重建三维场景

COLMAP 3D重建 项目概述项目功能项目运行方式1. 环境准备2. 编译 COLMAP3. 数据准备4. 运行 COLMAP 常见问题及解决方法1. **编译问题**2. **运行问题**3. **数据问题** 项目实战建议项目参考文献 项目概述 COLMAP 是一个开源的三维重建软件&#xff0c;专注于 Structure-from…

状态管理最佳实践:Bloc架构实践

状态管理最佳实践&#xff1a;Bloc架构实践 引言 Bloc (Business Logic Component) 是Flutter中一种强大的状态管理解决方案&#xff0c;它基于响应式编程思想&#xff0c;通过分离业务逻辑和UI表现层来实现清晰的代码架构。本文将深入探讨Bloc的核心概念、实现原理和最佳实践…

Python多任务编程:进程全面详解与实战指南

1. 进程基础概念 1.1 什么是进程&#xff1f; 进程(Process)是指正在执行的程序&#xff0c;是程序执行过程中的一次指令、数据集等的集合。简单来说&#xff0c;进程就是程序的一次执行过程&#xff0c;它是一个动态的概念。 想象你打开电脑上的音乐播放器听歌&#xff0c;…

Linux 网络基础(二) (传输协议层:UDP、TCP)

目录 一、传输层的意义 二、端口号 1、五元组标识一个通信 2、端口号范围划分 3、知名端口号&#xff08;Well-Know Port Number&#xff09; &#xff08;1&#xff09;查看端口号 4、绑定端口号数目问题 5、pidof & netstat 命令 &#xff08;1&#xff09;ne…

得佳胜哲讯科技 SAP项目启动会:胶带智造新起点 数字转型新征程

在全球制造业加速向数字化、智能化转型的浪潮中&#xff0c;胶带制造行业正迎来以“自动化生产、数据化运营、智能化决策”为核心的新变革。工业互联网、大数据分析与智能装备的深度融合&#xff0c;正推动胶带制造从传统生产模式向“柔性化生产精准质量控制全链路追溯”的智慧…

大数据学习栈记——MapReduce技术

本文介绍hadoop中的MapReduce技术的应用&#xff0c;使用java API。操作系统&#xff1a;Ubuntu24.04。 MapReduce概述 MapReduce概念 MapReduce是一个分布式运算程序的编程框架&#xff0c;核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序…

Centos9 离线安装 MYSQL8

centos 9 离线安装 mysql 8 参考教程 1. 官网下载mysql 下载地址 2. 将文件传输到Centos中解压 软件全部安装到了/opt中 在opt中新建mysql目录&#xff0c;解压到mysql目录中 tar -xvf mysql压缩文件 mysql[rootcentoshost mysql]# ls mysql-community-client-8.4.5-1.e…

helm的go模板语法学习

1、helm chart 1.0、什么是helm&#xff1f; 介绍&#xff1a;就是个包管理器。理解为java的maven、linux的yum就好。 安装方法也可参见官网&#xff1a; https://helm.sh/docs/intro/install 通过前面的演示我们知道&#xff0c;有了helm之后应用的安装、升级、查看、停止都…

display的一些学习记录

收集的SDM的log&#xff1a; 01-01 00:00:15.311 933 933 I SDM : Creating Display HW Composer HAL 01-01 00:00:15.311 933 933 I SDM : Scheduler priority settings completed 01-01 00:00:15.311 933 933 I SDM : Configuring RPC threadpool 0…