物联网 基于netty入门与线程模型探秘简述

物联网 基于netty入门与线程模型探秘

简述

理解 Netty 的核心组件(Channel、ChannelHandler、ChannelPipeline),掌握其高性能的 Reactor 线程模型,并通过一个完整的 Echo 示例快速入门

源码

netty-sample-00[https://gitee.com/kcnf-webrtc/iot-sample/tree/master/netty/netty-sample-00\]

Netty 核心组件

组件 作用
Channel 代表一个网络连接(如 NIO SocketChannel),负责读写数据。
ChannelHandler 处理 I/O 事件或拦截数据(如解码、业务逻辑)。可分为入站(Inbound)和出站(Outbound)。
ChannelPipeline 管理 ChannelHandler 的链表,数据流经 Pipeline 依次被各 Handler 处理。
EventLoopGroup 一组 EventLoop,每个 EventLoop 绑定一个线程,负责处理多个 Channel 的 I/O 事件。
Bootstrap / ServerBootstrap 引导类,配置并启动 Netty 客户端/服务器。

Reactor 线程模型

  • 三种典型 Reactor 模型
模型 描述 Netty 对应配置
单线程 一个 Reactor 线程同时处理连接、读、写。 EventLoopGroup 大小为 1。
多线程 一个 Reactor 线程处理连接,多个工作线程处理读写。 bossGroup 大小为 1,workerGroup 大小为 CPU*2。
主从多线程 多线程 Reactor 处理连接,多线程 Reactor 处理读写(用于更高并发)。 bossGroup 大小 >1,workerGroup 大小 >1。
  • Netty 默认实现(主从多线程变种)

BossGroup:监听端口,接收新连接,将 SocketChannel 注册到 WorkerGroup
WorkerGroup:负责已连接的读写 I/O 及业务处理(通常业务 Handler 可再异步执行)

复制代码
// 典型配置
EventLoopGroup bossGroup = new NioEventLoopGroup(1);   // 单线程处理连接
EventLoopGroup workerGroup = new NioEventLoopGroup();  // 默认 CPU 核数 * 2

每个 EventLoop 内部有一个 Selector 和任务队列,一个 EventLoop 服务于多个 Channel,保证同一 Channel 的事件串行执行

添加pom依赖

复制代码
 <dependencies>
        <!-- Netty 核心依赖 -->
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

server 代码

复制代码
package com.jysemel.iot;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
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;

import java.nio.charset.StandardCharsets;

public class EchoServer {
    public static void main(String[] args) throws InterruptedException {
        // 1. 创建线程组:boss 接受连接,worker 处理 I/O
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)      // 指定 NIO 传输
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ChannelPipeline pipeline = ch.pipeline();
                            // 添加编解码器(处理粘包/拆包可用 LengthFieldBasedFrameDecoder,这里简单演示)
                            pipeline.addLast(new StringDecoder(StandardCharsets.UTF_8));
                            pipeline.addLast(new StringEncoder(StandardCharsets.UTF_8));
                            // 添加业务 Handler
                            pipeline.addLast(new EchoServerHandler());
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128)      // 连接队列大小
                    .childOption(ChannelOption.SO_KEEPALIVE, true); // 长连接

            // 2. 绑定端口并启动
            ChannelFuture future = bootstrap.bind(8181).sync();
            System.out.println("Echo 服务器启动,端口 8181");
            future.channel().closeFuture().sync();  // 等待直到服务器关闭
        } finally {
            // 3. 优雅关闭
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

client 代码

复制代码
package com.jysemel.iot;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
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.nio.charset.StandardCharsets;

public class EchoClient {
    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup group = new NioEventLoopGroup();

        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new StringDecoder(StandardCharsets.UTF_8));
                            pipeline.addLast(new StringEncoder(StandardCharsets.UTF_8));
                            pipeline.addLast(new EchoClientHandler());
                        }
                    });

            ChannelFuture future = bootstrap.connect("127.0.0.1", 8181).sync();
            future.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }
}

运行与验证

复制代码
先启动 EchoServer,再启动 EchoClient。
控制台输出:
服务端返回: Hello, Netty!
服务器输出:收到: Hello, Netty!
相关推荐
GentleDevin1 小时前
IntelliJ Idea常用快捷键(Window和Mac对照表)
java·ide·intellij-idea
寺中人1 小时前
基于 5G 物联网的智慧养老全方位安全监测系统
人工智能·物联网·5g·安全·智能家居
Paxon Zhang1 小时前
JavaEE 初阶变强宝典 **线程安全问题,线程状态,锁synchronized**
java·java-ee
阿拉金alakin1 小时前
Java IO 核心类 File、InputStream/OutputStream 实战总结
java·开发语言
有梦想的小何1 小时前
Cursor AI 编程实战(篇二):Rules、速查与 Adapter/App 全文
java·大数据·elasticsearch·搜索引擎·ai·ai编程
噢,我明白了3 小时前
表单的完整 CRUD 练习【极简个人记账本】(含前端后端链接mySQL)
java·前端·数据库·mysql
通往曙光的路上3 小时前
mysql1
java
Tigshop开源商城8 小时前
『物流设置+SEO优化』Tigshop开源商城系统 JAVA v5.8.26 版本更新!
java·开源商城系统·tigshop
Tigshop开源商城10 小时前
『订单税率+收货地址校验国家字段』功能上新|跨境运营更高效,Tigshop开源商城系统 JAVA v5.8.23 版本更新
java·开源商城系统·tigshop