官方api:https://netty.io/4.1/api/index.html
Netty 实战(精髓):https://waylau.gitbooks.io/essential-netty-in-action/
一、简单介绍
本文是根据李林峰书籍《Netty权威指南》(第2版)总结而来。
二、Netty简介
Netty是一个高性能、异步事件驱动的NIO框架,提供了对TCP、UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用户可以方便的主动获取或者通过通知机制获得IO操作结果。
作为当前最流行的NIO框架,Netty在互联网领域、大数据分布式计算领域、游戏行业、通信行业等获得了广泛的应用,一些业界著名的开源组件也基于Netty构建,比如RPC框架、zookeeper等。
三、Netty学习路线(与书本顺序基本一致)
1、NIO入门
2、Netty入门应用介绍(helloworld:时间服务器)
3、TCP粘包/拆包问题解决方法:
(1)LineBasedFromeDecoder+StringDecoder:按行切换的文本解码器
(2)DelimiterBasedFrameDecoder+StringDecoder:自动完成以分隔符做结束标志的消息的解码器
(3)FixedLengthFrameDecoder+StringDecoder:自动完成对定长消息的解码器
4、Netty序列化问题解决方法:
(1)介绍Java序列化的缺点
(2)MessagePack
(3)Google的ProtoBuf
(4)Facebook的Thrift
(5)JBoss Marshalling
5、Netty多协议开发和应用
(1)HTTP协议介绍
(2)Netty HTTP+XML协议栈开发
四、Netty实例(源码)
1、解决粘包/拆包问题(LineBasedFromeDecoder实现)
1 package com.rs.test.timeserver; 2 3 import io.netty.bootstrap.ServerBootstrap; 4 import io.netty.channel.ChannelFuture; 5 import io.netty.channel.ChannelInitializer; 6 import io.netty.channel.ChannelOption; 7 import io.netty.channel.EventLoopGroup; 8 import io.netty.channel.nio.NioEventLoopGroup; 9 import io.netty.channel.socket.SocketChannel; 10 import io.netty.channel.socket.nio.NioServerSocketChannel; 11 import io.netty.handler.codec.LineBasedFrameDecoder; 12 import io.netty.handler.codec.string.StringDecoder; 13 14 public class TimeServer { 15 16 public void bind(int port) throws Exception { 17 // 配置服务端的NIO线程组 18 EventLoopGroup bossGroup = new NioEventLoopGroup(); 19 EventLoopGroup workerGroup = new NioEventLoopGroup(); 20 21 try { 22 ServerBootstrap b = new ServerBootstrap(); 23 b.group(bossGroup, workerGroup) 24 .channel(NioServerSocketChannel.class) 25 .option(ChannelOption.SO_BACKLOG, 1024) 26 .childHandler(new ChildChannelHandler()); 27 28 // 绑定端口,同步等待成功 29 ChannelFuture f = b.bind(port).sync(); 30 31 // 等待服务端监听端口关闭 32 f.channel().closeFuture().sync(); 33 } finally { 34 // 优雅退出,释放线程池资源 35 bossGroup.shutdownGracefully(); 36 workerGroup.shutdownGracefully(); 37 } 38 } 39 40 private class ChildChannelHandler extends ChannelInitializer<SocketChannel> { 41 42 @Override 43 protected void initChannel(SocketChannel ch) throws Exception { 44 // 核心在下面两行,加入了LineBasedFrameDecoder和StringDecoder两个解码器 45 // 所以当消息到达我们的业务处理handler即TimerServerHandler,所看到的消息 46 // 都是前面两个解码器经过处理之后的结果 47 ch.pipeline().addLast(new LineBasedFrameDecoder(1024)); 48 ch.pipeline().addLast(new StringDecoder()); 49 ch.pipeline().addLast(new TimeServerHandler()); 50 } 51 52 } 53 54 public static void main(String[] args) throws Exception { 55 int port = 8080; 56 if(args != null && args.length > 0) { 57 try { 58 port = Integer.valueOf(port); 59 } catch (NumberFormatException e) { 60 // TODO: handle exception 61 } 62 } 63 new TimeServer().bind(port); 64 } 65 66 }