Netty入门学习和技术实践

这篇具有很好参考价值的文章主要介绍了Netty入门学习和技术实践。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Netty

Netty入门学习和技术实践,后端,网络协议,nio

1.Netty简介

    Netty是由JBOSS提供的一个java开源框架,现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具,
用以快速开发高性能、高可靠性的网络服务器和客户端程序。
   也就是说,Netty 是一个基于NIO的客户、服务器端的编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现
了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和UDP的socket服务开发。
   “快速”和“简单”并不用产生维护性或性能上的问题。Netty 是一个吸收了多种协议(包括FTP、SMTP、HTTP等各种二进制文本协议)
的实现经验,并经过相当精心设计的项目。最终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸
缩性。
git地址链接: 

2.IO模型

Unix中定义了五种I/O模型:
    阻塞I/O
    非阻塞I/O
    I/O复用(select、poll、linux 2.6种改进的epoll)
    信号驱动IOSIGIO)
    异步I/OPOSIX的aio_系列函数)
Java共支持3种网络编程模型/IO模式:BIONIOAIO

BIO:

同步阻塞模式,进行IO操作时,程序会处于阻塞状态,直到IO操作完成。这意味着当程序进行网络操作或者文件操作时,如果操作耗时很长,
程序会一直等待,无法进行其他任务。虽然BIO的编程模型比较简单,但是它的并发处理能力相对较弱。因为当有多个IO请求时,线程会被
阻塞,CPU无法充分利用。对于高并发场景下的服务器应用来说,BIO的性能表现并不理想。

BIO原理图:Netty入门学习和技术实践,后端,网络协议,nio

AIO:

        Java 7 中引入了 NIO 的改进版 NIO 2,它是异步 IO 模型,异步 IO 是基于事件和回调机制实现的,
 也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。

AIO原理图:
Netty入门学习和技术实践,后端,网络协议,nio
NIO:

     Java 7 中引入了 NIO 的改进版 NIO 2,它是异步 IO 模型,异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返
 回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。
     非阻塞IO虽然相对于阻塞IO大幅提升了性能,其依然存在性能问题,频繁的轮询导致频繁的系统调用,会耗费大量的CPU资源。当并发
很高时,假设有1000个并发,那么单位时间循环内将会有1000次系统调用去轮询执行结果,而实际上可能只有2个请求结果执行完毕,这
就会有998次无效的系统调用,造成严重的性能浪费。NIO问题的本质就是频繁轮询导致的无效系统调用

NIO原理图:
Netty入门学习和技术实践,后端,网络协议,nio
IO多路复用

NIO的升级解决方案,减少系统无效的调用
  线程首先发起 select调用,询问内核数据是否准备就绪,等内核把数据准备好了,用户线程再发起read调用。read调用的过程(数据从内
核空间->用户空间)还是阻塞的。
  目前支持 IO 多路复用的系统调用,有 select,epoll 等。select 系统调用,是目前几乎在所有的操作系统上都有支持
  select调用,内核提供的系统调用,它支持一次查询多个系统调用的可用状态。几乎所有的操作系统都支持。
  epoll调用:linux 2.6 内核,属于 select调用的增强版本,优化了 IO 的执行效率。
  Netty 的非阻塞 I/O 的实现关键是基于 I/O 复用模型

IO多路复用原理图
Netty入门学习和技术实践,后端,网络协议,nio

总结:

  为什么会分为这五种情况,是因为应用程序和操作系统分为用户态和内核态,应用程序对操作系统的内核发起IO调用(系统调用),操作系
统负责的内核执行具体的IO操作。也就是说,我们的应用程序实际上只是发起了IO操作的调用而已,具体 IO 的执行是由操作系统的内核来
完成的。
应用程序发起的一次IO操作实际包含两个阶段:
IO调用阶段:应用程序进程向内核发起系统调用
IO执行阶段:内核执行IO操作并返回
  2.1. 准备数据阶段:内核等待I/O设备准备好数据
  2.2. 拷贝数据阶段:将数据从内核缓冲区拷贝到用户空间缓冲区

增进理解:

 - 同步阻塞:你到饭馆点餐,然后在那等着,还要一边喊:好了没啊!
 - 同步非阻塞:在饭馆点完餐,就去遛狗了。不过溜一会儿,就回饭馆喊一声:好了没啊!
 - 异步阻塞:遛狗的时候,接到饭馆电话,说饭做好了,让您亲自去拿。
 - 异步非阻塞:饭馆打电话说,我们知道您的位置,一会给你送过来,安心遛狗就可以了。

3.Netty框架介绍

