Netty入门

朱雀 2022-12-18 09:58 335阅读 0赞

概述

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

Netty底层用的是NIO,用netty为什么不直接用NIO?之前感觉NIO不温不火可能是bug太多了或者学习成本太高了,api复杂要掌握ServerSocketChannel等等,还有就是例如臭名昭著的epoll bug导致空轮询问题,这个在jdk1.8都没有得到彻底的解决。好在Netty做了一个巧妙但是治标不治本的措施规避了,有兴趣的可以查阅一下。

相对地,Netty的优点有很多:

  1. 1.API使用简单,学习成本低。
  2. 2.功能强大,内置了多种解码编码器,支持多种协议。
  3. 3.性能高,对比其他主流的NIO框架,Netty的性能最优。
  4. 4.社区活跃,发现BUG会及时修复,迭代版本周期短,不断加入新的功能。
  5. 5.DubboElasticsearch都采用了Netty,质量得到验证。

架构图

在这里插入图片描述

说明:

  1. 绿色的部分Core核心模块,包括零拷贝、API库、可扩展的事件模型。
  2. 橙色部分Protocol Support协议支持,包括Http协议、webSocket、SSL(安全套接字协议)、谷歌Protobuf协议、zlib/gzip压缩与解压缩、Large
    File Transfer大文件传输等等。
  3. 红色的部分Transport Services传输服务,包括Socket、Datagram、Http Tunnel等等。

以上可看出Netty的功能、协议、传输方式都比较全,比较强大

demo样例

  1. <dependency>
  2. <groupId>io.netty</groupId>
  3. <artifactId>netty-all</artifactId>
  4. <version>4.1.20.Final</version>
  5. </dependency>

服务端启动类

  1. import com.netty.handle.MyServerHandler;
  2. import io.netty.bootstrap.ServerBootstrap;
  3. import io.netty.channel.ChannelFuture;
  4. import io.netty.channel.ChannelInitializer;
  5. import io.netty.channel.ChannelOption;
  6. import io.netty.channel.EventLoopGroup;
  7. import io.netty.channel.nio.NioEventLoopGroup;
  8. import io.netty.channel.socket.SocketChannel;
  9. import io.netty.channel.socket.nio.NioServerSocketChannel;
  10. public class MyServer {
  11. public static void main(String[] args) throws Exception {
  12. //创建两个线程组 boosGroup、workerGroup
  13. EventLoopGroup bossGroup = new NioEventLoopGroup();
  14. EventLoopGroup workerGroup = new NioEventLoopGroup();
  15. try {
  16. //创建服务端的启动对象,设置参数
  17. ServerBootstrap bootstrap = new ServerBootstrap();
  18. //设置两个线程组boosGroup和workerGroup
  19. bootstrap.group(bossGroup, workerGroup)
  20. //设置服务端通道实现类型
  21. .channel(NioServerSocketChannel.class)
  22. //设置线程队列得到连接个数
  23. .option(ChannelOption.SO_BACKLOG, 128)
  24. //设置保持活动连接状态
  25. .childOption(ChannelOption.SO_KEEPALIVE, true)
  26. //使用匿名内部类的形式初始化通道对象
  27. .childHandler(new ChannelInitializer<SocketChannel>() {
  28. @Override
  29. protected void initChannel(SocketChannel socketChannel) throws Exception {
  30. //给pipeline管道设置处理器
  31. socketChannel.pipeline().addLast(new MyServerHandler());
  32. }
  33. });//给workerGroup的EventLoop对应的管道设置处理器
  34. System.out.println("服务端已经准备就绪...");
  35. //绑定端口号,启动服务端
  36. ChannelFuture channelFuture = bootstrap.bind(6666).sync();
  37. //对关闭通道进行监听
  38. channelFuture.channel().closeFuture().sync();
  39. } finally {
  40. bossGroup.shutdownGracefully();
  41. workerGroup.shutdownGracefully();
  42. }
  43. }
  44. }

