nio

Java BIO、NIO、AIO 学习

被刻印的时光 ゝ 提交于 2020-02-29 09:06:16
先来个例子理解一下概念,以银行取款为例: 同步 : 自己亲自出马持银行卡到银行取钱(使用同步IO时,Java自己处理IO读写)。 异步 : 委托一小弟拿银行卡到银行取钱,然后给你(使用异步IO时,Java将IO读写委托给OS处理,需要将数据缓冲区地址和大小传给OS(银行卡和密码),OS需要支持异步IO操作API)。 阻塞 : ATM排队取款,你只能等待(使用阻塞IO时,Java调用会一直阻塞到读写完成才返回)。 非阻塞 : 柜台取款,取个号,然后坐在椅子上做其它事,等号广播会通知你办理,没到号你就不能去,你可以不断问大堂经理排到了没有,大堂经理如果说还没到你就不能去(使用非阻塞IO时,如果不能读写Java调用会马上返回,当IO事件分发器会通知可读写时再继续进行读写,不断循环直到读写完成)。 Java对BIO、NIO、AIO的支持 : Java BIO : 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。 Java NIO : 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。 Java AIO(NIO.2) : 异步非阻塞

Netty-NioEventLoop线程工作机制

别来无恙 提交于 2020-02-28 17:56:09
I/O读写操作原理 异步任务执行原理 定时任务执行原理 Netty多线程最佳实践 I/O读写操作原理 NioEventLoop作为Reactor线程,负责TCP连接的创建和接入,以及TCP消息的读写,Reactor线程职责如下: 作为NIO服务端,接受客户端的TCP连接 作为NIO客户端,向服务端发起TCP连接 读取通信对端的请求或者应答信息 向通信对端发送消息请求或者应答消息 由于Reactor模式使用的是异步非阻塞I/O,因此所有的I/O操作都不会导致阻塞,理论上一个线程可以独立处理所有I/O相关操作。但对于高负载、大并发的应用场景却不适合。原因如下: 一个NIO线程同时处理成百上千条链路,在性能上无法支撑,即便NIO线程的CPU负荷达到100%,也无法满足海量消息的编码、解码、读取和发送需求。 当NIO线程负载过重时,处理速度将变慢,这回导致大量客户端连接超时,超时之后往往会进行重发消息,这更加加重NIO线程的负荷,最终将导致大量消息积压和处理超时,成为系统的性能瓶颈。 可靠性问题:一旦NIO线程出现意外,会导致整个系统通信模块不可用,不能接受和处理外部消息,造成节点故障。 对于Netty,在创建NioEventLoopGroup时可以指定工作的I/O线程数,通常为"CPU内核书X2"或者"CPU内核书+1",这样可提升网络的读写性能,需要指出的是,不要把I

高性能Server---Reactor模型

◇◆丶佛笑我妖孽 提交于 2020-02-28 07:30:09
转载自: http://www.jianshu.com/p/2461535c38f3 无处不在的C/S架构 在这个充斥着云的时代,我们使用的软件可以说99%都是C/S架构的! 你发邮件用的Outlook,Foxmail等 你看视频用的优酷,土豆等 你写文档用的Office365,googleDoc,Evernote等 你浏览网页用的IE,Chrome等(B/S是特殊的C/S) ...... C/S架构的软件带来的一个明显的好处就是:只要有网络,你可以在任何地方干同一件事。 例如:你在家里使用Office365编写了文档。到了公司,只要打开编辑地址就可以看到在家里编写的文档,进行展示或者继续编辑。甚至在手机上进行阅读与编辑。不再需要U盘拷来拷去了。 C/S架构可以抽象为如下模型: C就是Client(客户端),上面的B是Browser(浏览器) S就是Server(服务器): 服务器管理某种资源,并且通过操作这种资源来为它的客户端提供某种服务 C/S架构之所以能够流行的一个主要原因就是网速的提高以及费用的降低,特别是无线网络速度的提高。试想在2G时代,大家最多就是看看文字网页,小说什么的。看图片,那简直就是奢侈!更别说看视频了! 网速的提高,使得越来越多的人使用网络,例如:优酷,微信都是上亿用户量,更别说天猫双11的瞬间访问量了!这就对服务器有很高的要求!能够快速处理海量的用户请求

Tomcat 9.0.26 高并发场景下DeadLock问题排查与修复

