专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

Netty学习(一)Netty的概念及体系结构

前言

一系列文章旨在把我学习Netty以及使用Netty的一些经验分享出来,希望能帮助到对Netty感兴趣或正要上手的同学们。如果发现我述说得有问题,希望大家能指出讨论,非常感谢。

引导

首先我们要提出几个问题,大家一起思考,然后再通过文章来加深理解。

  • 什么是Netty
  • Netty的诞生是为了解决什么问题
  • Netty的核心组件有哪些

什么是Netty

Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。Netty基于IO多路复用模型,对Java提供的NIO进行了更加完善的包装,解决NIO存在的bug,使用者无需关注太多底层。成熟、稳定、高并发、低延迟、易上手等特点已经获得很多开发者的青睐。

它有以下特性:

  • 设计
    • 统一API,支持多种传输类型,阻塞和非阻塞
    • 真正的无连接数据报套接字支持
    • 链接逻辑组件以支持复用
  • 性能
    • 拥有比Java的NIO更高的吞吐量以及更低的延迟
    • 得益于池化和复用,拥有更低的资源消耗
  • 健壮性
    • 不会因为慢速、快速或者超载的连接而导致OutOfMemoryError
    • 消除在高速网络中NIO应用程序常见的不公平读/写比率
  • 安全性
    • 完整的SSL/TLS以及StartTLS支持

Netty的诞生为了解决什么问题

大家已经知道Netty是基于Java NIO的基础上实现的(需要区别Java NIO 以及NIO,前者是基于IO多路复用实现,后者一般指是None Blocking IO,非阻塞IO),主要原因在于Java NIO存在多方面缺陷:

  • 复杂的API、类库。Selector、ServerSocketChannel、SocketChannel、ByteBuffer等,想写出优秀高质量的NIO程序你就需要对网络编程这块非常熟悉才行。
  • 针对半包读写,网络阻塞,编码处理等等,NIO要实现的难度比较大
  • 存在bug,最为代表性的是Epoll空轮询,导致CPU利用率爆满。

由此,Netty就诞生了,它不单单解决了NIO的缺陷,还增加了多种功能支持,例如快速切换NIO和BIO,自定义编码解码,原生也提供了多种类库,以支持多种协议,包括TCP\UDP\MQTT\Protocol Buffers 等等。还有它高并发,低延迟的特性,让使用者能快速,方便上手,专心处理业务而无需关注性能和漏洞问题,因为Netty都已经帮你处理好这些东西。

Netty的核心组件

上面我们知道了什么是Netty以及Netty能给我们带来什么好处,下面我们就来看一下Netty的核心组件。

  • Channel
  • 回调
  • Future
  • 事件和ChannelHandler

Channel

Channel是Java NIO的一个基本构造,它代表到一个实体(实体包括硬件设备、文件、网络套接字等)的开放连接,可以进行读操作或写操作。简单来说,它就是两者之间可以进行数据交互的一条通道,不论是入站或出站数据(入站出站可以理解成数据的传出传入),都通过channel来传输。它可以被打开或关闭,连接或断开链接。

回调

进行多线程异步开发的人对回调这个名词应该不陌生,通俗来讲,它就是在某一个操作结束之后要执行的方法,方法我们可以自定义,可以包括通知、异常处理等等。 在Netty中很多地方都使用了回调,举个例子:ChannelInboundHandler中的channelActive方法,当一个新的连接已经建立的时候,该方法就会被执行。

/**
 * @author chenws
 * @date 2020/03/17 11:01:33
 */
@Slf4j
public class ConnectHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("client-{}已经成功连接。",ctx.channel().remoteAddress());
        super.channelActive(ctx);
    }
}

Future

Future提供了另一种在操作完成时通知应用程序的方式,你可以把它看作是一个异步操作结果的占位符,它将在未来某一时刻完成,并可以访问其结果。

Java NIO与之对应的是java.util.concurrent.Future,但是它实现的Future需要手动去检查对应的操作是否已经完成,或者一直阻塞直至它完成,这样的话即麻烦又耗资源,因此Netty在java Future的基础上编写了自己的一套支持异步读取的Future。

直接看例子 listener,监听事件,根据状态来判断操作是否成功,不成功的话可以打印错误信息。

/**
 * @author chenws
 * @date 2020/03/17 11:27:02
 */
@Slf4j
public class BindListener implements GenericFutureListener<Future<? super Void>> {

    @Override
    public void operationComplete(Future<? super Void> future) throws Exception {
        boolean success = future.isSuccess();
        if(success) {
            log.info("bind操作完成");
        }else {
            Throwable cause = future.cause();
            cause.printStackTrace();
        }
    }
}

绑定操作

/**
 * @author chenws
 * @date 2020/03/17 11:22:14
 */
@Slf4j
public class BindServer {

    public void startServer() throws InterruptedException {
        ServerBootstrap b = new ServerBootstrap();
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup(6);
        b.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                    }
                });
        BindListener bindListener = new BindListener();
        //addListener操作后,当该程序绑定指定ip和端口号后,就会执行配置的listener
        Channel channel = b.bind("localhost", 8080).sync().addListener(bindListener).channel();
    }
}

你可以把Netty的Future看作是回调的一个更加精细的版本,回调和Future是互相补充的机制,它们互相结合,构成Netty关键构建块之一。

事件和ChannelHandler。

首先我们先理解下这两个名词的定义

  • 事件:可以看作是有入站或出站数据而触发的事件
  • ChannelHandler:是我们自定义的一系列处理器,包括但不仅限:编码解码器,记录日志,数据转换,流控制以及我们的业务逻辑处理。

事件入站或出站后通过一系列的ChannelHandler处理数据以达到我们的目的,而ChannelHandler就是通过ChannelPipeline管理起来,它能使我们的事件按顺序的执行ChannelHandler。正是这种设计,使我们的代码耦合度降低,且灵活、方便、易懂。

35_1.png

小结

在本章中,我们主要了解Netty的功能、优点以及核心组件,下一章我们将介绍Netty的相关组件,包括Channel、EventLoop、ChannelFuture。在此之前,大家可以参照我Github上的 Netty-TCP例子来先了解一个Netty应用程序。

文章永久链接:https://tech.souyunku.com/42716

未经允许不得转载:搜云库技术团队 » Netty学习(一)Netty的概念及体系结构

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们