Netty框架介绍及实战

article/2025/9/21 10:30:51

Netty框架模型

NIO 的类库和API繁杂,使用麻烦:需要熟练掌握Selector、ServerSocket、ChannelSocketChannel、 ByteBuffer等。开发工作量和难度都非常大: 例如客户端面临断连重连、 网络闪断、心跳处理、半包读写、 网络拥塞和异常流的处理等等。
Netty 对 JDK 自带的 NIO 的 API 进行了良好的封装,解决了上述问题。且Netty拥有高性能、 吞吐量更高,延迟更低,减少资源消耗,最小化不必要的内存复制等优点。
Netty 现在都在用的是4.x,5.x版本已经废弃,Netty 4.x 需要JDK 6以上版本支持。
Netty的使用场景:
1)互联网行业:在分布式系统中,各个节点之间需要远程服务调用,高性能的 RPC 框架必不可少,Netty 作为异步高性能的通信框架,往往作为基础通信组件被这些 RPC 框架使用。典型的应用有:阿里分布式服务框架 Dubbo 的 RPC 框架使用 Dubbo 协议进行节点间通信,Dubbo 协议默认使用Netty 作为基础通信组件,用于实现。各进程节点之间的内部通信。Rocketmq底层也是用的Netty作为基础通信组件。
2)游戏行业:无论是手游服务端还是大型的网络游戏,Java 语言得到了越来越广泛的应用。Netty作为高性能的基础通信组件,它本身提供了 TCP/UDP 和 HTTP 协议栈。
3)大数据领域:经典的 Hadoop 的高性能通信和序列化组件 Avro 的 RPC 框架,默认采用 Netty进行跨界点通信,它的 Netty Service 基于 Netty 框架二次封装实现。

Netty线程模型

Netty线程模型
模型解释

  1. Netty抽象2个线程池,Boss Group和Work Group。Boss Group用于处理Accept事件,Work Group 用于处理 Read 和Write事件。
  2. Boss Group和Work Group都属于EventLoopGroup。
  3. NioEventLoopGroup 相当于一个事件循环线程组, 这个组中含有多个事件循环线程 , 每一个事件循环线程是NioEventLoop 。
  4. 每一个NioEventLoop都会有一个Selector用于监听绑定的Chanel
  5. Boss NioEventLoop的处理流程如下:
    a. 进行accpet操作,返回SocketChanel
    b.将该Socketchanel注册到某个work NioEventLoop的seletor上
    c.处理任务队列的任务 , 即runAllTasks
  6. Work NioEventLoop的处理流程如下:
    a. 轮询所有注册到该Loop Seletor上的Socketchanel的Read/Write事件
    b.处理Read/Write事件
    c.runAllTasks处理任务队列TaskQueue的任务 ,一些耗时的业务处理一般可以放入

Netty 实战

写一个聊天室程序,服务端具备上线检测,群发聊天内容等。Netty极大的简化了NIO编程,开发者更多的是编写ChannelHandle逻辑做业务处理
服务端代码 Server

 package com.qinghaihu.chat;import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;/**
* @ClassName ChatServer
* @Description TODO
* @Author:Zhang Lianzhong
* @Date 2020/11/22 10:13 下午
* @Version 1.0
**/
public class ChatServer {public void openServer(int port){ServerBootstrap bootstrap = new ServerBootstrap();EventLoopGroup boss = new NioEventLoopGroup(1);  //create boss group, threadpool size is 1EventLoopGroup work = new NioEventLoopGroup(5); //create work group, threadpool size is 5bootstrap.group(boss,work);   //组合netty组件//配置handle组件bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast("encoder",new StringEncoder());ch.pipeline().addLast("decoder",new StringDecoder());ch.pipeline().addLast(new ServerChanelHandle());}});bootstrap.channel(NioServerSocketChannel.class);try{ChannelFuture channel = bootstrap.bind(port).sync();System.out.println(("服务端已启动,绑定端口:" + port));channel.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();}finally {boss.shutdownGracefully();work.shutdownGracefully();}}public static void main(String[] args){ChatServer server = new ChatServer();server.openServer(8090);}}

服务端ChannelHandle

package com.qinghaihu.chat;import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;/*** @ClassName ServerChanelHandle* @Description TODO* @Author:Zhang Lianzhong* @Date 2020/11/22 10:21 下午* @Version 1.0**/
public class ServerChanelHandle extends SimpleChannelInboundHandler {//必须定义为类成员变量。每个客户端连接时,都会new ChatServerHandler。static保证数据共享public static ChannelGroup cg = new  DefaultChannelGroup(GlobalEventExecutor.INSTANCE);@Overridepublic void handlerAdded(ChannelHandlerContext ctx) throws Exception {Channel ch = ctx.channel();for(Channel chanel: cg){chanel.writeAndFlush(ch.remoteAddress()+"进来啦!");}cg.add(ch);}/*** 上线处理* @param ctx* @throws Exception*/@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {Channel channel = ctx.channel();for(Channel ch: cg){ch.writeAndFlush(channel.remoteAddress()+"上线啦");}}@Overrideprotected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {Channel channel = ctx.channel();for(Channel ch: cg){if(channel ==ch){ch.writeAndFlush("我说"+msg);}else {ch.writeAndFlush(channel.remoteAddress()+"说:"+msg);}}}@Overridepublic void handlerRemoved(ChannelHandlerContext ctx) throws Exception {Channel channel = ctx.channel();cg.remove(channel);}@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {Channel channel = ctx.channel();String customerAddress = channel.remoteAddress().toString();for(Channel ch:cg){ch.writeAndFlush("客户端" + customerAddress + "下线了!");}}}

客户端Client

package com.qinghaihu.chat;import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;import java.util.Scanner;/*** @ClassName ChatClient* @Description TODO* @Author:Zhang Lianzhong* @Date 2020/11/22 10:54 下午* @Version 1.0**/
public class ChatClient implements Runnable{private String serverIP;private int port;public ChatClient(String serverIp,int port ){this.serverIP = serverIp;this.port = port;}@Overridepublic void run() {Bootstrap bootstrap = new Bootstrap();EventLoopGroup work = new NioEventLoopGroup(1);bootstrap.group(work);bootstrap.handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast("encode",new StringEncoder());ch.pipeline().addLast("decode",new StringDecoder());ch.pipeline().addLast(new ClientChanelHandle());}});bootstrap.channel(NioSocketChannel.class);ChannelFuture channelFuture = bootstrap.connect(serverIP,port);Channel channel = channelFuture.channel();Scanner scanner = new Scanner(System.in);while(scanner.hasNext()){String sendMsg = scanner.nextLine();channel.writeAndFlush(sendMsg);}work.shutdownGracefully();}public static void main(String[] args){new Thread(new ChatClient("127.0.0.1",8090)).start();}
}