服务端处理器

  1. import io.netty.buffer.ByteBuf;
  2. import io.netty.buffer.Unpooled;
  3. import io.netty.channel.ChannelHandlerContext;
  4. import io.netty.channel.ChannelInboundHandlerAdapter;
  5. import io.netty.util.CharsetUtil;
  6. import java.util.concurrent.TimeUnit;
  7. /** * 自定义的Handler需要继承Netty规定好的HandlerAdapter * 才能被Netty框架所关联,有点类似SpringMVC的适配器模式 **/
  8. public class MyServerHandler extends ChannelInboundHandlerAdapter {
  9. @Override
  10. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  11. //获取客户端发送过来的消息
  12. ByteBuf byteBuf = (ByteBuf) msg;
  13. System.out.println("收到客户端" + ctx.channel().remoteAddress() + "发送的消息:" + byteBuf.toString(CharsetUtil.UTF_8));
  14. @Override
  15. public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
  16. //发送消息给客户端
  17. ctx.writeAndFlush(Unpooled.copiedBuffer("服务端已收到消息", CharsetUtil.UTF_8));
  18. }
  19. @Override
  20. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  21. //发生异常,关闭通道
  22. ctx.close();
  23. }
  24. }

客户端启动类

  1. import com.netty.handle.MyClientHandler;
  2. import io.netty.bootstrap.Bootstrap;
  3. import io.netty.channel.ChannelFuture;
  4. import io.netty.channel.ChannelInitializer;
  5. import io.netty.channel.nio.NioEventLoopGroup;
  6. import io.netty.channel.socket.SocketChannel;
  7. import io.netty.channel.socket.nio.NioSocketChannel;
  8. //客户端启动类
  9. public class MyClient {
  10. public static void main(String[] args) throws Exception {
  11. NioEventLoopGroup eventExecutors = new NioEventLoopGroup();
  12. try {
  13. //创建bootstrap对象,配置参数
  14. Bootstrap bootstrap = new Bootstrap();
  15. //设置线程组
  16. bootstrap.group(eventExecutors)
  17. //设置客户端的通道实现类型
  18. .channel(NioSocketChannel.class)
  19. //使用匿名内部类初始化通道
  20. .handler(new ChannelInitializer<SocketChannel>() {
  21. @Override
  22. protected void initChannel(SocketChannel ch) throws Exception {
  23. //添加客户端通道的处理器
  24. ch.pipeline().addLast(new MyClientHandler());
  25. }
  26. });
  27. System.out.println("客户端准备就绪..........");
  28. //连接服务端
  29. ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 6666).sync();
  30. //对通道关闭进行监听
  31. channelFuture.channel().closeFuture().sync();
  32. } finally {
  33. //关闭线程组
  34. eventExecutors.shutdownGracefully();
  35. }
  36. }
  37. }

客户端处理器

  1. import io.netty.buffer.ByteBuf;
  2. import io.netty.buffer.Unpooled;
  3. import io.netty.channel.ChannelHandlerContext;
  4. import io.netty.channel.ChannelInboundHandlerAdapter;
  5. import io.netty.util.CharsetUtil;
  6. //客户端处理器
  7. public class MyClientHandler extends ChannelInboundHandlerAdapter {
  8. @Override
  9. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  10. //发送消息到服务端
  11. ctx.writeAndFlush(Unpooled.copiedBuffer("hello world", CharsetUtil.UTF_8));
  12. }
  13. @Override
  14. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  15. //接收服务端发送过来的消息
  16. ByteBuf byteBuf = (ByteBuf) msg;
  17. System.out.println("收到服务端" + ctx.channel().remoteAddress() + "的消息:" + byteBuf.toString(CharsetUtil.UTF_8));
  18. }
  19. }

测试结果:
在这里插入图片描述在这里插入图片描述
下次再分享Netty的特性与重要组件

发表评论

表情:
评论列表 (有 0 条评论,335人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Netty入门

    概述 Netty是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。 Netty底层用的是NIO,用netty为什么不直接用NIO?之

    相关 Netty入门

    Netty是一个异步的事件驱动网络框架,使用Netty可以研发高性能的私有协议,将业务逻辑和网络进行解耦,通过Netty我们可以实现一些常用的协议,如HTTP。 基本概念

    相关 Netty入门

    第二部分 Netty入门 netty可以运用在那些领域? 1分布式进程通信 例如: hadoop、dubbo、akka等具有分布式功能的框架,底层RPC通信都是基