仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 467|回复: 8
打印 上一主题 下一主题

[学习教程] JAVA编程:netty使用中吸收缓存覆写的圈套仓酷云

[复制链接]
小妖女 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:22:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
令人可喜的是java现在已经开源了,所以我想我上述的想法也许有一天会实现,因为java一直都是不断创新的语言,每次创新都会给我们惊喜,这也是我喜欢java的一个原因。version:netty-3.2.1.final
location:org.jboss.netty.channel.socket.nio.NioWorker.read(SelectionKey)
代码片断以下:
  1. 01ByteBufferbb=recvBufferPool.acquire(predictedRecvBufSize);0203...0405if(readBytes>0){06bb.flip();0708finalChannelBufferFactorybufferFactory=09channel.getConfig().getBufferFactory();10finalChannelBufferbuffer=bufferFactory.getBuffer(11bb.order(bufferFactory.getDefaultOrder()));1213recvBufferPool.release(bb);1415//Updatethepredictor.16predictor.previousReceiveBufferSize(readBytes);1718//Firetheevent.19fireMessageReceived(channel,buffer);20}else{21recvBufferPool.release(bb);22}
复制代码
fireMessageReceived会终极触发handler的messageReceived办法的挪用,但吸收数据的buffer已在此前就偿还给了缓存池(recvBufferPool).实在,bb的接纳放在fireMessageReceived之前或以后,在一样平常情形下对实行的了局不发生影响,究竟在fireMessageReceived实行终了时,bb也就利用完了.可是,如有三个条件前提同时满意时,就会呈现bb被覆写成绩.

  • 利用ExecutionHandler异步化messageReceived的实行,那末bb就有大概在(异步线程)读取之前,被(以后线程)用厥后的数据覆写,除非buffer是bb的正本;
  • 利用DirectChannelBufferFactory完成zero-copy,那末buffer一定是对bb的wrapped,但bb并非间接服用的,而是由recvBufferPool办理,除非bb恰好满意了厥后数据的必要;
  • 利用FixedReceiveBufferSizePredictor令每次对缓存巨细需求都一样,那末bb就会被覆写.
重现这一圈套的代码以下:
  1. 01packagecn.cafusic.netty.execution.bug;0203importjava.net.InetSocketAddress;04importjava.util.concurrent.Executors;05importjava.util.concurrent.TimeUnit;0607importorg.jboss.netty.bootstrap.ClientBootstrap;08importorg.jboss.netty.bootstrap.ServerBootstrap;09importorg.jboss.netty.buffer.ChannelBuffer;10importorg.jboss.netty.buffer.ChannelBuffers;11importorg.jboss.netty.buffer.DirectChannelBufferFactory;12importorg.jboss.netty.channel.Channel;13importorg.jboss.netty.channel.ChannelFactory;14importorg.jboss.netty.channel.ChannelFuture;15importorg.jboss.netty.channel.ChannelHandlerContext;16importorg.jboss.netty.channel.ChannelPipeline;17importorg.jboss.netty.channel.ChannelStateEvent;18importorg.jboss.netty.channel.FixedReceiveBufferSizePredictor;19importorg.jboss.netty.channel.MessageEvent;20importorg.jboss.netty.channel.SimpleChannelHandler;21importorg.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;22importorg.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;23importorg.jboss.netty.channel.socket.nio.NioSocketChannelConfig;24importorg.jboss.netty.handler.execution.ExecutionHandler;2526/**27*Bug28*29*@author<ahref=mailto:jushi@taobao.com>jushi</a>30*@created2010-8-1731*32*/33publicclassBug{3435privatestaticclassClientHandlerextendsSimpleChannelHandler{36@Override37publicvoidmessageReceived(finalChannelHandlerContextctx,38finalMessageEvente)throwsException{39ChannelBufferbuf=(ChannelBuffer)e.getMessage();40while(buf.readable()){41System.out.print((char)buf.readByte());42}43System.out.println();44e.getChannel().close();45}46}4748privatestaticclassServerHandlerextendsSimpleChannelHandler{49@Override50publicvoidmessageReceived(finalChannelHandlerContextctx,51finalMessageEvente)throwsException{52TimeUnit.SECONDS.sleep(1);//delayforbufferrewrite.53e.getChannel().write(e.getMessage());54}5556@Override57publicvoidchannelConnected(ChannelHandlerContextctx,58ChannelStateEvente)throwsException{59System.out.println("connected:"+e.getChannel());60NioSocketChannelConfigconfig=61(NioSocketChannelConfig)e.getChannel().getConfig();62config.setBufferFactory(newDirectChannelBufferFactory());//zero-copy63config.setReceiveBufferSizePredictor(newFixedReceiveBufferSizePredictor(10));//fixbuffersizerequirement64}6566@Override67publicvoidchannelClosed(ChannelHandlerContextctx,ChannelStateEvente)throwsException{68System.out.println("closed:"+e.getChannel());69}70}7172staticvoidserve(){73finalChannelFactoryfactory=74newNioServerSocketChannelFactory(Executors.newSingleThreadExecutor(),75Executors.newSingleThreadExecutor(),761);77finalServerBootstrapbootstrap=newServerBootstrap(factory);7879ChannelPipelinepipeline=bootstrap.getPipeline();80pipeline.addLast("execution",81newExecutionHandler(Executors.newCachedThreadPool()));//asyncmessagereceived82pipeline.addLast("handler",newServerHandler());8384bootstrap.setOption("child.tcpNoDelay",true);85bootstrap.setOption("child.keepAlive",true);86finalChannelbind=bootstrap.bind(newInetSocketAddress(8080));8788Runtime.getRuntime().addShutdownHook(newThread(){89@Override90publicvoidrun(){91System.out.println("shutdown");92bind.close().awaitUninterruptibly();93bootstrap.releaseExternalResources();94}95});96}9798staticvoidconnect(){99finalChannelFactoryfactory=100newNioClientSocketChannelFactory(Executors.newSingleThreadExecutor(),101Executors.newSingleThreadExecutor(),1021);103104finalClientBootstrapbootstrap=newClientBootstrap(factory);105106ChannelPipelinepipeline=bootstrap.getPipeline();107pipeline.addLast("handler",newClientHandler());108109bootstrap.setOption("child.tcpNoDelay",true);110bootstrap.setOption("child.keepAlive",true);111ChannelFuturefuture=112bootstrap.connect(newInetSocketAddress("localhost",8080));113Channelchannel=future.awaitUninterruptibly().getChannel();114channel.write(ChannelBuffers.wrappedBuffer("++++++++++".getBytes()))115.awaitUninterruptibly();116channel.write(ChannelBuffers.wrappedBuffer("----------".getBytes()))117.awaitUninterruptibly();118channel.write(ChannelBuffers.wrappedBuffer("==========".getBytes()))119.awaitUninterruptibly();120channel.getCloseFuture().awaitUninterruptibly();121bootstrap.releaseExternalResources();122}123124publicstaticvoidmain(String[]args){125serve();126connect();127System.exit(0);128}129}
复制代码
C++编译的是本地码,优点是启动快,而且可以精确控制资源因此可以开发很高效的程序.缺点是编程麻烦,而且容易留下安全隐患.跨平台靠源代码在各个平台间分别编译(一处编写到处编译)
第二个灵魂 该用户已被删除
沙发
发表于 2015-1-20 22:10:37 | 只看该作者
Java是一种计算机编程语言,拥有跨平台、面向对java
海妖 该用户已被删除
板凳
发表于 2015-2-1 23:36:20 | 只看该作者
《JAVA语言程序设计》或《JAVA从入门到精通》这两本书开始学,等你编程有感觉的时候也可以回看一下。《JAVA读书笔记》这本书,因为讲的代码很多,也很容易看懂,涉及到面也到位。是你学习技术巩固的好书,学完后就看看《JAVA编程思想》这本书,找找一个自己写的代码跟书上的代码有什么不一样。
飘飘悠悠 该用户已被删除
地板
发表于 2015-2-7 16:11:20 | 只看该作者
你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。
蒙在股里 该用户已被删除
5#
发表于 2015-2-11 20:15:56 | 只看该作者
还好,SUN提供了Javabean可以把你的JSP中的 Java代码封装起来,便于调用也便于重用。
因胸联盟 该用户已被删除
6#
发表于 2015-3-2 18:20:51 | 只看该作者
学Java必读的两个开源程序就是Jive和Pet Store.。 Jive是国外一个非常著名的BBS程序,完全开放源码。论坛的设计采用了很多先进的技术,如Cache、用户认证、Filter、XML等,而且论坛完全屏蔽了对数据库的访问,可以很轻易的在不同数据库中移植。论坛还有方便的安装和管理程序,这是我们平时编程时容易忽略的一部份(中国程序员一般只注重编程的技术含量,却完全不考虑用户的感受,这就是我们与国外软件的差距所在)。
再见西城 该用户已被删除
7#
发表于 2015-3-8 13:44:09 | 只看该作者
设计模式是高级程序员真正掌握面向对象核心思想的必修课。设计模式并不是一种具体"技术",它讲述的是思想,它不仅仅展示了接口或抽象类在实际案例中的灵活应用和智慧
8#
发表于 2015-3-19 23:37:05 | 只看该作者
Jive的资料在很多网站上都有,大家可以找来研究一下。相信你读完代码后,会有脱胎换骨的感觉。遗憾的是Jive从2.5以后就不再无条件的开放源代码,同时有licence限制。不过幸好还有中国一流的Java程序员关注它,外国人不开源了,中国人就不能开源吗?这里向大家推荐一个汉化的Jive版本—J道。Jive(J道版)是由中国Java界大名 鼎鼎的banq在Jive 2.1版本基础上改编而成, 全中文,增加了一些实用功能,如贴图,用户头像和用户资料查询等,而且有一个开发团队在不断升级。你可以访问banq的网站
柔情似水 该用户已被删除
9#
发表于 2015-4-6 04:09:48 | 只看该作者
不过,每次的执行编译后的字节码需要消耗一定的时间,这同时也在一定程度上降低了 Java 程序的运行效率。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-11-15 17:01

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表