客户端ChannelHandle

package com.qinghaihu.chat;import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;/*** @ClassName ClientChanelHandle* @Description TODO* @Author:Zhang Lianzhong* @Date 2020/11/22 11:08 下午* @Version 1.0**/
public class ClientChanelHandle extends SimpleChannelInboundHandler {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {System.out.println(msg);}
}

运行效果

服务端运行情况
ClientA
ClientB


http://chatgpt.dhexx.cn/article/1BUnlAtu.shtml

相关文章

Netty框架使用

前言 首先在使用Netty框架的时候需要了解Netty是一个什么东西。 Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具&#xff0c;用以快速开发高性能、高可靠性的网络服务器和客户端程序。也就是说&#xff0c;Netty 是一个基于NIO的…

Netty框架简介

Netty框架介绍 早已听说Netty牛逼了&#xff0c;最近有时间学习学习&#xff0c;官网地址&#xff1a;https://netty.io/&#xff0c;Java系的多种服务器/大数据框架&#xff0c;都离不开Netty做出的贡献&#xff0c;例如dubbo&#xff0c;elasticsearch等等&#xff0c;采用的…

netty框架android,隻需五步,即可基於Netty框架實現Android內網推送功能。

隻需五步,即可基於Netty框架實現Android內網推送功能。 一、先引入依賴,客戶端和服務端用的都是同一個依賴netty-all。 Android Studio中Gradle配置: compile io.netty:netty-all:5.0.0.Alpha2 IDEA中Maven配置: io.netty netty-all 5.0.0.Alpha2 二、創建消息模塊包。 目前…

Netty框架之Selector轮询器

Selector的原理详解 1.传统多线程网络通信的服务器设计2.线程池版网络通信的服务器设计Selector版网络通信的服务器设计 说到Selector的作用&#xff0c;我们不得不引入 多线程网络通信的设计 1.传统多线程网络通信的服务器设计 服务器每建立一个客户端连接Socket&#xff0c;…

netty框架学习及springboot整合集成

netty框架学习及springboot整合集成 1. Netty基本概念2. Netty框架2.1 Netty框架结构2.1 Netty NIO2.2 Reactor线程模型 3. Springboot集成netty3.1 引入jar包依赖3.2 服务端3.3 客户端 4. 参考资料 从很久以前就接触到netty&#xff0c;也在几个项目中使用netty进行网络通讯对…

Netty框架介绍

Netty框架介绍 一、netty&#xff08;通讯框架&#xff09;介紹 1、什么是netty Netty是一个基于Java NIO类库的异步通讯框架&#xff0c;他的架构特点是&#xff1a;异步非阻塞、基于事件驱动、高性能、高可靠和高定制行。 2、netty应用场景 rpc远程调用框架dubbo底层就是通…

Netty框架简述

Netty是什么&#xff1f; Netty 是一个广泛使用的 Java 网络编程框架&#xff0c;Netty提供异步的、事件驱动的网络应用程序框架和工具&#xff0c;用以快速开发高性能、高可靠性的网络服务器和客户端程序。Netty 的内部实现时很复杂的&#xff0c;但是 Netty 提供了简单易用的…

Netty框架的基本使用

