带你玩转Netty(一)

导语

netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.

Netty简介

上面的导语是netty官方的一个介绍,netty 其实就是基于事件驱动,快速开发高并发,高可靠性的服务和客户端的一个开源框架。主要特性有以下几点。

设计

  • 统一的API,适用于不同的协议(阻塞和非阻塞)
  • 基于灵活、可扩展的事件驱动模型
  • 高度可定制的线程模型
  • 可靠的无连接数据Socket支持(UDP)

性能

  • 更好的吞吐量,低延迟
  • 更省资源
  • 尽量减少不必要的内存拷贝

安全

  • 完整的SSL/ TLS和STARTTLS的支持

易用

  • 完善的Java doc,用户指南和样例,社区很活跃
  • 简洁简单
  • 仅依赖于JDK1.5

Netty框架

核心部分

  • 零拷贝

    “Zero-copy” describes computer operations in which the CPU does not perform the task of copying data from one memory area to another.

    上面是wiki的一描述,它通常是指计算机在网络上发送文件时,不需要将文件内容拷贝到用户空间(User Space)而直接在内核空间(Kernel Space)中传输到网络的方式,所谓的两个空间只是说明两个不一样的内存区域,通过减少不同内存区域的拷贝,减低cpu的消耗。下面有两张对比图

    1、非零拷贝模式

    2、零拷贝模式

    Netty的零拷贝与实际定义还是有点出入,java是基于虚拟机的,其实都是用户空间,Netty中的零拷贝,更多的是一种数据的优化操作,比如多包合并处理上,netty是将各个包的地址记录下来,在逻辑上合成一个整体,实际存储还是独立的,这样减少内存拷贝,降低cpu消耗。

  • 统一通讯API

    netty提供了命名为 channel 统一异步IO接口,主要是为了解决java OIO,NIO API 不兼容,简化业务层的工作。

  • 可扩展的事件模型

    Netty has a well-defined event model focused on I/O. It also allows you to implement your own event type without breaking the existing code because each event type is distinguished from another by a strict type hierarchy. This is another differentiator against other frameworks.

    Netty是通过ChannelEvent作为事件流载体,通过ChannelHander来做事件逻辑处理,channelHander又可分为INBoundHandler 和 OUTBoundHandler分别处理流入数据和流出数据,Event则通过sendDownStream 和 sendUpStream 在每个handler中流转,ChannelPipeline作为handler的容器,用户自定义的handler只要添加到pipe,就可以截取数据流做业务处理。

所有的数据流转,和执行过程都是在一个线程(EventLoop)上执行的,这种串行化的处理方式,让netty无锁化,无需处理数据竞争问题,提高了执行效率。

高级组件

  • 编解码框架

    netty提供里提供一套EncodeHandler 和 DecodeHandler,将业务逻辑从编解码分离,大家可以了解一下,有时间会对这块仔细说明

  • SSL / TLS Support

    在netty中使用SSL也是很方便的,使用SSLEngine,SslHandler就可以

  • Http/WebSocket支持

Netty线程模型

Netty支持三种线程模型,分别是单线程模型,多线程模型,以及主从线程模型,重点会介绍主从多线程模型

  • 单线程模型

    从accpet连接到分发到handler处理业务,都在单线程中完成,模型简单,适合简单场景,不适合大并发场景。

  • 多线程模型

    1. Acceptor单独线程接受accpet连接请求,创建Channel,并移交给IO线程池
    2. IO线程池分配线程读取Channel数据,并分发handler处理相关业务
    3. Accpetor是单线程,如果期间执行鉴权,登陆等操作,出现拥堵,会有单点问题。
  • 主从多线程模型

    1. Acceptor线程池(NioEventLoopGroup)分配一个NioEventLoop接受连接请求,并创建Channel,并将Channel移交给IO线程池

    2. I/O线程池((NioEventLoopGroup)分配一个NioEventLoop处理Channel数据,从Channel读数据,并将数据交给handler处理,handler处理完后,向Channel写数据

    3. I/O线程池还可以处理定时任务,和系统任务。

这边多次提到NioEventLoop,许多个NioEventLoop构成NioEventLoopGroup,其主要的职能如下:
1. 作为Acceptor线程,负责处理客户端的请求接入
2. 作为Connecor线程,负责注册监听连接操作位,用于判断异步连接结果
3. 作为IO线程,监听网络读操作位,负责从SocketChannel中读取写报文



这张图很好的说明NioEventLoop的作用,以及Netty串行化的处理链。
1. 一个客户端Channel只能由一个NioEventLoop处理,避免并发资源竞争问题。
2. NioEventLoop的事件是分发给Netty的事件模型,这个模型可以参考上面的说明。

总结

本文主要介绍了Netty的原理,重点对Netty的串行化处理链,线程模型,数据模型做了说明,绕过了细节,希望对大家在大层面去理解Netty有帮助,更多的实践,以及细节,留在后续文章再说。

资料

  1. Netty 零拷贝知识
  2. Netty user guide
  3. Netty 教程

欢迎关注公众号

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值