為{幸葍}努か 提交于 2020-02-28 00:41:24
本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/-OcCDI4L5GR8vVXSYhXJ7w 作者:黄卫兵、陈锦霞 一、Tomcat容器 9.0.26 版本 Deadlock 问题 1.1 问题现象 1.1.1 发生 Deadlock 的背景 某接口/get.do压测,3分钟后,成功事务数TPS由1W骤降至0。 1.1.2 Tomcat服务器出现大量的CLOSE_WAIT 被压测服务器,出现TCP CLOSE_WAIT状态个数在200~2W左右。 1.2 初步定位:线程堆栈信息入手 通过jstack打印Tomcat堆栈信息,发现“Found 1 deadlock” Found one Java-level deadlock: ============================= "http-nio-8080-exec-409": waiting to lock monitor 0x00007f064805aa78 (object 0x00000006c0ebf148, a java.util.HashSet), which is held by "http-nio-8080-ClientPoller" "http-nio-8080-ClientPoller": waiting to lock monitor

Netty简介

本小妞迷上赌 提交于 2020-02-27 19:59:32
一、什么是Netty 在网络编程领域,Netty是Java的卓越框架。它驾驭了Java高级API的能力,并将其隐藏在一个易于使用的API之后。Netty使你可以专注于自己真正的业务。简单的说,Netty是一个让网络编程变得简洁的框架,实现了真正的异步非阻塞,性能及其优越。 二、为什么选择Netty 通常,如果用NIO来实现一个服务端需要以下步骤。 创建ServerSocketChannel,配置它为非阻塞模式; 绑定监听,配置TCP参数,例如backlog大小; 创建一个独立的I/O线程,用于轮询多路复用器Selector; 创建Selector,将之前创建的ServerSocketChannel注册到Selector上,监听SelectionKey.ACCEPT; 启动I/O线程,在循环体中执行Selector.select()方法,轮询就绪的Channel; 当轮询到了处于就绪Channel时,需要对其进行判断,如果是OP_ACCEPT状态,说明是新的客户端接入,则调用ServerSocketChannel.accept()方法接受新的客户端; 设置新接入的客户端链路SocketChannel为非阻塞模式,配置其他的一些TCP参数; 将SocketChannel注册到Selector,监听OP_READ操作位; 如果轮询的Channel为OP_READ

java网络编程基础BIO,NIO学习

大憨熊 提交于 2020-02-27 04:55:00
网络各个层的数据包格式 即一帧就是以上的,如果 数据太大,那么就分成多个 帧 进行发送 java.io 输入与输出: 用法可以这样记 : 读进去(input), 写出来(output) 数据源 到 应用 就是 输入流, 应用到 数据源就是 对应 输出流 字节流即处理字节,也就是 1 byte = 8 bit 字符流高于 字节流 ,虽然操作数据最基本是字节的,但是 字符流这里并不是一个字节一个字节 去读写的,而是一个字符一个字符去读写的。 字符对应Java就是 char (Character) , 1 char 需要 2 byte 去存储 以上是基本的,下面是衍生的复制类,属于包装类: InputStreamReader 即可将字节转换为字符的作用 OutputStreamReader 将字符转为字节 作用 字节流 以下是包装类 DataInputStream 与DataOutputStream 即可以将字节 转换为对应的 基本类型比如 int ,long Socket socket 也是一种数据源。 socket 可以类比为相似现实的 插座, 插上之后就有电流,电流就是IO流 在Unix 系统中 一切皆是文件,因此 socket 也是文件 同步/异步/阻塞/非阻塞 同步或者异步 是 对通信机制上面来说的。即 被调用方的处理结果的形式来说的。 即 被调用方 直接返回结果,就是同步。

Netty快速入门(06)Netty介绍

≡放荡痞女 提交于 2020-02-26 11:20:57
前面简单的介绍了Java I/O 和NIO,写了示例程序。 Java I/O是阻塞的,为了让它支持多个并发,就要针对每个链接启动线程,这种方式的结果就是在海量链接的情况下,会创建海量的线程,就算用线程池去缓解,也是治标不治本。所以,Java I/O 不适合高并发高性能的网络编程需求。 NIO的出现就是为了解决这个问题,NIO中一个线程可以关注多个链接,解决了线程问题,前面也演示了如何用NIO编程。大家可以看到使用NIO是非常复杂的,可以说是陷阱重重,不是在网络编程方面很资深的程序员,很难用NIO编写出正常的程序,甚至高级程序员也不推荐用。 Netty介绍 写程序比较开心的就是碰到这种情况,一定会有很多框架去解决各种问题,比如JDBC直接写很复杂,就会有hibernate和mybatis等框架,让开发变得简单。NIO编程也是一样,出现过很多框架,相信很多人听说过mina框架,和netty是同一个作者。而netty是目前最流行的解决NIO编程问题的框架。我们打开netty的官网, https://netty.io,首页最上面就是netty的介绍: 翻译成中文就是: > Netty是一个提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。 用NIO也能开发这样的程序,但是很复杂,如果用netty,就能很简单很快速的开发高性能高可靠的程序