Netty概述 为什么使用Netty 前面了解过的NIO模型&#xff0c;它有可靠性高、吞吐量高的优点&#xff0c;但也存在编程复杂的问题&#xff0c;我们要掌握大量的API&#xff0c;如&#xff1a;各种Channel、Buffer、Selector&#xff0c;还要编程处理特殊情况&#xff0c;如&am…

初识Netty框架

总体概述 Netty作为一款网络通信框架&#xff0c;底层封装了NIO。我们在使用Netty时&#xff0c;无需再关注NIO细节。下图为Netty处理流程图&#xff1a; 应用程序中使用Netty作为网络通信框架后&#xff0c;会形成一条PipeLine链&#xff0c;PipeLine链上有一个一个的事件处…

【java网络编程】netty框架

一、简介 netty是一个高性能、异步事件驱动的NIO框架&#xff0c;它基于Java Nio提供的API实现&#xff0c;提供了对TCP、UDP和文件传输的支持。 二、Reactor模型 Reactor是一种并发处理客户端请求响应的事件驱动模型。服务端在接收到客户端请求后采用多路复用策略&#xff0…

Netty学习二:Netty整体框架

一、Netty的整体结构和源码结构 1. Core层 提供底层网络通信的通用抽象和实现&#xff0c;包括可扩展的事件模型、通用的通信API和支持零拷贝的ByteBuf等。 common模块是Netty的核心基础包&#xff0c;提供丰富的工具类&#xff0c;其他模块都需要依赖该模块。常用的包括&…

Netty框架

概述 Netty 是由 JBOSS 提供的一个 Java 开源框架。Netty 提供异步的、基于事件驱动的网络应用程序框架&#xff0c;用以快速开发高性能、高可靠性的网络 IO 程序。 Netty 是一个基于 NIO 的网络编程框架&#xff0c;使用 Netty 可以帮助你快速、简单的开发出一个网络应用&…

Netty框架基本介绍

NIO 1.概述&#xff1a;NIO全称java non-blocking IO &#xff0c;是指JDK1.4开始&#xff0c;java提供了一系列改进的输入/输出的新特性&#xff0c;被统称为NIO(即New IO )。新增了许多用于处理输入输出的类&#xff0c;这些类都被放在java.nio包及子包下&#xff0c;并且对j…

超详细Netty入门,看这篇就够了!

思维导图 前言 本文主要讲述Netty框架的一些特性以及重要组件&#xff0c;希望看完之后能对Netty框架有一个比较直观的感受&#xff0c;希望能帮助读者快速入门Netty&#xff0c;减少一些弯路。 一、Netty概述 官方的介绍&#xff1a; Netty is an asynchronous event-drive…

SPI通信协议详解(一)

SPI是一个同步的数据总线&#xff0c;也就是说它是用单独的数据线和一个单独的时钟信号来保证发送端和接收端的完美同步。 时钟是一个振荡信号&#xff0c;它告诉接收端在确切的时机对数据线上的信号进行采样。 产生时钟的一侧称为主机&#xff0c;另一侧称为从机。总是只有一个…

SPI协议的介绍

学习内容&#xff1a; 学习SPI协议记录 学习清单&#xff1a; 提示&#xff1a;这里可以添加要学的内容 例如&#xff1a; SPI协议的介绍三根线还是四根线两个概念四种模式SPI时序图SPI优缺点SPI和IIC的对比 学习详细内容&#xff1a; 1.SPI协议的介绍 SPI是串口外设接口…

SPI 通信协议

文章目录 【 1. 概述 】【 2. 原理 】1. 全双工特征下的传输特点2. 二线式、三线式的SPI3. SPI 模式CPOL(Clock Polarity)&#xff0c;时钟极性CPHA (Clock Phase)&#xff0c;时钟相位通信模式_时序 4. 通信过程5. 底层数据传输演示 【 3. SPI底层驱动 】 【 1. 概述 】 SPI …

SPI通信协议基础

文章目录 引言正文串行与并行通信SPI通信简介SPI如何运作&#xff1f;时钟从机选择多个从机MOSI和MISOSPI数据传输步骤 SPI的优缺点优点缺点 好文推荐参考 引言 当您将微控制器连接到传感器&#xff0c;显示器或其他模块时&#xff0c;您是否考虑过这两种设备如何相互通信&…

SPI、I2C、UART(即串口)三种串行总线详解

以下内容均来源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 参考博客 几个串口协议学习整理 UART IIC SPI_mainn的博客-CSDN博客 SPI、I2C、UART三种串行总线的原理、区别及应用_嵌入式Linux,的博客-CSDN博客 RS-232 和 UART 之间有什么区别&#xff1f; - 知乎…

uart、spi、i2c通信协议详解

文章目录 前言一、uart&#xff08;串口&#xff09;介绍使用rs232、rs485拓展 二、I2C介绍1.宏观流程2.时序上3.典型操作 三、spi&#xff08;串行外设接口&#xff09;介绍使用1.宏观上2.微观上 总结1.i2c和spi对比 前言 之前对于各种通信协议学习了就忘&#xff0c;学了就忘…