标签:nio over pie 可靠 企业应用 软件 xtend 处理 bootstra
一、不选择Java原生NIO编程的原因
(1)NIO的类库和API复杂,使用麻烦,你需要熟练掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等
(2)需要具备其他的额外技能做铺垫,例如熟悉Java多线程编程。这是因为NIO编程涉及到Reactor模式,你必须对多线程和网络编程非常熟悉,才能编写出高质量NIO程序。
(3)可靠性能力补齐,工作量和难度都非常大。例如客户端面临断链重连、网络闪断、半包读写、失败缓存、网络拥塞和异常码流的处理等问题,NIO编程的特点是功能开发相对容易,但是可靠性能力补齐的工作量和难度非常大。
(4)JDK NIO的BUG,例如臭名昭著的epoll bug,它会导致Selector空轮询,最终导致CPU 100%。官方声称在JDK 1.6 版本的update 18修复了该问题,但是直到JDK 1.7版本该问题仍旧存在,只不过该BUG发生概率降低了一些而已,它并没有得到根本性解决。
二、Netty 优点
(1)API使用简单,开发门槛低
(2)功能强大,预置了多种编解码功能,支持多种主流协议
(3)定制能力强,可以通过ChannelHandler 对通信框架进行灵活地扩展
(4)性能高,通过与其他业界主流的NIO框架对比,Netty的综合性能最优
(5)成熟、稳定,Netty修复了已经发现的所有JDK NIO BUG,业务开发人员不需要再为NIO的BUG而烦恼
(6)社区活跃,版本迭代周期短,发现的BUG可以被及时修复,同时,更多的新功能会加入
(7)经历了大规模的商业应用考验,质量得到验证。Netty 在互联网、大数据、网络游戏、企业应用、电信软件的 众多行业已经得到了成功商业,证明它已经完全能够满足不同行业的商业应用了
三、Netty服务端Demo
import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; /** * Netty 时间服务器服务端TimeServer */ public class TimeServer { public void bind(int port) { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 1024).childHandler(new ChildChannelHandler()); //绑定端口,同步等待成功 ChannelFuture f = b.bind(port).sync(); //等待服务端监听端口关闭 f.channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); } finally { //优雅退出,释放线程池资源 bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } private class ChildChannelHandler extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new TimeServerHandler()); } } public static void main(String[] args) { int port = 8080; new TimeServer().bind(port); } } import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; import java.util.Date; public class TimeServerHandler extends ChannelHandlerAdapter{ @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf buf = (ByteBuf) msg; byte[] req = new byte[buf.readableBytes()]; buf.readBytes(req); String body = new String(req,"UTF-8"); System.out.println("The time server receive order : "+body); String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body)?new Date(System.currentTimeMillis()).toString():"BAD ORDER"; ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes()); ctx.write(resp); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); } }
四、Netty的客户端Demo
import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; /** * Created by ThinkPad on 2019/6/17. */ public class TimeClient { public void connect(int port,String host) { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY,true).handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new TimeClientHandler()); } }); //发起异步连接操作 ChannelFuture f = b.connect(host,port).sync(); //等待客户端连接操作 f.channel().closeFuture().sync(); }catch (Exception e) { e.printStackTrace(); }finally { //优雅退出,释放NIO线程组 group.shutdownGracefully(); } } public static void main(String[] args) { int port = 8080; new TimeClient().connect(port,"127.0.0.1"); } } import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; /** * Created by ThinkPad on 2019/6/17. */ public class TimeClientHandler extends ChannelHandlerAdapter{ private final ByteBuf firstMessage; public TimeClientHandler() { byte[] req = "QUERY TIME ORDER".getBytes(); firstMessage = Unpooled.buffer(req.length); firstMessage.writeBytes(req); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { ctx.writeAndFlush(firstMessage); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf buf = (ByteBuf)msg; byte[] req = new byte[buf.readableBytes()]; buf.readBytes(req); String body = new String(req,"UTF-8"); System.out.println("Now is : "+body); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); } }
五、测试运行结果
先运行Netty 服务端,然后在运行Netty 客户端
运行结果如下:
标签:nio over pie 可靠 企业应用 软件 xtend 处理 bootstra
原文地址:https://www.cnblogs.com/lovegrace/p/11047777.html