大文件拷贝,试试NIO的内存映射

不想你离开。 提交于 2020-02-25 18:59:35
最近项目里有个需求需要实现文件拷贝,在java中文件拷贝流的读写,很容易就想到IO中的InputStream和OutputStream之类的,但是上网查了一下文件拷贝也是有很多种方法的,除了IO,还有NIO、Apache提供的工具类、JDK自带的文件拷贝方法 IO拷贝 public class IOFileCopy { private static final int BUFFER_SIZE = 1024; public static void copyFile(String source, String target) { long start = System.currentTimeMillis(); try(InputStream in = new FileInputStream(new File(source)); OutputStream out = new FileOutputStream(new File(target))) { byte[] buffer = new byte[BUFFER_SIZE]; int len; while ((len = in.read(buffer)) > 0) { out.write(buffer, 0, len); } System.out.println(String.format("IO file copy cost %d

Java NIO框架Mina、Netty、Grizzly介绍与对比

痞子三分冷 提交于 2020-02-25 18:13:32
Mina Mina(Multipurpose Infrastructure for Network Applications) 是 Apache组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。当前发行的 Mina 版本2.04支持基于 JavaNIO 技术的 TCP/UDP 应用程序开发、串口通讯程序,Mina 所支持的功能也在进一步的扩展中。目前,正在使用Mina的应用包括:Apache Directory Project、AsyncWeb、AMQP(Advanced MessageQueuing Protocol)、RED5 Server(Macromedia? FlashMedia RTMP)、ObjectRADIUS、 Openfire等等。 Netty Netty是一款异步的事件驱动的网络应用框架和工具,用于快速开发可维护的高性能、高扩展性协议服务器和客户端。也就是说,Netty是一个NIO客户端/服务器框架,支持快速、简单地开发网络应用,如协议服务器和客户端。它极大简化了网络编程,如TCP和UDP套接字服务器。 Grizzly Grizzly是一种应用程序框架,专门解决编写成千上万用户访问服务器时候产生的各种问题。使用JAVANIO作为基础,并隐藏其编程的复杂性。容易使用的高性能的API。带来非阻塞socketd到协议处理层

Java的BIO,NIO和AIO的区别于演进

落爺英雄遲暮 提交于 2020-02-25 07:28:20
作者:公众号: 我是攻城师 前言 Java里面的IO模型种类较多,主要包括BIO,NIO和AIO,每个IO模型都有不一样的地方,那么这些IO模型是如何演变呢,底层的原理又是怎样的呢? 本文我们就来聊聊。 BIO BIO全称是Blocking IO,是JDK1.4之前的传统IO模型,本身是同步阻塞模式,针对网络通信都是一请求一应答的方式,虽然简化了上层的应用开发,但在性能和可靠性方面存在着巨大瓶颈,试想一下如果每个请求都需要新建一个线程来专门处理,那么在高并发的场景下,机器资源很快就会被耗尽,当然,我们可以通过线程池来优化这种情况,但即使是这样,仍然改变不了阻塞IO的根本问题,就是在IO执行的两个阶段都被block了。拿一个read操作来举例子,在linux中,应用程序向linux发起read操作,会经历两个步骤: 第一个阶段linux内核首先会把需要读取的数据加载到操作系统内核的缓冲区中(Linux文件系统是缓存IO,也称标准IO) 第二个阶段应用程序拷贝内核里面的数据到自己的用户空间中 如果是socket操作,类似也会经历两个步骤: 第一个阶段:通常涉及等待网络上的数据分组包到达,然后被复制到内核的缓冲区 第二个阶段:把数据从内核缓冲区,从内核缓冲区拷贝到用户进程的内存空间里面 同步阻塞IO之所以效率低下,就是因为在这两个阶段,用户的线程或者进程都是阻塞的,期间虽然不占cpu资源