Java 杂谈Spring-BootJAVA相关

Netty框架整体架构及源码知识点

2019-05-04  本文已影响6人  Java机械师

Netty概述

Netty是一个高性能、异步事件驱动的NIO框架,它提供了对TCP、UDP和文件传输的支持。作为当前最流行的NIO框架,Netty在互联网领域、大数据分布式计算领域、游戏行业、通信行业等获得了广泛的应用,一些业界著名的开源组件也基于Netty的NIO框架构建。

Netty 利用 Java 高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 构建一个客户端/服务端,其具有高并发、传输快、封装好等特点。

高并发

Netty是一款基于NIO(Nonblocking I/O,非阻塞IO)开发的网络通信框架,对比于BIO(Blocking I/O,阻塞IO),他的并发性能得到了很大提高 。

传输快

Netty的传输快其实也是依赖了NIO的一个特性——零拷贝。

封装好

Netty封装了NIO操作的很多细节,提供易于使用的API,还有心跳、重连机制、拆包粘包方案等特性,使开发者能能够快速高效的构建一个稳健的高并发应用。

image

Netty框架

Netty项目致力于提供一个异步的、事件驱动的网络应用框架和工具,用于快速开发可维护的、高性能的、高扩展性的服务器和客户端之间的协议。换句话说,Netty式一个NIO客户端服务器框架,能够快速、轻松地开发网络应用例如服务器和客户端间的协议。它简化了网络编程如TCP/IP socket服务器。

JBOSSes Netty的设计吸取了大量的协议如FTP、SMTP、HTTP和各种二进制、基于文本的继承协议等协议的设计经验,成功地找到了一种方法实现易于开发、性能、稳定、灵活的协议开发。

特征:

Netty为用户提供了很多创新和更好的网络开发体验。

1)设计Design

为各种传输类型(块和非块socket)提供了统一的API;

建立在灵活和可扩展的事件模型;

高度可定制的线程模式——单线程,一个或多个线程池(如SEDA);

可信的五连接数据报socket支持。

2)易于使用

良好文档化的Javadoc、用户向导和例子;

结构并不臃肿;

无其它的依赖,只需JDK1.5或以上。

3)性能

高吞吐量、低延迟时间;

很小的资源消耗;

最小化不必要的内存复制。

4)健壮性

不会因为快速连接、慢速连接或超载连接引起OutOfMemoryError错误;

高速网络下不会引起NIO程序的读写异常。

5)安全

完全支持SSL/TLS和StartTLS;

在Java Applet环境下运行正常。

6)社区

至少每两周一个版本发布。

项目主页: http://www.jboss.org/netty/

文档地址: http://www.jboss.org/netty/documentation.html

下载地址: http://www.jboss.org/netty/downloads.html

为什么选择Netty

Socket通信(IO/NIO/AIO)编程,对于通信模型已经有了一个基本的认识。我们学习的仅仅是一个模型,如果想把这些真正的用于实际工作中,那么还需要不断的完善、扩展和优化。比如经典的TCP读包写包问题,或者是数据接收的大小,实际的通信处理与应答的处理逻辑等等一些细节问题需要认真的去思考,而这些都需要大量的时间和经历,以及丰富的经验。所以想学好Socket通信不是件容易事,那么接下来就来学习一下新的技术Netty,为什么会选择Netty?因为它简单!使用Netty不必编写复杂的逻辑代码去实现通信,再也不需要去考虑性能问题,不需要考虑编码问题,半包读写等问题。强大的Netty已经帮我们实现好了,我们只需要使用即可。

Netty是最流行的NIO框架,它的健壮性、功能、性能、可定制性和可扩展性在同类框架都是首屈一指的。它已经得到成百上千的商业/商用项目验证,如Hadoop的RPC框架Avro、RocketMQ以及主流的分布式通信框架Dubbox等等。

image

Netty的线程模型

并发系统可以采用多种并发编程模型来实现。并发模型指定了系统中的线程如何通过协作来完成分配给它们的作业。不同的并发模型采用不同的方式拆分作业,同时线程间的协作和交互方式也不相同。

对于网络请求一般可以分为两个处理阶段,一是接收请求任务,二是处理网络请求。根据不同阶段处理方式分为以下几种线程模型:

串行化处理模型

