Netty学习

一、Netty有必要学吗

Netty是一个基于NIO的客户端/服务端框架,用于开发网络应用程序。相对于传统的Java I/O,Netty提供了更好的性能、更好的可维护性和更好的可扩展性。学习Netty可以让我们更加深入地理解网络编程,还能够在工作中运用到这个高性能的框架。

与其他的网络编程框架相比,Netty在处理高并发、高吞吐量以及低延迟等方面有很大的优势。如果我们需要开发高性能的网络应用,并且在实际应用中跑得更快、更稳定,那么学习Netty就是非常有必要的。

最后,在如今互联网高速发展的背景下,网络安全一直是人们关注的焦点。Netty提供了基于SSL的安全传输,可以保证数据在传输过程中的安全性。所以,即使我们不经常开发网络应用程序,学习Netty也有一定的必要性。

二、Netty客户端维护多个连接

在实际应用中,我们可能需要维护多个网络连接,例如连接多个服务器进行数据交互。当使用传统Java I/O时,每个网络连接都需要一个线程来处理,如果连接数非常多,那么就会出现线程数过多的问题,导致系统崩溃。但是在Netty中,我们可以使用连接池技术来解决这个问题,从而提高应用程序的性能和可靠性。

(一)连接池实现方式举例


public class NettyConnectionPool {
  private static final String HOST = "127.0.0.1";
  private static final int PORT = 8080;
  
  private static EventLoopGroup group = new NioEventLoopGroup();
  private static Bootstrap bootstrap = new Bootstrap();
  private static final int MAX_POOL_SIZE = 10;
  private static final Queue<Channel> pool = new ConcurrentLinkedQueue<Channel>();
  
  // 初始化连接池
  static {
       bootstrap.group(group);
    bootstrap.channel(NioSocketChannel.class);
    bootstrap.option(ChannelOption.TCP_NODELAY, true);
    bootstrap.handler(new ChannelInitializer<SocketChannel>() {
      @Override
      public void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new NettyClientHandler());
      }
    });
    while (pool.size() < MAX_POOL_SIZE) {
       pool.add(bootstrap.connect(HOST, PORT).channel());
     }
  }
  
  // 获取连接
  public static Channel getConnection() {
    if (pool.isEmpty()) {
       return null;
    } else {
       return pool.poll();
    }
  }
  
  // 释放连接
  public static void releaseConnection(Channel channel) {
    if (channel != null && pool.size() < MAX_POOL_SIZE) {
       pool.add(channel);
    } else {
       channel.close();
    }
  }
}

(二)连接池使用方式

使用连接池技术,我们可以更好地管理网络连接,提高应用程序的性能和可靠性。


public class NettyClient {
  private static final int MAX_RETRY = 3;
  
  // 启动连接
  public static void start() {
     Bootstrap bootstrap = new Bootstrap();
     EventLoopGroup group = new NioEventLoopGroup();
     bootstrap.group(group);
     bootstrap.channel(NioSocketChannel.class);
     bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
     bootstrap.option(ChannelOption.TCP_NODELAY, true);
     bootstrap.handler(new ChannelInitializer<SocketChannel>() {
         @Override
         protected void initChannel(SocketChannel ch) throws Exception {
             ChannelPipeline pipeline = ch.pipeline();
             pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
             pipeline.addLast(new LengthFieldPrepender(4));
             pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
             pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
             pipeline.addLast(new NettyClientHandler());
        }
     });
     ChannelFuture future = connect(bootstrap, "127.0.0.1", 8080, MAX_RETRY);
     future.addListener(new ChannelFutureListener() {
         @Override
      public void operationComplete(ChannelFuture future) throws Exception {
        if (future.isSuccess()) {
          Channel channel = future.channel();
          NettyConnectionPool.releaseConnection(channel);
        } else {
          System.out.println("连接失败!");
        }
   }
 });
 }
  
  // 连接或重连服务器
  private static ChannelFuture connect(Bootstrap bootstrap, String host, int port, int retry) {
     return bootstrap.connect(host, port).addListener(new ChannelFutureListener() {
         @Override
         public void operationComplete(ChannelFuture future) throws Exception {
             if (future.isSuccess()) {
                 System.out.println("连接成功!");
             } else if (retry == 0) {
                 System.out.println("重试次数已用完,放弃连接!");
             } else {
                 int order = (MAX_RETRY - retry) + 1;
                 int delay = 1 <
                         connect(bootstrap, host, port, retry - 1), delay, TimeUnit.SECONDS);
             }
         }
     });
 }
}

三、Netty的对象池技术

Netty的对象池技术是指在应用程序中,为了防止频繁地创建对象而引入的一种技术方案。由于频繁创建对象会导致申请和销毁内存空间的开销,从而影响应用程序的性能。因此,使用对象池技术可以大大地提高应用程序的性能。

(一)对象池实现方式举例


public class NettyObjectPool {
  private static final int DEFAULT_POOL_SIZE = 10;
  private final int maxPoolSize;
  private final PoolObjectFactory factory;
  private final Deque pool;
  
  // 实现 PoolObjectFactory 接口
  public interface PoolObjectFactory<T> {
    T createObject();
     void destroyObject(T obj);
  }
  
  // 初始化对象池
  public NettyObjectPool(PoolObjectFactory factory) {
     this(DEFAULT_POOL_SIZE, factory);
  }
  
