首页 > 其他分享 >Netty 快速入门

Netty 快速入门

时间:2024-06-06 17:45:03浏览次数:17  
标签:Netty 入门 netty io 服务器 import 快速 channel

什么是 Netty

Netty的官网: [https://netty.io/

Netty是一个Java NIO技术的开源异步事件驱动的网络编程框架,用于快速开发可维护的高性能协议服务器和客户端。

往通俗了讲,可以将 Netty 理解为:一个将Java NIO进行了大量封装,并大大降低Java NIO使用难度和上手门槛的网络编程框架。

Netty 的特点

  • 高并发:基于 NIO(Nonblocking IO,非阻塞IO)开发,对比于 BIO(Blocking I/O,阻塞IO),他的并发性能得到了很大提高
  • 传输快:传输依赖于零拷贝特性,尽量减少不必要的内存拷贝,实现了更高效率的传输
  • 封装好:封装了 NIO 操作的很多细节,提供了易于使用调用接口

Netty 的优势

  • 使用简单:封装了 NIO 的很多细节,使用更简单
  • 功能强大:预置了多种编解码功能,支持多种主流协议
  • 扩展性强:可以通过 ChannelHandler 对通信框架进行灵活地扩展
  • 性能优异:通过与其他业界主流的 NIO 框架对比,Netty 的综合性能最优
  • 运行稳定:Netty 修复了已经发现的所有 NIO 的 bug,让开发人员可以专注于业务本身
  • 社区活跃:Netty 是活跃的开源项目,版本迭代周期短,bug 修复速度快

Netty 能做什么

  1. 分布式系统中的RPC通信
    • 在分布式系统中,各个节点之间需要进行远程服务调用,Netty 作为高性能的通信框架,经常被用作 RPC 框架的基础通信组件。
    • 例如,阿里巴巴的分布式服务框架 Dubbo 使用 Netty 作为其默认的通信框架。
  2. 即时通讯(IM)系统
    • 即时通讯系统需要处理大量的并发连接和低延迟的消息传输,Netty 的高并发和低延迟特性使其成为构建这类系统的理想选择。
  3. 消息推送系统
    • 消息推送系统需要向多个客户端实时推送消息,Netty 能够高效地处理这些推送操作。
  4. 物联网(IoT)
    • 物联网应用中,大量的设备需要与服务器进行通信,Netty 可以作为设备和服务器之间通信的基础框架。
  5. 游戏行业
    • 在游戏行业中,Netty 可用于开发高性能的游戏服务器,处理游戏内的数据通信。
  6. 大数据分布式计算
    • 在大数据领域,Netty 可用于构建分布式计算框架,如 Apache Spark 和 Apache Storm,这些框架需要高效地处理大量数据的传输。
  7. Web应用
    • Netty 可用于构建高性能的Web服务器和代理服务器,支持 HTTP、WebSocket 等协议。
  8. 微服务架构
    • 在微服务架构中,服务之间的通信需要快速且可靠,Netty 可以作为服务间通信的底层框架。

Netty 的高性能、高可靠性、易用性和可扩展性使其成为互联网应用开发中的首选网络编程框架之一。

核心概念

Channel(通道)

Channel (通道)是 Netty 中的网络操作抽象,代表一个网络连接

Netty 提供了多种类型的 Channel,例如 NioSocketChannel(用于客户端 TCP 连接)和 NioServerSocketChannel(用于服务器端 TCP 监听)。

ChannelHandler(通道处理器)

ChannelHandler (通道处理器)是 Netty 中用于处理网络事件的接口(即接收通道消息)

常见的 ChannelHandler 包括 SimpleChannelInboundHandler、ChannelInboundHandlerAdapter 等。

ChannelPipeline(通道流水线)

ChannelPipeline(通道流水线) 是一个处理器链,包含了一系列的 ChannelHandler(通道处理器),数据和事件在 ChannelPipeline 中按照顺序被多个 ChannelHandler 处理

ChannelInitializer(通道初始化器)

ChannelInitializer 用于初始化新创建的 Channel,通常在其中设置 ChannelPipeline。它允许动态地为 Channel 设置处理器,通常在服务器端使用。

Bootstrap(引导启动辅助类)

Bootstrap 是 Netty 的客户端启动辅助类,用于配置客户端 Channel 的参数并启动客户端。服务器端也有一个对应的 ServerBootstrap 类。

Future 和 ChannelFuture

Future 表示一个异步操作的结果,可以在操作完成时获取结果或处理通知。ChannelFuture 是 Future 的一个子类型,专门用于表示 Channel 的异步操作。

Netty 编程案例

1. 创建 Maven 工程

2. 引入 Netty Maven 依赖
<!-- netty -->
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.87.Final</version>
</dependency>
3. 创建服务器端启动类
package com.binge.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class NettyServer {
    //服务器监听端口
    private int port;

    //构造方法
    public NettyServer(int port) {
        this.port = port;
    }

    public void run() throws InterruptedException {
        // 创建线程池,用于处理服务器的接受连接请求
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        // 创建线程池,用于处理已经接受的连接,包括读取数据、处理数据和发送数据
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            // 创建服务器启动器
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup) //设置线程池
                .channel(NioServerSocketChannel.class) //实例化一个监听通道(Channel)
                .childHandler(new ChannelInitializer() { //初始化连接通道配置
                    @Override
                    protected void initChannel(Channel channel) throws Exception {
                        // 设置自定义通道消息处理器
                        channel.pipeline().addLast(new StringDecoder(), new StringEncoder(), new ServerChannelHandler());
                    }
                })
                .option(ChannelOption.SO_BACKLOG, 128) //设置服务器可以挂起未处理的连接的数量
                .childOption(ChannelOption.SO_KEEPALIVE, true); // 设置 TCP 的保活机制,用于检测死连接

            // 绑定服务器监听端口, 同步等待成功
            ChannelFuture future = bootstrap.bind(port).sync();
            //打印服务器启动信息
            System.out.println("Server started on port " + port);

            // 开启通道监监听器,监听通道是否关闭
            future.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        // 创建服务器实例
        NettyServer server = new NettyServer(8888);
        try {
            server.run(); // 启动服务器
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
4. 创建服务器端通道处理器
package com.binge.server;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

public class ServerChannelHandler extends SimpleChannelInboundHandler {
    /**
     * 客户端连接成功
     * @param ctx 通道上下文
     */
    public void channelActive(ChannelHandlerContext ctx)  {
        System.out.println("连接客户端成功..");
    }

    /**
     * 处理接收到的消息
     * @param ctx 通道上下文
     * @param message 消息对象
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object o) {
        System.out.println("Server received: " + o.toString());
        ctx.writeAndFlush("Hello,client!");
    }

    /**
     * 处理I/O事件的异常
     * @param ctx 通道上下文
     * @param cause 异常原因
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        if (cause instanceof java.net.SocketException) {
            System.out.println("客户端连接已断开..");
        } else {
            System.err.println("服务器捕获到异常,但将继续运行... ");
            cause.printStackTrace();
        }
        // 不要调用ctx.close(),这样连接就不会关闭
    }
}
5. 创建客户端启动类
package com.binge.client;


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.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class NettyClient {
    //服务器主机地址
    private String host;
    //服务器监听端口
    private int port;

    //构造方法
    public NettyClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void run() throws InterruptedException {
        //创建线程池,处理客户端请求连接和接受服务器消息
        EventLoopGroup group = new NioEventLoopGroup();

        try {
            // 创建客户端启动器
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group) //设置线程池
                    .channel(NioSocketChannel.class) //实例化一个TCP连接通道
                    .handler(new ChannelInitializer() { //初始化连接通道配置
                        @Override
                        protected void initChannel(Channel channel) {
                            //设置自定义通道消息处理器
                            channel.pipeline().addLast(new StringDecoder(), new StringEncoder(), new ClientChannelHandler());
                        }
                    });

            // 连接服务器并等待连接成功
            ChannelFuture future = bootstrap.connect(host, port).sync();
            //打印连接服务器成功信息
            System.out.println("Connected to server: " + host + ":" + port);

            //发送消息给服务器
            future.channel().writeAndFlush("Hello, server!");

            //等待通道关闭
            future.channel().close();

            //开启通道监监听器,监听通道是否关闭
            future.channel().closeFuture().sync();
        } finally {
            //优雅关闭线程池
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        // 创建客户端实例
        NettyClient client = new NettyClient("localhost", 8888);
        try {
            client.run(); // 启动客户端
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
6. 创建客户端通道处理器
package com.binge.client;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

public class ClientChannelHandler extends SimpleChannelInboundHandler {
    /**
     * 服务器连接成功
     * @param ctx 通道上下文
     */
    public void channelActive(ChannelHandlerContext ctx)  {
        System.out.println("连接服务器成功..");
    }

    /**
     * 读取通道接收的消息
     * @param ctx 通道上下文
     * @param message 接收的消息
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object message)  {
        System.out.println(message);
    }
}
7. 工程目录结构

image-20240606172644922

8. 测试

运行 NettyServer 启动服务器(监听端口)

Server started on port 8888

运行 NettyClient 启动客户端

连接服务器成功..
Connected to server: localhost:8888

这是服务器端显示如下:

Server started on port 8888
连接客户端成功..
Server received: Hello, server!

测试成功:)

标签:Netty,入门,netty,io,服务器,import,快速,channel
From: https://www.cnblogs.com/binbingg/p/18235704

相关文章

  • git快速删除未被跟踪的文件或文件夹
    如果你想快速删除所有未追踪的文件(即未被Git版本控制的文件),你可以使用以下命令:######gitclean-f这个命令会删除所有未追踪的文件。如果你还想删除未追踪的目录,可以使用-d选项:######gitclean-fd如果你还想删除由.gitignore忽略的文件,可以使用-x选项:######gitcl......
  • 使用 jar 方式,快速运行 minecraft-service
    在Linux系统中,要将命令封装成.service文件,需要创建一个systemd服务单元文件。下面是创建一个名为minecraft.service​的示例,它会运行你提供的java​命令来启动MinecraftSpigot服务器。打开终端。使用文本编辑器创建一个新的.service文件。你可以使用nano​或者vi​。例如:s......
  • 冒泡排序、插入排序、快速排序
    三种排序:冒泡排序、插入排序、快速排序规则:冒泡排序:每一轮循环后,最大的一个数被交换到末尾,因此,下一轮循环就可以“刨除”最后的数,每一轮循环都比上一轮循环的结束位置靠前一位。插入排序:将待排序数组分为已排序和未排序两部分,初始已排序部分只包含第一个元素。然后,从第二个元素......
  • FastAPI-3:快速入门
    3快速入门第二章是python基础,故不做介绍。FastAPI是一个现代、快速(高性能)的网络框架,用于使用基于标准Python类型提示的Python3.6+构建API。FastAPI的创建者是SebastiánRamírez。FastAPI由SebastiánRamírez于2018年发布。与大多数PythonWeb框架相比,它在很多方面都更......
  • Android视频开发入门: VideoView、MediaPlayer、 FFmpeg、exoplayer...
    现在,视频功能是越来越普遍的需求。本文将提供一个关于Android视频开发的入门指南,帮助读者快速掌握视频播放、录制和处理等基本功能。1、概述在Android平台上,视频开发主要涉及以下几个方面:视频播放与控制视频录制与处理视频编解码与格式转换视频流媒体与直播接下来,我......
  • 001__C语言程序入门
    一、第一个程序:helloworld配置部署好vsCode之后,就可以直接在上面写代码了,新建一个新的C程序文件,向屏幕输出一串字符“HelloWorld!”下面,从整体上来分析一下这个最简单的C语言程序,将这个最简程序的各个部分剖析清楚,明白我们写下的每一个字符的具体含义。二、C语言的基本结......
  • 巧用docker+jmeter快速实现分布式百万级并发
    分享背景碰到的问题:一个JMeter实例可能无法产生足够的负载来对你的应用程序进行压力测试~解决办法:1、修改jmeter配置文件里的内存堆2、引入jmeter分布式压测带来的问题:如果我们要做分布式负载测试–我们需要1个主机和N个从机来产生巨大的负载。每台JMeter从机都需要......
  • 探索Adobe XD:高效UI设计软件的中文入门教程
    在这个数字化世界里,创意设计不仅是为了吸引观众的注意,也是用户体验的核心部分。强大的设计工具可以帮助设计师创造出明亮的视觉效果,从而提高用户体验。一、AdobeXD是什么?AdobeXD是一家知名软件公司AdobeSystems用户体验和用户界面设计软件的制作和发布。软件可以帮助设......
  • 快速排序——AcWing785.快速排序
    AcWing785.快速排序题目描述785.快速排序-AcWing题库运行代码#include<iostream>#include<algorithm>usingnamespacestd;constintN=1e6+6;intq[N];voidquick_sort(intq[],intl,intr){if(l>=r)return;intm=l+r>>1;//>......
  • SQL—数据库查询语言,全面详解演示,入门进阶必会
    文章目录一、基础二、创建表三、修改表四、插入五、更新六、删除七、查询DISTINCTLIMIT八、排序九、过滤十、通配符十一、计算字段十二、函数汇总文本处理日期和时间处理数值处理十三、分组十四、子查询十五、连接内连接自连接自然连接外连接十六、组合查询十七、视图......