首页 > 其他分享 >Netty框架

Netty框架

时间:2024-08-13 08:57:28浏览次数:9  
标签:Netty 框架 netty io 服务器 import channel

Netty

什么是 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 中的网络操作抽象,代表一个网络连接

image-20240606170022814

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

ChannelHandler(通道处理器)

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

image-20240606170121280

常见的 ChannelHandler 包括 SimpleChannelInboundHandler、ChannelInboundHandlerAdapter 等。

ChannelPipeline(通道流水线)

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

image-20240606170203479

ChannelInitializer(通道初始化器)

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

Bootstrap(引导启动辅助类)

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

Future 和 ChannelFuture

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

Netty 编程案例

1. 创建 Maven 工程

image-20240606170355319

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/ZWJ7671277/p/18356138

相关文章

  • 【鸿蒙学习】HarmonyOS应用开发者基础 - 应用程序框架基础
    从第一节的学习到现在,学习的人数越来越少,要相信,坚持学习下去的将会获得相应的收获。加油少年!!!一、应用框架基础1.应用  用户应用程序泛指运行在设备的操作系统之上,为用户提供特定服务的程序,简称“应用”。一个应用所对应的软件包文件,称为“应用程序包”。2.Module......
  • 使用 langchain 框架,构建一个简单的 LLM 应用程序
    介绍使用langchain框架,构建一个简单的LLM应用程序本文中出现的每段代码都是可以完整执行的注意大语言模型和各类框架迭代飞快,再看本文时,部分代码可能已经过时了本文所用到的python包版本dashscope1.20.3langchain0.2.12langchain-community0.2.11......
  • C ++ 也可以搭建Web?高性能的 C++ Web 开发框架 CPPCMS + MySQL 实现快速入门案例
    什么是CPPCMS?CppCMS是一个高性能的C++Web开发框架,专为构建快速、动态的网页应用而设计,特别适合高并发和低延迟的场景。其设计理念类似于Python的Django或RubyonRails,但针对C++提供了更细粒度的控制和更高效的性能。主要特点和优点1.高性能与并发处理​Cp......
  • Java入门基础16:集合框架1(Collection集合体系、List、Set)
    集合体系结构Collection是单列集合的祖宗,它规定的方法(功能)是全部单列集合都会继承的。collection集合体系Collection的常用方法packagecom.itchinajie.d1_collection;importjava.util.ArrayList;importjava.util.HashSet;/**目标:认识Collection体系的特点。*......
  • 基于flask+vue框架的高校毕业生在线招聘系统[开题+论文+程序]-计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着高等教育的普及与就业市场的日益竞争激烈,高校毕业生面临着前所未有的求职挑战。传统招聘方式受限于时间、地域等因素,难以高效匹配企业......
  • 基于flask+vue框架的畅饮水站业务管理系统[开题+论文+程序]-计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着现代生活节奏的加快与健康意识的提升,便捷、高质量的饮用水服务成为了人们日常生活中不可或缺的一部分。畅饮水站作为社区及办公区域的......
  • Scrapy框架进阶攻略:代理设置、请求优化及链家网实战项目全解析
    scrapy框架加代理付费代理IP池middlewares.py#代理IP池classProxyMiddleware(object):proxypool_url='http://127.0.0.1:5555/random'logger=logging.getLogger('middlewares.proxy')asyncdefprocess_request(self,request,spider):......
  • 科普文:Java基础系列之【你必须知道的框架基础-代理详解】
     概叙科普文:Java基础系列之【你必须知道的框架基础-反射/代理】-CSDN博客前面我们详细讲解了反射,反射作用在类加载后创建对象这个期间,再来看看代理。反射是基础,通过反射获取对象及其属性和操作;代理则可以将反射出来的类包装成目标类,然后构建一个代理类,通过代理类来操控目......
  • 科普文:Java基础系列之【你必须知道的框架基础-反射/代理】
    前言科普文:Java基础系列之【Java动态代理的应用场景和基本原理】-CSDN博客科普文:Java基础系列之【字节码增强技术探索】-CSDN博客科普文:Java基础系列之【字节码应用案例Fastjson原理和实操说明】-CSDN博客科普文:Java基础系列之【JVM字节码操作ASM框架概叙】-CSDN博客......
  • 基于flask+vue框架的基于Web民宿管理系统的设计与实现[开题+论文+程序]-计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着旅游业的蓬勃发展,民宿作为一种新兴的住宿方式,凭借其独特的文化体验、个性化的服务以及灵活的价格策略,逐渐受到广大旅行者的青睐。然而......