Netty 的工作架构图
Netty入门学习和技术实践,后端,网络协议,nio

Server端包含 1Boss NioEventLoopGroup1Worker NioEventLoopGroup
  Boss 专门负责接收客户端的连接, Worker专门负责网络的读写;
  NioEventLoopGroup:相当于 1 个事件循环组,这个组里包含多个事件循环 NioEventLoop,每个 NioEventLoop 包含 1Selector1个事件循环线程。
 Boss NioEventLoop 循环执行的任务包含 3 步:
 1.轮询 Accept 事件。
 2.处理 Accept I/O 事件,与 Client 建立连接,生成 NioSocketChannel,并将 NioSocketChannel 注册到某个 Worker 
 NioEventLoopSelector 上。
 3.处理任务队列中的任务,runAllTasks。任务队列中的任务包括用户调用 eventloop.execute 或 schedule 执行的任务,或者其他线程
提交到该 eventloop 的任务。
 Worker NioEventLoop 循环执行的任务包含 3 步:
 1.轮询 ReadWrite 事件。
 2.处理 I/O 事件,即 ReadWrite 事件,在 NioSocketChannel 可读、可写事件发生时进行处理。
 3.处理任务队列中的任务,runAllTasks。

Selector 选择器原理
Netty入门学习和技术实践,后端,网络协议,nio

netty几大核心概念
拆包/粘包

应用A 通过网络发送数据向应用B 发送消息,大概会经过如下阶段:
  阶段一:应用A 把流数据发送到 TCP发送缓冲区。
  阶段二:TCP发送缓冲区把数据发送到达 B服务器 TCP接收缓冲区。
  阶段三:应用BTCP接收缓冲区读取流数据。

Netty入门学习和技术实践,后端,网络协议,nio

  假设客户端向服务端连续发送了两个数据包,分别用ABCDEF来表示,那么服务端收到的数据可以分为以下三种情况:
 情况1:接收端正常收到两个数据包,即没有发生拆包和粘包的现象。

Netty入门学习和技术实践,后端,网络协议,nio

 情况2:接收端只收到一个数据包,这一个数据包中包含了发送端发送的两个数据包的信息,这种现象即为粘包。

Netty入门学习和技术实践,后端,网络协议,nio

 情况3:接收端收到了两个数据包,但是这两个数据包要么是不完整的,要么就是多出来一块,这种情况即发生了拆包和粘包。

Netty入门学习和技术实践,后端,网络协议,nio

TCP发送数据原由:
  1.因为TCP本身传输的数据包大小就有限制,所以应用发出的消息包过大,TCP会把应用消息包拆分为多个TCP数据包发送出去。
  2.Negal算法的优化,当应用发送数据包太小,TCP为了减少网络请求次数的开销,它会等待多个消息包一起,打成一个TCP数据包一次发送
出去。
TCP接收方的原由:
  1.TCP缓冲区里的数据都是字符流的形式,没有明确的边界,因为数据没边界,所以应用从TCP缓冲区中读取数据时就没办法指定一个或几个
消息一起读,而只能选择一次读取多大的数据流,而这个数据流中就可能包含着某个消息包的一部分数据
1)粘包原因:
发送的数据大小小于发送缓冲区,tcp就会把发送的数据多次写入缓冲区,此时发生粘包;
接收数据方的应用层没有及时从 接收缓冲区读取数据,也会发生粘包;
2)拆包原因:
发送的数据大小 大于 tcp发送缓冲区,就会发生拆包;
发送的数据大小 大于 报文最大长度,也会拆包;
原因总结:
 1.一个TCP报文最大能传输65536个字节,也就是16Kb。
 2.TCP是流式协议,数据无边界。

解决粘包拆包的关键在于为每一个数据包添加界限标识,常用方法如下:
方法1)发送方以固定长度封装数据包。如果不足,则补0填充。
方法2)自定义设置数据包的界限标识,如添加特别标识(如======)。接收方通过标识可以识别不同的数据包;
方法3)发送方为每一个数据包添加报文头部。头部至少包含数据包长度(类似http协议的头部length)。 通过这种方式,接收方通过读取头
部的长度知道当前数据包的界限,并在界限处停止读取。

netty处理 拆包/粘包 的方式:
Netty入门学习和技术实践,后端,网络协议,nio

零拷贝:

  
  零拷贝概念:在操作数据时, 不需要将数据buffer从一个内存区域拷贝到另一个内存区域。 少了一次内存的拷贝,CPU的效率就得到的提升。
