异步通讯框架-Netty_实践分享.ppt.ppt
异步通讯框架-Netty 实践分享,2023/2/26,杭州斯凯网络科技有限公司,1,NIO和异步IO什么是NettyNetty的特性Netty的性能哪些地方在用Nettystc-nio-netty,2023/2/26,杭州斯凯网络科技有限公司,2,什么是NIO?NIO即new I/O,由于常常用来做非阻塞方式的IO操作,很容易被误认为是non-blocking IO的简称NIO和I/O有同样的作用和目的,但是使用方式不同NIO并非就一定是非阻塞的,2023/2/26,杭州斯凯网络科技有限公司,3,异步 I/O异步 I/O 是一种没有阻塞地读写数据的方法。您将注册对特定 I/O 事件的兴趣 可读的数据的到达、新的套接字连接,等等,而在发生这样的事件时,系统将会告诉您。您可以监听任何数量的通道上的事件,不用轮询,也不用额外的线程。,2023/2/26,杭州斯凯网络科技有限公司,4,NIO和异步IO什么是NettyNetty的特性Netty的性能哪些地方在用Nettystc-nio-netty,2023/2/26,杭州斯凯网络科技有限公司,5,什么是NettyNetty是一个异步的、基于事件驱动的NIO框架。Netty简单、高效、健壮、灵活。内置了大量协议的支持,要实现自己的自定义二进制协议也非常简单。所有的Channel I/O操作都是异步进行的。执行结果将会由ChannelFuture来通知。,2023/2/26,杭州斯凯网络科技有限公司,6,2023/2/26,杭州斯凯网络科技有限公司,7,NIO和异步IO什么是NettyNetty的特性Netty的性能哪些地方在用Nettystc-nio-netty,2023/2/26,杭州斯凯网络科技有限公司,8,特性Netty设计的初衷是提供最好的网络编程体验具体参考http:/www.jboss.org/netty,2023/2/26,杭州斯凯网络科技有限公司,9,良好的设计对阻塞和非阻塞的socket提供统一的API基于灵活的可扩展的事件模型高度可定制化的线程模型 真正支持无状态的连接,2023/2/26,杭州斯凯网络科技有限公司,10,易用性丰富的示例、文档和JAVADOC没有搞得大而全,更像瑞士军刀除了JDK1.5(或以上)外别无依赖,2023/2/26,杭州斯凯网络科技有限公司,11,高性能更好的吞吐量,更低的延迟更低的资源占用尽量避免不必要的内存拷贝,2023/2/26,杭州斯凯网络科技有限公司,12,健壮性在各种网络连接情况下,不再有OutOfMemoryError的发生避免了在高速网络环境下的NIO应用中经常出现的读写不均衡现象,2023/2/26,杭州斯凯网络科技有限公司,13,安全性完全支持 SSL/TLS 和 StartTLS在一些限制性的环境例如Applet 和Google Android中运行良好,2023/2/26,杭州斯凯网络科技有限公司,14,社区很频繁的发布版本作者在2003年就开始编写类似的框架,并且经常参与社区的讨论越来越多的开源项目从MINA切换到Netty,2023/2/26,杭州斯凯网络科技有限公司,15,NIO和异步IO什么是NettyNetty的特性Netty的性能哪些地方在用Nettystc-nio-netty,2023/2/26,杭州斯凯网络科技有限公司,16,性能比较 Netty VS Mina,2023/2/26,杭州斯凯网络科技有限公司,17,性能比较 NettyGrizzlyMINANIOFrameworkxSocket,2023/2/26,杭州斯凯网络科技有限公司,18,2023/2/26,杭州斯凯网络科技有限公司,19,2023/2/26,杭州斯凯网络科技有限公司,20,NIO和异步IO什么是NettyNetty的特性Netty的性能哪些地方在用Nettystc-nio-netty,2023/2/26,杭州斯凯网络科技有限公司,21,谁在使用NettyTwitter现在的应用服务器就是基于Netty写的,而且Twitter的大量项目都使用了NettyJmemcached Play FrameworkApache James ServerJBossWSAnd more,2023/2/26,杭州斯凯网络科技有限公司,22,NIO和异步IO什么是NettyNetty的特性Netty的性能哪些地方在用Nettystc-nio-netty,2023/2/26,杭州斯凯网络科技有限公司,23,stc-nio-nettystcNettyHttpServer.xmlstcNettyHttpConnector.xmlasync memcached,2023/2/26,杭州斯凯网络科技有限公司,24,示例代码HttpClientClientBootstrap bootstrap=new ClientBootstrap();bootstrap.setOption(remoteAddress,new InetSocketAddress(remoteAddress,remotePort);bootstrap.setFactory(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(),Executors.newCachedThreadPool();bootstrap.setPipelineFactory(httpClientPipelineFactory);ChannelFuture future=bootstrap.connect();channel=future.await().getChannel();channel.write(message);,2023/2/26,杭州斯凯网络科技有限公司,25,HttpClientPipelineFactory当socket连接建立后,Netty通过ChannelPipelineFactory获取一个新的Pipeline,这个Pipeline负责处理这个socket的业务逻辑public ChannelPipeline getPipeline()throws Exception ChannelPipeline pipeline=pipeline();pipeline.addLast(codec,new HttpClientCodec();pipeline.addLast(aggregator,new HttpChunkAggregator(1048576);pipeline.addLast(nettyEncoder,nettyEncoder);pipeline.addLast(GLOBAL_TRAFFIC_SHAPING,globalTrafficShapingHandler);pipeline.addLast(nettyDecoder,nettyDecoder);pipeline.addLast(handler,httpResponseHandler);return pipeline;,2023/2/26,杭州斯凯网络科技有限公司,26,Pipeline中可以添加任意多的逻辑处理单元(ChannelHandler),Netty会根据添加的顺序调用这些单元,这和web里面的fiterChain类似;这样的架构使单元复用变得很容易,例如统计流量,处理超时,协议编解码,压缩解压,安全验证等,都可以实现复用。,2023/2/26,杭州斯凯网络科技有限公司,27,HttpResponseHandler Override public void messageReceived(ChannelHandlerContext ctx,MessageEvent e)throws Exception eventBus.fireEvent(eventResponseReceived,e.getMessage();/异步+事件驱动,使得客户端发完信息后就可以立即释放线程资源,等应答回来后再继续处理,2023/2/26,杭州斯凯网络科技有限公司,28,异步HttpClientHTTP杯具的的协议规范注定HTTP自身是无法支持异步的。可以通过加大客户端和服务端的线程池和连接池来一定程度的解决这个问题。提交请求给HttpClient的线程可以立即返回要异步就得用一个全局唯一的UUID来标记请求和应答。由于http本身是阻塞的,所以同一个http连接不会存在UUID混乱的情况。,2023/2/26,杭州斯凯网络科技有限公司,29,服务端示例用Netty写client很简单,写服务端也一样HttpInboundServerBootstrap bootstrap=new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(),Executors.newCachedThreadPool();bootstrap.setPipelineFactory(pipelineFactory);bootstrap.setOption(child.keepAlive,true);channel=bootstrap.bind(new InetSocketAddress(this.acceptIp,this.acceptPort);,2023/2/26,杭州斯凯网络科技有限公司,30,HttpServerPipelineFactory/Do not create many instances.private HashedWheelTimer timer=new HashedWheelTimer();public ChannelPipeline getPipeline()throws Exception ChannelPipeline pipeline=pipeline();/HttpServerCodec是非线程安全的,不能所有Channel使用同一个 pipeline.addLast(codec,new HttpServerCodec();pipeline.addLast(GLOBAL_TRAFFIC_SHAPING,globalTrafficShapingHandler);pipeline.addLast(aggregator,new HttpChunkAggregator(1048576);pipeline.addLast(idleHandler,new IdleStateHandler(timer,0,0,idleTime,TimeUnit.SECONDS);pipeline.addLast(handler,httpRequestHandler);return pipeline;,2023/2/26,杭州斯凯网络科技有限公司,31,HttpRequestHandlerOverride public void exceptionCaught(ChannelHandlerContext ctx,ExceptionEvent e)throws Exception ctx.getChannel().close();Override public void messageReceived(ChannelHandlerContext ctx,MessageEvent e)throws Exception/处理收到的请求 eventBus.fireEvent(eventHttpRequestArrived,e.getMessage();Override public void channelClosed(ChannelHandlerContext ctx,ChannelStateEvent e)throws Exception Override public void channelIdle(ChannelHandlerContext ctx,IdleStateEvent e)throws Exception Override public void channelOpen(ChannelHandlerContext ctx,ChannelStateEvent e)throws Exception,2023/2/26,杭州斯凯网络科技有限公司,32,谢谢!,2023/2/26,杭州斯凯网络科技有限公司,33,