前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Netty】NIO编程的利器

【Netty】NIO编程的利器

作者头像
周三不加班
发布于 2019-09-04 02:05:47
发布于 2019-09-04 02:05:47
41400
代码可运行
举报
文章被收录于专栏:程序猿杂货铺程序猿杂货铺
运行总次数:0
代码可运行

今天换换口味,由于本人工作中马上要用到Netty这个东西,所以这几天也是开始学习,此学习过程应该会是一个完整的系列,初步的目标是先会用,之后有机会再深入。鉴于笔者之前也从未使用过Netty,所以有什么疏漏错误的,希望大家指正,先行感谢!

学习Netty之前需要先回顾一下java中的IO编程和NIO编程,因为根据我的理解Netty就是对JDK中的NIO编程做了一层很好的封装,可以让开发者专注于业务逻辑的开发。

官方的定义是这样的:

Netty is an asynchronous event-driven network application framework

for rapid development of maintainable high performance protocol servers & clients

大致意思是说:

Netty是一个异步事件驱动的网络应用程序框架

用于快速开发可维护的高性能协议服务器和客户端。

1

IO编程模型

回顾一个Java Socket编程的简单例子,应用场景为 客户度每隔2秒钟向服务端发送一个消息,

服务端代码如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Created by zhoudl on 2018/10/3.
 * IO编程 服务端
 */
public class IOServer {