在系统层面上的零拷贝通常指避免在用户态(User-space)与内核态(Kernel-space)之间来回拷贝数据。NettyZero-copy完全是在用户态
(Java 层面), 更多的偏向于优化数据操作。
netty实现零拷贝原理:
  1.Netty的接收和发送ByteBuffer采用DIRECT BUFFERS,使用堆外直接内存进行Socket读写,不需要进行字节缓冲区的二次拷贝。如果
使用传统的堆内存(HEAP BUFFERS)进行Socket读写,JVM会将堆内存Buffer拷贝一份到直接内存中,然后才写入Socket中。相比于堆外
直接内存,消息在发送过程中多了一次缓冲区的内存拷贝。
  2.Netty提供了组合Buffer对象,可以聚合多个ByteBuffer对象,用户可以像操作一个Buffer那样方便的对组合Buffer进行操作,避免了
传统通过内存拷贝的方式将几个小Buffer合并成一个大的Buffer3.Netty的文件传输采用了transferTo方法,它可以直接将文件缓冲区的数据发送到目标Channel,避免了传统通过循环write方式导致的
内存拷贝问题。

4. Netty实战项目学习

项目学习地址:
Netty教程:十二个实例带你轻松学习Netty
项目代码gitee地址:
nettyTeach

5. Netty实际应用场景

netty可以做什么:
有了Netty,你可以实现自己的HTTP服务器,FTP服务器,UDP服务器,RPC服务器,WebSocket服务器,Redis的Proxy服务器,MySQL的Proxy服务器等等。

传统的HTTP服务器的原理
 1、创建一个ServerSocket,监听并绑定一个端口
 2、一系列客户端来请求这个端口
 3、服务器使用Accept,获得一个来自客户端的Socket连接对象
 4、启动一个新线程处理连接
  4.1、读Socket,得到字节流
  4.2、解码协议,得到Http请求对象
  4.3、处理Http请求,得到一个结果,封装成一个HttpResponse对象
  4.4、编码协议,将结果序列化字节流 写Socket,将字节流发给客户端
 5、继续循环步骤3
   HTTP服务器之所以称为HTTP服务器,是因为编码解码协议是HTTP协议,如果协议是Redis协议,那它就成了Redis服务器,如果协议是
 WebSocket,那它就成了WebSocket服务器,等等。 使用Netty可以定制编解码协议,实现特定协议的服务器。

netty适用行业:

2.1 互联网行业
  1、互联网行业:在分布式系统中,各个节点之间需要远程调用,高性能的 RPC 框架必不可少,Netty 作为异步高性能的通行框架,往往作
为基础通信组件被这些 RPC 框架使用。
 2、典型的应用有:阿里分布式服务框架 DubboRPC 框架使用 Dubbo 协议进行节点间通信,Dubbo 协议默认使用 Netty 作为基础通信
组件,用于实现各进程节点之间的内部通信。

Netty入门学习和技术实践,后端,网络协议,nio

2.2 游戏行业
  1、无论是手游服务端还是大型的网络游戏,Java 语言得到了越来越广泛的应用。
 2Netty 作为高性能的基础通信组件,提供了 TCP/UDPHTTP 协议栈,方便定制和开发私有协议栈,账号登录服务器。
 3、地图服务器之间可以方便的通过 Netty 进行高性能的通信。

2.3 大数据领域

2.2 游戏行业
  1、经典的 Hadoop 的高性能通信 和 序列化组件(AVRO 实现数据文件共享)的 RPC 框架,默认采 Netty 进行跨界点通信。
  2、它的 Netty Service 基于 Netty 框架二次封装实现。

Netty入门学习和技术实践,后端,网络协议,nio
2.4 其它开源项目使用的Netty
网址:https://netty.io/wiki/related-projects.html
Netty入门学习和技术实践,后端,网络协议,nio

6.扩展

netty相关书籍:

 Netty入门与实战:仿写微信 IM 即时通讯系统
 Netty 4.x学习笔记 - 线程模型
 Netty入门与实战
 理解高性能网络模型
 Netty基本原理介绍
 software-architecture-patterns.pdf
 Netty高性能之道 —— 李林锋
 Netty In Action
 Netty权威指南

netty官网:netty.io

netty优秀开源项目
gitee:

 mqtt-cluster:https://gitee.com/quickmsg/mqtt-cluster.git
 netty-mqtt:https://gitee.com/lxrv587/iot_push.git
 heart-netty:https://gitee.com/zjz0812/heart-netty.git
netty_redis_zookeeper:https://gitee.com/crazymaker/netty_redis_zookeeper_source_code.git

github:文章来源地址https://www.toymoban.com/news/detail-683684.html

