`
budairenqin
  • 浏览: 201505 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Netty Server端代码简单分析

阅读更多
Netty源码简单分析:
Netty整体架构清晰的分为两部分:
1. ChannelFactory:主要负责生产网络通信相关的Channel和ChannelSink实例,NIO Server端一般使用NioServerSocketChannelFactory,用户也可以定制自己的ChannelFactory。
2. ChannelPipelineFactory:主要用来对传输数据的处理,由于对数据的处理属于业务相关,用户应自己实现ChannelPipelineFactory,然后往ChannelPipelineFactory添加自定义的Handler

Netty服务端启动步骤:
代码:
// 构造一个服务端Bootstrap实例,并通过构造方法指定一个ChannelFactory实现
// 其中后两个参数分别是BOSS和WORK的线程池
Bootstrap serverBootstrap = new ServerBootstrap(
        new NioServerSocketChannelFactory(
                Executors.newCachedThreadPool(), 
                Executors.newCachedThreadPool()));

// 注册用户自己实现的ChannelPipelineFactory
serverBootstrap.setPipelineFactory(this.pipelineFactory);

// 调用bind等待客户端来连接
((ServerBootstrap) serverBootstrap).bind(socketAddress);


Netty提供NIO与BIO两种模式,我们主要关心NIO的模式:
NIO处理方式:
1.Netty用一个BOSS线程去处理客户端的接入,创建Channel
2.从WORK线程池(WORK线程数量默认为cpu cores的2倍)拿出一个WORK线程交给BOSS创建好的Channel实例(Channel实例持有java网络对象)
3.WORK线程进行数据读入(读到ChannelBuffer)
4.接着触发相应的事件传递给ChannelPipeline进行业务处理(ChannelPipeline中包含一系列用户自定义的ChannelHandler组成的链)

有一点要注意的是,执行整个ChannelHandler链这个过程是串行的,如果业务逻辑(比如DB操作)比较耗时,会导致WORK线程长时间被占用得不到释放,最终影响整个服务端的并发处理能力,所以一般我们通过ExecutionHandler线程池来异步处理ChannelHandler调用链,使得WORK线程经过ExecutionHandler时得到释放。
要解决这个问题增加下面代码即可:
ExecutionHandler executionHandler =
        new ExecutionHandler(
                new OrderedMemoryAwareThreadPoolExecutor(16, 1048576, 1048576));
public ChannelPipeline getPipeline() {
        return Channels.pipeline(
                                new DatabaseGatewayProtocolEncoder(),
                                new DatabaseGatewayProtocolDecoder(),
                                executionHandler, // Must be shared
                                new DatabaseQueryingHandler());
}



Netty为ExecutionHandler提供了两种可选的线程池模型:
1) MemoryAwareThreadPoolExecutor
通过对线程池内存的使用控制,可控制Executor中待处理任务的上限(超过上限时,后续进来的任务将被阻塞),并可控制单个Channel待处理任务的上限,防止内存溢出错误;
2) OrderedMemoryAwareThreadPoolExecutor
是1)的子类。除了MemoryAwareThreadPoolExecutor 的功能之外,它还可以保证同一Channel中处理的事件流的顺序性,这主要是控制事件在异步处理模式下可能出现的错误的事件顺序,但它并不保证同一Channel中的事件都在一个线程中执行,也没必要保证这个。
我们看下OrderedMemoryAwareThreadPoolExecutor中的注释:



处理同一个Channel的事件,是串行的方式执行的,但是同一个Channel的多个事件,可能会分布到线程中池中的多个线程去处理,不同的Channel事件可以并发处理,互相并不影响

再来看看MemoryAwareThreadPoolExecutor中的注释:



同一个Channel的事件,并不保证处理顺序,可能一个线程先处理了Channel A (Event 3),然后另一个线程才处理Channel A (Event 2),如果业务不要求保证事件的处理顺序,我认为还是尽量使用MemoryAwareThreadPoolExecutor比较好

Netty采用标准的SEDA(Staged Event-Driven Architecture) 架构
SEDA的核心思想是把一个请求处理过程分成几个Stage,不同资源消耗的Stag使用不同数量的线程来处理,Stag间使用事件驱动的异步通信模式。更进一步,在每个Stage中可以动态配置自己的线程数,在超载时降级运行或拒绝服务。

Netty所设计的事件类型,代表了网络交互的各个阶段,每个阶段发生时,会触发相应的事件并交给ChannelPipeline进行处理。事件处理都是通过Channels类中的静态方法调用开始的。

Channels中事件流转静态方法:
1. fireChannelOpen
2. fireChannelBound
3. fireChannelConnected
4. fireMessageReceived
5. fireWriteCompleteLater
6. fireWriteComplete
7. fireChannelInterestChangedLater
8. fireChannelDisconnectedLater
9. fireChannelDisconnected
10. fireChannelUnboundLater
11. fireChannelUnbound
12. fireChannelClosedLater
13. fireChannelClosed
14. fireExceptionCaughtLater
15. fireExceptionCaught
16. fireChildChannelStateChanged


Netty将网络事件分为两种类型:
1.Upstresam:上行,主要是由网络底层反馈给Netty的,比如messageReceived、channelConnected
2.Downstream:下行,框架自己发起的,比如bind、write、connect等

Netty的ChannelHandler 分为3种类型:
1.只处理Upstream事件:实现ChannelUpstreamHandler接口
2.只处理Downstream事件:实现ChannelDownstreamHandler接口
3.同时处理Upstream和Downstream事件:同时实现ChannelUpstreamHandler和ChannelDownstreamHandler接口
ChannelPipeline维持所有ChannelHandler的有序链表,当有Upstresam或Downstream网络事件发生时,调用匹配事件类型的ChannelHandler来处理。ChannelHandler自身可以控制是否要流转到调用链中的下一个ChannelHandler(ctx.sendUpstream(e)或者ctx.sendDownstream(e)),这一样有一个好处,比如业务数据Decoder出现非法数据时不必继续流转到下一个ChannelHandler

下面是我胡乱的画的一个图:



  • 大小: 111.3 KB
  • 大小: 21.9 KB
  • 大小: 25.9 KB
分享到:
评论

相关推荐

    netty_server实例代码

    通过分析和运行"netty_server"实例代码,你可以更好地理解Netty框架如何与WebSocket协议结合,以及如何处理网络通信的各个阶段,包括连接建立、数据交换和连接关闭。此外,你还可以学习到如何自定义处理器以适应特定...

    netty实战教程、netty代码demo

    通过分析和运行这些示例,你可以了解 Netty 的基本用法,如创建服务器、连接服务器、处理 I/O 事件、自定义编码解码器等。同时,也可以尝试扩展这些示例,例如添加新的处理器以处理特定的业务逻辑,或者实现更复杂的...

    netty_server_demo.zip

    这个"Netty_server_demo.zip"文件很可能是包含了一个简单的 Netty 服务器端的示例代码,用于帮助开发者理解如何在 Java 中使用 Netty 搭建和运行网络服务。 Netty 的核心概念包括以下几个部分: 1. **ByteBuf**:...

    Netty_Chat_server_client_src_java.zip_netty_netty html5 chat_sep

    在这个"Netty_Chat_server_client_src_java.zip"压缩包中,包含了一个基于Netty实现的简单聊天应用的源代码,分为服务器(server)和客户端(client)两部分。 首先,我们来看"server"部分。Netty服务器端通常由多个...

    NettyServer

    在Java程序中,NettyServer运行正常,表明服务器端代码逻辑正确,能够正确地监听端口,处理HTTP请求,并返回响应。但是,当尝试在Android设备上运行时,可能会遇到问题,这通常与Android的沙盒环境和权限管理有关。...

    netty版贪吃蛇

    1. Server模块:实现了Netty服务器端,包括WebSocket服务器处理类,用于处理连接、消息收发和游戏逻辑。 2. Client模块:包含HTML、CSS和JavaScript文件,构建了用户界面和WebSocket客户端逻辑,负责与服务器交互并...

    netty-socketio-demo

    1. src/main/java - 包含项目的源代码,可能有Server端的启动类、Socket.IO处理器以及其他业务逻辑。 2. src/main/resources - 可能存放配置文件,如Netty的配置或Socket.IO的配置。 3. pom.xml - Maven项目配置文件...

    物联网之java实现(springboot + netty + 心跳,附完整源码)

    在物联网领域,Java技术常被用来构建服务器端和客户端应用,尤其在结合Spring Boot和Netty框架时,能实现高效、稳定的数据传输。本实例主要探讨如何利用Java、Spring Boot和Netty来创建一个带有心跳机制的物联网系统...

    netty4.0文件分片上传+断点续传+权限校验

    Netty 是一个高性能、异步事件驱动...rrkd-file-client和rrkd-file-server这两个文件可能包含了实现上述功能的客户端和服务端代码示例,通过分析和学习这些代码,开发者可以更好地理解和应用Netty进行文件上传的实践。

    netty学习教程

    本教程从基础概念出发,逐步深入到核心组件及其实现细节,并通过一个简单的“Hello World”示例,帮助读者理解如何构建一个完整的Netty应用。这不仅有助于初学者快速入门Netty,也为进阶学习打下了坚实的基础。

    使用Netty实现IMServer,支持Tcp和WebSocket实现。_Java_下载.zip

    4. 编译并运行服务器端代码,通常在主类中有一个 `main` 方法作为入口。 5. 配置客户端连接到服务器,对于WebSocket,可能需要一个Web浏览器和WebSocket客户端库;对于TCP,可以使用Netty的客户端示例或者自建TCP...

    Netty5.0架构剖析和源码解读

    以上代码展示了如何使用`ServerBootstrap`创建一个简单的服务端。首先,我们需要设置两个`EventLoopGroup`:一个负责接收新的连接,另一个负责处理这些连接的读写操作。接着,配置Channel参数和初始化...

    聊天类软件其中的简单的server端

    在服务器端,Java通常用于编写处理客户端请求、管理用户会话、解析数据等逻辑的代码。Java的Socket API是进行网络通信的基础,它提供了创建TCP连接、发送和接收数据的方法。 3. **Android环境下的通信**:尽管...

    基于Java的RTSP服务源码

    "rtspserver"这个文件很可能是Java RTSP服务的源代码。通过阅读和分析这些源码,可以学习到如何设置RTSP服务器,处理客户端请求,以及如何利用RTP/TCP和RTP/UDP模式进行数据传输。同时,还可以了解如何与VLC这样的...

    netty-test:netty学习使用

    通过分析 `netty-test-master` 压缩包中的代码,你可以了解到如何使用 Netty 创建简单的 TCP 服务和客户端,这将帮助你理解 Netty 的基本架构和工作原理。在实际项目中,Netty 可用于构建复杂的网络应用,如分布式...

    JAVA上百实例源码以及开源项目源代码

    Tcp服务端与客户端的JAVA实例源代码 2个目标文件 摘要:Java源码,文件操作,TCP,服务器 Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多...

    java--http--web-server.zip_http server java_http服务_java http服务器

    Java是一种广泛使用的编程语言,尤其在开发Web应用和服务方面具有强大的实力。...通过分析和修改源代码,开发者可以深入了解HTTP协议的工作原理,提升服务器开发技能,并为将来构建更复杂的服务打下基础。

    tiny-web-server:使用 java nio 构建的原型 Web 服务器。 灵感来自 Netty

    总的来说,"tiny-web-server"项目提供了一个学习和实践Java NIO以及服务器端编程的好机会,你可以通过阅读和分析源代码,了解如何利用非阻塞I/O来提高Web服务器的性能,同时也可以借鉴其设计思想,为自己的项目提供...

    JAVA一个简单的即时通讯工具的设计与开发(源代码+LW).rar

    通过分析这个项目的源代码和相关文档,我们可以深入理解其设计原理和实现方法。 首先,我们要了解Java在软件开发中的地位。Java是一种面向对象的编程语言,以其跨平台性、稳定性和强大的库支持而备受开发者喜爱。在...

    Dtree和一个简单的JSP实例

    在本实例中,Dtree被应用于一个简单的JavaServer Pages (JSP)项目,为初学者提供了一个直观的学习入口。 JSP是Java平台上的服务器端技术,用于创建动态web内容。它允许开发者将HTML、CSS、JavaScript与Java代码混合...

Global site tag (gtag.js) - Google Analytics