    public static void main(String[] args) {
        try {
            server(8080);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 1.首先创建了一个serverSocket来监听 某个 端口,然后创建一个线程
     * 2.线程里面不断调用阻塞方法 serversocket.accept();获取新的连接
     * 3.当获取到新的连接之后,给每条连接创建一个新的线程,这个线程负责从该连接中读取数据
     * 4.然后读取数据是以字节流的方式
     *
     * @param port
     * @throws IOException
     */
    public static void server(int port) throws IOException {
        // 1
        ServerSocket serverSocket = new ServerSocket(port);
        new Thread(() -> {
            while (true) {
                try {
                    // 2.调用阻塞方法获取新的连接
                    Socket socket = serverSocket.accept();
                    // 3.每个连接都交给一个新的线程去处理
                    new Thread (() -> {
                        int length;
                        byte[] bytes = new byte[1024];
                        try {
                            InputStream inputStream = socket.getInputStream();
                            // 4.根据字节流方式获取数据
                            while ((length = inputStream.read(bytes)) != -1) {
                                System.out.println(new String(bytes, 0, length));
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }).start();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }).start();
    }
}
服务端创建过程分析
  • 1.首先创建了一个serverSocket来监听 某个 端口,然后创建一个线程
  • 2.线程里面不断调用阻塞方法 serversocket.accept()获取新的连接
  • 3.当获取到新的连接之后,给每条连接创建一个新的线程,这个线程负责从该连接中读取数据
  • 4.然后读取数据是以字节流的方式

客户端代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package top.zhoudl.io;

import java.io.IOException;
import java.net.Socket;
import java.util.Date;

/**
 * Created by zhoudl on 2018/10/3.
 * IO 编程 客户端
 */
public class IOClient {

    public static void client(int port,String address){

        new Thread(() -> {
            try {
                // 建立连接
                Socket socket = new Socket(address,port);
                while (true) {
                    try {
                        socket.getOutputStream()
                            .write((new Date() + ": hello world").getBytes());
                        // 每隔2秒向服务器发送一条 hello world
                        Thread.sleep(2000);
                    } catch (Exception e) {
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }).start();
    }

    public static void main(String[] args) {
        client(8080,"127.0.0.1");
    }
}
O 编程模型在客户端较少的情况下运行良好,但是对于客户端比较多的业务来说,单机服务端可能需要支撑成千上万的连接,IO 模型可能就不太合适了,我们来分析一下原因,根据刚才举例的IO编程模型来说,传统的 IO 模型中,每个连接创建成功之后都需要一个线程来维护,每个线程包含一个 while 死循环,那么 1w 个连接对应 1w 个线程,继而 1w 个 while 死循环,这就带来如下几个问题:
  • 线程资源受限:同一时刻有大量的线程处于阻塞状态是非常严重的资源浪费
  • 线程切换效率低下:单机 CPU 核数固定,线程爆炸之后操作系统频繁进行线程切换,应用性能急剧下降
  • 字节流读取数据:效率低下

2

NIO编程模型

NIO编程模型可以解决的问题
线程资源受限问题
NIO 编程模型中,新来一个连接不再创建一个新的线程,而是可以把这条连接直接绑定到某个固定的线程,然后这条连接所有的读写都由这个线程来负责。 IO 模型中,一个连接来了,会创建一个线程,对应一个 while 死循环,死循环的目的就是不断监测这条连接上是否有数据可以读,大多数情况下,1w 个连接里面同一时刻只有少量的连接有数据可读,因此,很多个 while 死循环都白白浪费掉了,因为读不出啥数据。 而在 NIO 模型中,这么多 while 死循环变成一个死循环,这个死循环由一个线程控制,那么他又是如何做到一个线程,一个 while 死循环就能监测1w个连接是否有数据可读的呢? 这就是 NIO 模型中 selector 的作用,一条连接来了之后,现在不创建一个 while 死循环去监听是否有数据可读了,而是直接把这个新的连接注册到 selector 上,然后,通过检查这个 selector,就可以批量监测出有数据可读的连接,进而读取数据。 这就是 NIO 模型解决线程资源受限的方案,实际开发过程中,我们会开多个线程,每个线程都管理着一批连接 ,相对于 IO 模型中一个线程管理一条连接,消耗的线程资源大幅减少。
线程切换效率问题
与此同时,NIO中线程切换效率也会变得高很多,因为线程数量减少,对应所需切换次数也就减少了。
读写效率问题
IO编程使用字节流读取数据,而NIO编程使用的是字节块,NIO模型维护了一个缓冲区,可以按块从这个缓冲区中读取数据。这就好比小时候嗑瓜子(当然我长大之后还是喜欢这样),一般会先嗑好很多之后,然后一次性吃到嘴里,这种快感比一个一个塞嘴里咬爽了不少。对于程序来讲,效率自然高了很多。 接下来演示一下使用JDK原生的API实现NIO编程,可能比较辣眼睛,非礼勿视(说实话,下面这段代码我也是拷过来的,因为JDK原生的NIO编程用起来实在是恐怖,恐怖如斯,倒吸凉气,有木有?) package top.zhoudl.NIO; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.util.Iterator; import java.util.Set; /** * Created by zhoudl on 2018/10/3. */ public class NIOServer { public static void main(String[] args) throws IOException { Selector serverSelector = Selector.open(); Selector clientSelector = Selector.open(); new Thread(() -> { try { // 对应IO编程中服务端启动 ServerSocketChannel listenerChannel = ServerSocketChannel.open(); listenerChannel.socket().bind(new InetSocketAddress(8000)); listenerChannel.configureBlocking(false); listenerChannel.register(serverSelector, SelectionKey.OP_ACCEPT); while (true) { // 监测是否有新的连接,这里的1指的是阻塞的时间为 1ms if (serverSelector.select(1) > 0) { Set<SelectionKey> set = serverSelector.selectedKeys(); Iterator<SelectionKey> keyIterator = set.iterator(); while (keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if (key.isAcceptable()) { try { // (1) 每来一个新连接,不需要创建一个线程,而是直接注册到clientSelector SocketChannel clientChannel = ((ServerSocketChannel) key.channel()).accept(); clientChannel.configureBlocking(false); clientChannel.register(clientSelector, SelectionKey.OP_READ); } finally { keyIterator.remove(); } } } } } } catch (IOException ignored) { } }).start(); new Thread(() -> { try { while (true) { // (2) 批量轮询是否有哪些连接有数据可读,这里的1指的是阻塞的时间为 1ms if (clientSelector.select(1) > 0) { Set<SelectionKey> set = clientSelector.selectedKeys(); Iterator<SelectionKey> keyIterator = set.iterator(); while (keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if (key.isReadable()) { try { SocketChannel clientChannel = (SocketChannel) key.channel(); ByteBuffer byteBuffer = ByteBuffer.allocate(1024); // (3) 读取数据以块为单位批量读取 clientChannel.read(byteBuffer); byteBuffer.flip(); System.out.println(Charset.defaultCharset().newDecoder().decode(byteBuffer) .toString()); } finally { keyIterator.remove(); key.interestOps(SelectionKey.OP_READ); } } } } } } catch (IOException ignored) { } }).start(); } } 简单分析下过程:
  • NIO 模型中通常会有两个线程,每个线程绑定一个轮询器 selector ,在我们这个例子中serverSelector负责轮询是否有新的连接,clientSelector负责轮询连接是否有数据可读
  • 服务端监测到新的连接之后,不再创建一个新的线程,而是直接将新连接绑定到clientSelector上,这样就不用 IO 模型中 1w 个 while 循环在死等,参见(1)
  • clientSelector被一个 while 死循环包裹着,如果在某一时刻有多条连接有数据可读,那么通过 clientSelector.select(1)方法可以轮询出来,进而批量处理,参见(2)
  • 数据的读写以内存块为单位,参见(3)

3

总结

根据大佬的讲解,这是大佬的原话:

  • JDK 的 NIO 编程需要了解很多的概念,编程复杂,对 NIO 入门非常不友好,编程模型不友好,ByteBuffer 的 Api 简直反人类
  • 对 NIO 编程来说,一个比较合适的线程模型能充分发挥它的优势,而 JDK 没有给你实现,你需要自己实现,就连简单的自定义协议拆包都要你自己实现
  • JDK 的 NIO 底层由 epoll 实现,该实现饱受诟病的空轮询 bug 会导致 cpu 飙升 100%
  • 项目庞大之后,自行实现的 NIO 很容易出现各类 bug,维护成本较高

接下来进入正题,开始学习Netty编程

4

Netty编程模型

Netty是什么?
  • Netty 何方神圣?根据我的理解就是它封装了JDK原生的NIO编程,可以让我们用的更爽。 Netty 是一个异步事件驱动的网络应用框架,用于快速开发可维护的高性能服务器和客户端。
优点
  • Netty底层模型可以随意切换,只需改动几个参数而已;
  • Netty自带拆包解包,异常机制检测等,让我们只专注于业务逻辑开发;
  • Netty 解决了 JDK 的很多包括空轮询在内的 Bug;
  • Netty 底层对线程,selector 做了很多细小的优化,精心设计的 reactor 线程模型做到非常高效的并发处理;
  • 自带各种协议栈:处理任何一种通用协议都几乎不用亲自动手;
  • Netty 已经历各大 RPC 框架,消息中间件,分布式通信中间件线上的广泛验证,如dubbo、elecsticsearch等底层通信都使用了Netty。
使用Netty编程
  • 引入Maven依赖 <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.6.Final</version> </dependency>

服务端

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package top.zhoudl.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;

/**
 * Created by zhoudl on 2018/10/3.
 */
public class NettyServer {

    public static void server (int port) {

        ServerBootstrap serverBootstrap = new ServerBootstrap();
        // boss 对应 IOServer.java 中的接受新连接线程,主要负责创建新连接
        NioEventLoopGroup boss = new NioEventLoopGroup();
        // worker 对应 IOClient.java 中的负责读取数据的线程,主要用于读取数据以及业务逻辑处理
        NioEventLoopGroup worker = new NioEventLoopGroup();
        serverBootstrap.group(boss,worker)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<Channel>() {
                    @Override
                    protected void initChannel(Channel channel) throws Exception {
                        channel.pipeline().addLast(new StringDecoder());
                        channel.pipeline().addLast(new SimpleChannelInboundHandler<String>() {
                            @Override
                            protected void channelRead0(ChannelHandlerContext ctx, String msg) {
                                System.out.println(msg);
                            }
                        });
                    }
                })
                .bind(8080);
    }

    public static void main(String[] args) {
        server(8080);
    }
}

客户端

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package top.zhoudl.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;
import java.util.Date;
/**
 * Created by zhoudl on 2018/10/3.
 */
public class NettyClient {
    public static void client(String hots,int port) throws InterruptedException {
        Bootstrap bootstrap = new Bootstrap();
        NioEventLoopGroup group = new NioEventLoopGroup();
        // 设置线程组
        bootstrap.group(group)
                // 设置线程模型
                .channel(NioSocketChannel.class)
                // 设置连接读写处理逻辑
                .handler(new ChannelInitializer<Channel>() {
                    @Override
                    protected void initChannel(Channel channel) {
                        channel.pipeline().addLast(new StringEncoder());
                    }
                });
        // 连接指定地址的指定端口
        ChannelFuture connect = bootstrap.connect(hots, port);
        // 判断是否连接成功
        // 实际开发中 在此处肯定是要添加连接重试的逻辑的
        connect.addListener(future -> {
                    if (future.isSuccess()) {
                        System.out.println("连接成功!");
                    } else {
                        System.err.println("连接失败!");
                    }
                });
        Channel channel = connect.channel();
        while (true) {
            channel.writeAndFlush(new Date() + ": hello world!");
            Thread.sleep(2000);
        }
    }
    public static void main(String[] args) throws InterruptedException {
        client("127.0.0.1",8080);
    }
}

5

总结

生活是好的,峰回路转,柳暗花明,前面总会有另一番不同的风光。

使用了Netty进行NIO编程之后,是不是觉得爽了很多,虽然现在你还不太了解上述代码具体是做什么用的,但我想聪明的你对比着前边的或者是自己已经熟知的Java Socket编程也能猜个一二。所谓学习,便是大胆猜测,小心验证,当最终的结果证实你的猜想之后 ,你会发现,疯起来,整个世界都是你的!(相应的,沉默下来,整个世界都与你无关)

服务端启动过程分析

最小参数启动举例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class NettyServer {
    public static void main(String[] args) {
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap
                .group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    protected void initChannel(NioSocketChannel ch) {
                    }
                });
        serverBootstrap.bind(8080);
    }
}
  • 创建了两个线程NioEventLoopGroup ,我们暂且定义名字为 bossGroupworkerGroup ,和传统的IO编程相比,他们俩可以理解为 IO编程中的两个线程组,前者表示监听端口,使用accept()方法建立连接,后者表示每一个连接的读写数据线程组,bossGroup负责接活,workerGroup则负责真正的干活(这也是起这个名字的源头,bossGroup就好比老板,负责接活签合同,而workerGroup则表示下海干活的员工);
  • ServerBootstrap是一个启动类,负责引导我们对服务端的操作;
  • 通过 ServerBootstrap.group()方法将两大线程组设置进去,也就是说这个引导类至此线程模型就确定了;
  • 制定服务端的线程模型为NIO:.channel(NioServerSocketChannel.class) ,如果要设置成Bio的话对应 OioServerSocketChannel.class
  • 调用 childHandler() 方法,给引导类创建一个ChannelInitializer,这个类 是 Netty 对 NIO 类型的连接的抽象,而我们前面NioServerSocketChannel也是对 NIO 类型的连接的抽象,NioServerSocketChannelNioSocketChannel的概念可以和 BIO 编程模型中的ServerSocket以及Socket两个概念对应上。

总结一点

启动一个Netty服务端,最少需要3个过程

  • 指定线程模型
  • 指定IO模型
  • 连接读写处理逻辑

客户端启动流程概述

学完服务端启动流程之后,客户端启动流程就比较简单了,代码直接参考上述NettyClient.java Netty提供的API个人觉得很优秀,而且大多都简介明了,无论是客户端还是服务端。客户端启动流程大致概括如下:

  • 创建启动类Bootstrap,创建线程NioEventLoopGroup;
  • 利用 Bootstrapgroup()方法为Bootstrap设置线程组,也就是指定线程模型;
  • 指定IO模型:.channel(NioSocketChannel.class) 指定为NIO模型;
  • 处理读写逻辑:.handler(new ChannelInitializer<Channel>() 指定一个handler ;
  • 配置好 线程模型、IO 模型、业务处理逻辑之后,开始建立连接,connect()方法的第一个参数为IP或者域名,第二个参数为连接端口号。此外,connect()方法返回的是一个Future,了解Java的应该会知道这是个一个异步的,通过 addListener方法可以监听到连接是否成功,进而打印出连接信息。

客户端启动过程中会有个失败重连的问题:

鉴于失败重连和第一次获取连的逻辑基本分毫不差,所以此处我们很自然的想到了可以使用递归,所以地NettyClient.java中的connect()方法做出封装

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private static void connect(Bootstrap bootstrap, String host, int port, int retryCounts) {
    bootstrap.connect(host, port).addListener(future -> {
        if (future.isSuccess()) {
            System.out.println("success!");
        } else if (retryCounts == 0) {
            System.err.println("The number of retries has been used up, giving up the connection!");
        } else {
            // 第几次重新建立连接
            int number = (MAX_RETRY - retryCounts) + 1;
            // 本次重连的时间间隔
            int delay = 1 << order;
            System.err.println(new Date() + ":Connection failed,Reconnected for the"  + number +  "time");
            bootstrap.config().group().schedule(() -> connect(bootstrap, host, port, retryCounts - 1), delay, TimeUnit
                    .SECONDS);
        }
    });
}

以上今天的文章就结束了,在此感谢闪电侠大佬的Netty学习教程,此文是作为学习总结,有不的地方欢迎大家指正!

下一篇将了解利用Netty进行服务端和客户端的双向通信。

以上代码会同步更新在本人的Github和CSDN上

Github地址:https://github.com/Bylant/LeetCode

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-10-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员啊粥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
一篇文章搞定Netty入门
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
用户1212940
2019/11/13
4240
用Socket编程?我还是选择了Netty
最近在写IO的这块的内容,于是就免不了去研究IO,NIO,AIO,在看NIO的时候,阿粉就发现了一个极其好的东西,那就是Netty,为什么说他好呢?大家就跟着阿粉来深度认识一下Netty吧。 什么是N
架构师修炼
2021/05/17
3.5K0
用Socket编程?我还是选择了Netty
Netty入门篇-从双向通信开始
Netty是由JBOSS提供的一个java开源框架,现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
niceyoo
2020/07/09
4710
分布式专题|都说netty入门很难,那是因为你没有看我的文章!
在写代码之前,我们先看下netty的线程模型,这比那固定格式的代码将会更有趣,看完线程模型,你就知道netty写的那几段固定代码的意义了。
AI码师
2020/12/26
1.6K0
分布式专题|都说netty入门很难,那是因为你没有看我的文章!
最强开源网络应用框架 Netty,没有之一,直接“榨干”CPU!
👆点击“博文视点Broadview”,获取更多书讯 在开始了解Netty是什么之前,我们先来回顾一下,如果需要实现一个客户端与服务端通信的程序,使用传统的IO编程,应该如何来实现? IO编程 我们简化一下场景:客户端每隔两秒发送一个带有时间戳的“hello world”给服务端,服务端收到之后打印它。 在传统的IO模型中,每个连接创建成功之后都需要由一个线程来维护,每个线程都包含一个while死循环,那么1万个连接对应1万个线程,继而有1万个while死循环,这就带来如下几个问题。 线程资源受限:线程是
博文视点Broadview
2022/03/10
6310
《跟闪电侠学Netty》阅读笔记 - 开篇入门Netty
《跟闪电侠学Netty》 并不是个人接触的第一本Netty书籍,但个人更推荐读者把它作为作为第一本Netty入门的书籍。
阿东
2023/06/27
5130
《跟闪电侠学Netty》阅读笔记 - 开篇入门Netty
NIO 读数据和写数据方式
整个 NIO 体系包含的类远远不止这三个,只能说这三个是 NIO 体系的 “核心 API”。上面已经对这三个概念进行了基本的阐述,这里就不多做解释了。
happyJared
2019/08/08
7340
Java面试常考的 BIO,NIO,AIO 总结
熟练掌握 BIO,NIO,AIO 的基本概念以及一些常见问题是你准备面试的过程中不可或缺的一部分,另外这些知识点也是你学习 Netty 的基础。
Java技术江湖
2019/09/25
8060
Java面试常考的 BIO,NIO,AIO 总结
NIO (New I/O)
NIO是一种同步非阻塞的I/O模型,在Java 1.4 中引入了 NIO 框架,对应 java.nio 包,提供了 Channel , Selector,Buffer等抽象。
崔笑颜
2020/06/08
8160
史诗级最强教科书式“NIO与Netty编程”
java.nio全称java non-blocking IO,是指JDK1.4开始提供的新API。从JDK1.4开始,Java提供了一系列改进的输入/输出的新特性,也被称为NIO(既New IO),新增了许多用于处理输入输出的类,这些类都被放在java.nio包及子包下,并且对原java.io包中的很多类进行改写,新增类满足NIO的功能。 NIO和BIO有着相同的目的和作用,但是它们的实现方式完全不同,BIO以流的方式处理数据,而NIO以块的方式处理数据,块I/O的效率比流I/O高很多。另外,NIO是非阻塞式的,这一点跟BIO也很不相同,使用它可以提供非阻塞式的高伸缩性网络。 NIO主要有三大核心部分 :Channel(通道),Buffer(缓冲区),Selector(选择器)。传统的BIO基于字节流和字符流进行操作,而NIO基于Channel和Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择区)用于监听多个通道的事件(比如 :连接打开,数据到达)。因此使用单个线程就可以监听多个数据管道。
海仔
2019/08/26
9420
史诗级最强教科书式“NIO与Netty编程”
Java 中 3 种常见的 IO 模型
如下图,应用程序发出一个 read 调用,内核空间需要经历准备数据的几个阶段,准备好之后返回数据给应用程序。期间如果另一个应用程序也需要 read 调用,那么它必须等待;这就是阻塞。
wsuo
2021/06/24
3010
彻底搞懂NIO效率高的原理
这篇文章读不懂的没关系,可以先收藏一下。笔者准备介绍完epoll和NIO等知识点,然后写一篇Java网络IO模型的介绍,这样可以使Java网络IO的知识体系更加地完整和严谨。初学者也可以等看完IO模型介绍的博客之后,再回头看这些博客,会更加有收获。
全菜工程师小辉
2019/08/16
2.6K0
滴滴面试:谈谈你对Netty线程模型的理解?
Netty 线程模型是指 Netty 框架为了提供高性能、高并发的网络通信,而设计的管理和利用线程的策略和机制。
磊哥
2024/05/31
3000
从NIO到Netty开发
文章转自:https://blog.csdn.net/qq285016127/article/details/80393951 1. 从传统BIO到NIO的升级 Client/Server模型是网络编程的基本模型,服务端提供位置信息,客户端通过连接操作向服务端发起连接请求,通过三次握手建立连接,如果连接建立成功,双方就可以通过网络套接字(Socket)进行通信。 传统的Socket编程是服务端一直处于accpet阻塞等待的状态,并且只有客户端发送了请求,服务才会从阻塞状态变成处理任务的状态,当任务处理完了,
Java高级架构
2018/07/20
5920
nio与netty编程(二)
Netty 是由 JBOSS 提供的一个 Java 开源框架。Netty 提供异步的、基于事件驱动的网络应用程序框架,用以快速开发高性能、高可靠性的网络 IO 程序。 Netty 是一个基于 NIO 的网络编程框架,使用 Netty 可以帮助你快速、简单的开发出一个网络应用,相当于简化和流程化了 NIO 的开发过程。 作为当前最流行的 NIO 框架,Netty 在互联网领域、大数据分布式计算领域、游戏行业、通信行业等获得了广泛的应用,知名的 Elasticsearch 、Dubbo 框架内部都采用了 Netty。
周杰伦本人
2022/10/25
5000
nio与netty编程(二)
09-Netty 高性能架构设计-基于Netty开发TCP服务
Netty快速入门实例-TCP服务 需求 使用IDEA创建Netty项目 Netty服务器在6668端口监听, 客户端能发送消息给服务器"Hello, 服务器~" 服务器可以回复消息给客户端"hello, 客户端~" 目的: 对Netty线程模型 有一个初步认识, 便于理解Netty 模型理论 编写服务端 编写客户端 对Netty程序进行分析, 看看Netty模型特点 添加Netty依赖 <!-- https://mvnrepository.com/artifact/io.netty/netty-all -
彼岸舞
2022/02/18
5080
完美诠释NIO的强大之处-原理和实战
平时工作中,很大部分时间都投入了业务。我们对于一些框架、设计思想等都没有太去的关注,第一个深入一个技术底层是比较枯燥与孤独的;第二个就是没有人带领去用一个有趣或者通俗易懂的教导;但如果真的是明白了那些大牛们的思维方式,我们都会异口同声的称赞他们,真的就是牛逼啊。
chengcheng222e
2021/11/04
2220
netty系列之:NIO和netty详解
netty为什么快呢?这是因为netty底层使用了JAVA的NIO技术,并在其基础上进行了性能的优化,虽然netty不是单纯的JAVA nio,但是netty的底层还是基于的是nio技术。
程序那些事
2022/03/09
6460
45 张图深度解析 Netty 架构与原理
接下来我们会学习一个 Netty 系列教程,Netty 系列由「架构与原理」,「源码」,「架构」三部分组成,今天我们先来看看第一部分:Netty 架构与原理初探,大纲如下:
kunge
2020/11/27
25.7K4
netty Reactor模式(源码死磕
1. 为什么是Reactor模式 2. Reactor模式简介 3. 多线程IO的致命缺陷 4. 单线程Reactor模型 4.1. 什么是单线程Reactor呢? 4.2. 单线程Reactor的参考代码 4.3. 单线程模式的缺点: 5. 多线程的Reactor 5.1. 基于线程池的改进 5.2. 改进后的完整示意图 5.3. 多线程Reactor的参考代码 6. Reactor持续改进 7. Reactor编程的优点和缺点 7.1. 优点 7.2. 缺点
py3study
2020/01/15
2.7K0
相关推荐
一篇文章搞定Netty入门
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验