到了这里,关于Netty入门学习和技术实践的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【Netty专题】【网络编程】从OSI、TCP/IP网络模型开始到BIO、NIO(Netty前置知识)

    【Netty专题】【网络编程】从OSI、TCP/IP网络模型开始到BIO、NIO(Netty前置知识)

    我是有点怕网络编程的,总有点【谈网色变】的感觉。为了让自己不再【谈网色变】,所以我想过系统学习一下,然后再做个笔记这样,加深一下理解。但是真要系统学习,其实还是要花费不少时间的,所以这里也只是简单的,尽可能地覆盖一下,梳理一些我认为比较迫切需

    2024年02月06日
    浏览(10)
  • 由浅入深Netty基础知识NIO网络编程

    由浅入深Netty基础知识NIO网络编程

    阻塞模式下,相关方法都会导致线程暂停 ServerSocketChannel.accept 会在没有连接建立时让线程暂停 SocketChannel.read 会在没有数据可读时让线程暂停 阻塞的表现其实就是线程暂停了,暂停期间不会占用 cpu,但线程相当于闲置 单线程下,阻塞方法之间相互影响,几乎不能正常工作,

    2024年02月05日
    浏览(19)
  • Java网络编程(二)NIO和Netty实现多人聊天功能
  • 从零开始学习Netty - 学习笔记 - NIO基础 - ByteBuffer: 简介和基本操作

    从零开始学习Netty - 学习笔记 - NIO基础 - ByteBuffer: 简介和基本操作

    1.1. Channel Buffer Channel 在Java NIO(New I/O)中,“Channel”(通道)是一个重要的概念,用于 在非阻塞I/O操作中进行数据的传输 。Java NIO提供了一种更为灵活和高效的I/O处理方式,相比于传统的I/O,它具有更好的性能和可扩展性。 常见的Java NIO中的通道类型: FileChannel(文件通道

    2024年02月20日
    浏览(13)
  • 【 基于Netty实现聊天室聊天业务学习】第4节.什么是BIO与NIO

    【 基于Netty实现聊天室聊天业务学习】第4节.什么是BIO与NIO

    IO在读写的时候是阻塞的,无法做其他操作,并发处理能力的非常低,线程之间访问资源通信时候也是非常耗时久,依赖我们的网速,带宽。 我们看一下他的白话原理 我们来看一下这张图那么这张图的话它里面有一个server还有三个客户端那么客户端的话它可以有很多,那么我

    2024年04月26日
    浏览(31)
  • 【网络协议详解】——VLAN技术(学习笔记)

    【网络协议详解】——VLAN技术(学习笔记)

    VLAN技术把用户划分成多组逻辑的网络,组内可以通信,组间不允许通信。 二层转发的单播、组播、广播报文只能在组内转发。 为了实现转发控制,在待转发的以太网帧中添加 VLAN标签 ,然后 设定交换机端口 对该标签和帧的处理方式。 方式包括丢弃帧、转发帧、添加标签、

    2024年02月05日
    浏览(11)
  • 【netty基础四】netty与nio

    【netty基础四】netty与nio

    阻塞I/O在调用InputStream.read()方法时是 阻塞的,它会一直等到数据到来 (或超时)时才会返回; 同样,在调用ServerSocket.accept()方法时,也会一直 阻塞到有客户端连接 才会返回,每个客户端连接成功后,服务端都会启动一个线程去处理该客户端的请求。 阻塞I/O的通信模型示意

    2024年02月10日
    浏览(13)
  • Netty网络编程(五):使用UDP协议

    Netty网络编程(五):使用UDP协议

    今天我将会给大家介绍如何在netty中使用UDP协议。 UDP( User Datagram Protocol ),也叫用户数据报协议。 UDP 的主要功能和亮点并不在于它引入了什么特性,而在于它忽略的那些特性:不保证消息交付,不保证交付顺序,不跟踪连接状态,不需要拥塞控制。 我们来看一下UDP的数据包

    2023年04月27日
    浏览(9)
  • Netty开篇——NIO章下(五)

    Netty开篇——NIO章下(五)

    SelectionKey 表示 Selector 和网络通道的注册关系,共四种(全是常量): Int OP_ACCEPT:有新的网络连接可以接受,值为 16 (1 4) Int OP_CONNECT: 代表连接已经建立,值为 8 (1 3) Int OP_READ:代表读操作,值为 1 (1 0) Int OP_WRITE: 代表写操作,值为 4  (1 2) 相关方法:   ServerSocket

    2024年01月20日
    浏览(9)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包