这个模型中用一个线程来处理网络请求连接和任务处理,当worker接受到一个任务之后,就立刻进行处理,也就是说任务接受和任务处理是在同一个worker线程中进行的,没有进行区分。这样做存在一个很大的问题是,必须要等待某个task处理完成之后,才能接受处理下一个task。

而通常情况下,任务的处理过程会比任务的接受流程慢得多。例如在处理任务的时候,我们可能会需要访问远程数据库,这属于一种网络IO。通常情况下IO操作是比较耗时的,这直接影响了下一个任务的接受,而且通常在IO操作的时候,CPU是比较空闲的,白白浪费了资源。

因此可以把接收任务和处理任务两个阶段分开处理,一个线程接收任务,放入任务队列,另外的线程异步处理任务队列中的任务。

并行化处理模型

由于任务处理一般比较缓慢,会导致任务队列中任务积压长时间得不到处理,这时可以使用多线程来处理。这里使用的是一个公共的任务队列,多线程环境中不免要通过加锁来保证线程安全,我们常用的线程池就是这种模式。可以通过为每个线程维护一个任务队列来改进这种模型。

Reactor线程模型

reactor线程模型关注的是:任务接受之后,对处理过程继续进行切分,划分为多个不同的步骤,每个步骤用不同的线程来处理,也就是原本由一个线程处理的任务现在由多个线程来处理,每个线程在处理完自己的步骤之后,还需要将任务转发到下阶段线程继续进行处理。

Netty的Reactor线程模型

其中mainReacotor,subReactor,Thread Pool是三个线程池。mainReactor负责处理客户端的连接请求,并将accept的连接注册到subReactor的其中一个线程上;subReactor负责处理客户端通道上的数据读写;Thread Pool是具体的业务逻辑线程池,处理具体业务。

Netty具体线程模型

如何理解NioEventLoop和NioEventLoopGroup

1)NioEventLoop实际上就是工作线程,可以直接理解为一个线程。NioEventLoopGroup是一个线程池,线程池中的线程就是NioEventLoop。

2)实际上bossGroup中有多个NioEventLoop线程,每个NioEventLoop绑定一个端口,也就是说,如果程序只需要监听1个端口的话,bossGroup里面只需要有一个NioEventLoop线程就行了。

每个NioEventLoop都绑定了一个Selector,所以在Netty的线程模型中,是由多个Selecotr在监听IO就绪事件。而Channel注册到Selector。

一个Channel绑定一个NioEventLoop,相当于一个连接绑定一个线程,这个连接所有的ChannelHandler都是在一个线程中执行的,避免了多线程干扰。更重要的是ChannelPipline链表必须严格按照顺序执行的。单线程的设计能够保证ChannelHandler的顺序执行。

一个NioEventLoop的selector可以被多个Channel注册,也就是说多个Channel共享一个EventLoop。EventLoop的Selecctor对这些Channel进行检查。

在监听一个端口的情况下,一个NioEventLoop通过一个NioServerSocketChannel监听端口,处理TCP连接。后端多个工作线程NioEventLoop处理IO事件。每个Channel绑定一个NioEventLoop线程,1个NioEventLoop线程关联一个selector来为多个注册到它的Channel监听IO就绪事件。NioEventLoop是单线程执行,保证Channel的pipline在单线程中执行,保证了ChannelHandler的执行顺序。

小编准备了关于netty的面试题分享给大家,由于文章篇幅原因以下只分享10道netty的面试题。后五道题未设置答案,需要获取答案和更多Java架构资料、面试题(含答案)和面试心得以及视频资料的可以加入Java猫的架构学习基地:810589193获取!

netty面试题

1.BIO、NIO和AIO的区别?

2.NIO的组成?

3.Netty的特点?

4.Netty的线程模型?

5.TCP 粘包/拆包的原因及解决方法?

6.了解哪几种序列化协议?

7.如何选择序列化协议?

8.Netty的零拷贝实现?

9.Netty的高性能表现在哪些方面?

10.NIOEventLoopGroup源码?

如果你想突破自己的天花板,那一定要比别人付出更多,这个过程是很辛苦的。如果你认准了一条路,坚持走下去,你一定会获得很多收获和你满意的答案。

最后,希望以上的分享能给大家带来收获。更多面试题领取方式加入Java猫的架构学习基地:810589193免费获取!!!

上一篇下一篇

猜你喜欢

热点阅读