  public NettyObjectPool(int maxPoolSize, PoolObjectFactory factory) {
     this.maxPoolSize = maxPoolSize;
     this.factory = factory;
     this.pool = new ConcurrentLinkedDeque();
    for (int i = 0; i < maxPoolSize; i++) {
      pool.add(factory.createObject());
    }
  }
  
  // 获取对象
  public Object borrowObject() {
    if (pool.isEmpty()) {
       return null;
    } else {
       return pool.pop();
    }
  }
  
  // 归还对象
  public void returnObject(Object obj) {
    if (pool.size() >= maxPoolSize) {
       factory.destroyObject(obj);
    } else {
       pool.add(obj);
    }
  }
}

(二)对象池使用方式

使用对象池技术,我们可以更好地管理内存,减少内存分配和销毁的开销,提高应用程序的性能。


public class NettyClient {
  private static final NettyObjectPool<NettyClientHandler> handlerPool =
    new NettyObjectPool(MAX_POOL_SIZE, new NettyObjectPool.PoolObjectFactory<NettyClientHandler>() {
      @Override
      public NettyClientHandler createObject() {
        return new NettyClientHandler();
      }
      @Override
      public void destroyObject(NettyClientHandler handler) {
        handler = null;
      }
    });
  
  // 启动连接
  public static void start() {
     Bootstrap bootstrap = new Bootstrap();
     EventLoopGroup group = new NioEventLoopGroup();
     bootstrap.group(group);
     bootstrap.channel(NioSocketChannel.class);
     bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
     bootstrap.option(ChannelOption.TCP_NODELAY, true);
     bootstrap.handler(new ChannelInitializer<SocketChannel>() {
          @Override
          protected void initChannel(SocketChannel ch) throws Exception {
             ChannelPipeline pipeline = ch.pipeline();
             pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
             pipeline.addLast(new LengthFieldPrepender(4));
             pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
             pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
      NettyClientHandler handler = handlerPool.borrowObject();
      pipeline.addLast(handler);
      channel.attr(AttributeKey.valueOf("handler")).set(handler); // 将handler保存到channel的属性中
         }
     });
     ChannelFuture future = connect(bootstrap, "127.0.0.1", 8080, MAX_RETRY);
     future.addListener(new ChannelFutureListener() {
         @Override
         public void operationComplete(ChannelFuture future) throws Exception {
             if (future.isSuccess()) {
                 System.out.println("连接成功!");
                 Channel channel = future.channel();
                 NettyClientHandler handler = (NettyClientHandler) channel.pipeline().last();
                 handlerPool.returnObject(handler); // 将handler对象归还给对象池
             } else {
                 System.out.println("连接失败!");
             }
         }
     });
 }
}

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/233623.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-11 17:10
下一篇 2024-12-11 17:11

相关推荐

  • gateway io.netty.buffer.poolchunk

    在本文中,我们将深入探讨Netty中的一个基础组件——PoolChunk,它是Netty中ByteBuf的一个关键实现,负责对ByteBuf进行缓存和管理。我们将从多个方面对该组件…

    编程 2025-04-28
  • 同时启动两个netty服务的实现方法

    本文将介绍如何同时启动两个netty服务的具体实现方法。 一、实现思路 为了同时启动两个netty服务,我们需要创建两个不同的Channel,每个Channel都绑定到不同的服务端…

    编程 2025-04-27
  • netty和tomcat的比较

    一、简介 Netty和Tomcat都是Java Web服务器,但它们的设计思想和应用场景不同。 Netty是一个高性能、异步事件驱动的网络通信框架,可以用于实现WebSocket服…

    编程 2025-04-20
  • 深入理解Netty粘包

    一、什么是粘包 网络通信中消息的传输有两个重要的问题,一个是粘包,一个是拆包。 粘包的概念就是发送方发送的多个小数据包被接收方一次性收到,这就像是把多个包“粘”在了一起。 造成粘包…

    编程 2025-04-12
  • Netty in Action:Java网络编程的终极选择

    一、基础概念 Netty是由JBOSS的工程师Norman Maurer和Trustin Lee共同开发的,是一个高性能、异步、事件驱动的网络编程框架。 相比于传统的BIO(Blo…

    编程 2025-01-24
  • 深入探讨Netty ByteBuf

    一、ByteBuf概述 在Netty中,ByteBuf是最基本、最核心的数据结构之一。实际上,Netty在设计时,就将ByteBuf作为数据处理的核心,因为I/O操作的数据流必定是…

    编程 2025-01-11
  • Netty面试题及答案详解

    一、Netty面试题及答案 在Netty的面试过程中,会涉及到不少面试题,下面列举并解答几个比较常见的问题。 1、Netty是什么? Netty是一个基于Java的NIO网络编程框…

    编程 2024-12-23
  • 使用Android Netty轻松实现网络通信

    一、什么是Android Netty Android Netty是一个开源的,基于Java NIO的客户端/服务器框架。Netty框架的出现使得开发者可以轻松地构建可维护和高性能协…

    编程 2024-12-22
  • Netty面试

    一、Netty面试题 Netty是一个高性能的网络通信框架,它的出现使得网络编程变得更加简单和高效。以下是一些常见的Netty面试题: 1. 请简要介绍Netty框架及其优点。 N…

    编程 2024-12-13
  • 如何使用Netty实现客户端断线重连

    一、Netty客户端离线监听 在Netty客户端中,由于网络原因,客户端会与服务端断开连接,但是我们希望客户端能够重新连接服务端,这就需要在客户端中监听客户端是否处于离线状态。 我…

    编程 2024-12-12

发表回复

登录后才能评论