a problem in my app Performance Testing
chris
zz12847643 at gmail.com
Tue Jan 4 00:12:29 EST 2011
thanks for your reply , the problem i had resolved and the decoder i had
modified like Factorial .
thank you..
but the other problem about memory leak still trouble me.
i have replyed the other mail for that.
Upstream network tech. Ltd.
Chris Cheung
focus on java,c programming language and linux core
On Tue, Jan 4, 2011 at 10:57, Trustin Lee [via Netty Forums and Mailing
Lists] <ml-node+5887488-405170497-309534 at n2.nabble.com<ml-node%2B5887488-405170497-309534 at n2.nabble.com>
> wrote:
> Your decoder implementation is incorrect. There's no need to call
> Channel.isReadable()and you need to check if there's enough data in the
> buffer before decoding. Please refer to te user guide and the examples like
> Factorial
>
> --
> Trustin Lee - http://gleamynode.net/
> Sent from a mobile device - please excuse the brevity.
>
> On Dec 27, 2010, at 11:13 AM, chris <[hidden email]<http://user/SendEmail.jtp?type=node&node=5887488&i=0>>
> wrote:
>
> >
> > I'm sorry for my bad English writting.
> > cut in short..
> >
> > i'm developping a webgame,when i was doing the performance testing upon
> > Concurrency 4000
> > , console print the exception as follows :
> >
> > java.lang.ArrayIndexOutOfBoundsException
> > at java.lang.System.arraycopy(Native Method)
> > at
> >
> org.jboss.netty.buffer.HeapChannelBuffer.setBytes(HeapChannelBuffer.java:137)
>
> > at
> >
> org.jboss.netty.buffer.HeapChannelBuffer.setBytes(HeapChannelBuffer.java:130)
>
> > at
> >
> org.jboss.netty.buffer.AbstractChannelBuffer.writeBytes(AbstractChannelBuffer.java:462)
>
> > at
> >
> org.jboss.netty.buffer.DynamicChannelBuffer.ensureWritableBytes(DynamicChannelBuffer.java:85)
>
> > at
> >
> org.jboss.netty.buffer.DynamicChannelBuffer.writeBytes(DynamicChannelBuffer.java:239)
>
> > at
> >
> org.jboss.netty.buffer.AbstractChannelBuffer.writeBytes(AbstractChannelBuffer.java:457)
>
> > at
> >
> org.jboss.netty.buffer.AbstractChannelBuffer.writeBytes(AbstractChannelBuffer.java:450)
>
> > at
> >
> org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:213)
>
> > at
> > org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:274)
> > at
> > org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:261)
> > at
> > org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:350)
> > at
> >
> org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:281)
>
> > at
> > org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:201)
> > at
> >
> org.jboss.netty.util.internal.IoWorkerRunnable.run(IoWorkerRunnable.java:46)
>
> > at
> >
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>
> > at
> >
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>
> > at java.lang.Thread.run(Thread.java:619)
> >
> >
> >
> > ackage net.sy599.mahjong.socket.server;
> >
> > import java.net.InetSocketAddress;
> > import java.util.List;
> > import java.util.Map;
> > import java.util.concurrent.ExecutorService;
> > import java.util.concurrent.Executors;
> >
> > import net.sy599.mahjong.common.context.MahjongContext;
> > import net.sy599.mahjong.polling.TableAssignmentExecutor;
> >
> > import org.apache.log4j.xml.DOMConfigurator;
> > import org.jboss.netty.bootstrap.ServerBootstrap;
> > import org.jboss.netty.channel.ChannelFactory;
> > import org.jboss.netty.channel.ChannelPipelineFactory;
> > import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
> > import org.slf4j.Logger;
> > import org.slf4j.LoggerFactory;
> > import org.springframework.context.ApplicationContext;
> >
> > /** bootstrap
> > *
> > * @author chris
> > */
> > public class GameServerBootStrap
> > {
> > /**
> > * serversocket
> > */
> > private Map bootstrapConfigMap = null;
> >
> > private List roomIdList = null;
> >
> > private static final Logger LOGGER = LoggerFactory.getLogger("sys");
> >
> > /**
> > * port
> > */
> > private Integer port = null;
> >
> > public static void main(String[] args)
> > {
> > DOMConfigurator.configure("../config/log4j.xml");
> >
> > LOGGER.info("spring Bean factory init ...");
> >
> > ApplicationContext context = MahjongContext.getContext();
> >
> > LOGGER.info(" spring Bean factory init complete !!");
> >
> > MahjongAgentServer server =
> > context.getBean("agentServer",MahjongAgentServer.class);
> >
> > ChannelPipelineFactory pipeFactory =
> > context.getBean("pipeFacotory",ChannelPipelineFactory.class);
> >
> > ChannelFactory factory = new
> > NioServerSocketChannelFactory(Executors.newCachedThreadPool(),
> > Executors.newCachedThreadPool());
> >
> > ServerBootstrap bootstrap = new ServerBootstrap(factory);
> >
> > bootstrap.setOptions(server.getBootstrapConfigMap());
> >
> > bootstrap.setPipelineFactory(pipeFactory);
> >
> > ExecutorService executorService =
> Executors.newCachedThreadPool();
> >
> > List idList = server.getRoomIdList();
> >
> > for(Integer i: idList)
> > {
> > executorService.execute(new TableAssignmentExecutor(i));
> > }
> >
> > executorService.shutdown();
> >
> > LOGGER.info("Table Assignment Executor startup success..");
> >
> > bootstrap.bind(new InetSocketAddress(server.getPort()));
> >
> >
> > }
> >
> >
> >
> > package net.sy599.mahjong.socket.handler;
> >
> > import java.nio.charset.Charset;
> > import java.util.HashMap;
> > import java.util.Map;
> >
> > import net.sy599.mahjong.common.secret.BufferEncrypt;
> >
> > import org.jboss.netty.buffer.ChannelBuffer;
> > import org.jboss.netty.buffer.ChannelBuffers;
> > import org.jboss.netty.channel.Channel;
> > import org.jboss.netty.channel.ChannelHandlerContext;
> > import org.jboss.netty.handler.codec.frame.FrameDecoder;
> > import org.slf4j.Logger;
> > import org.slf4j.LoggerFactory;
> >
> >
> > /** decoder for game socket
> > * @author chris
> > *
> > */
> > public class ActionDecoder extends FrameDecoder
> > {
> >
> > private static final Logger LOGGER = LoggerFactory.getLogger("sys");
> >
> > @Override
> > protected Object decode(ChannelHandlerContext ctx, Channel channel,
> > ChannelBuffer buffer) throws Exception
> > {
> > Map map = null;
> > if (channel.isReadable())
> > {
> > byte[] tou = new byte[8];
> > buffer.getBytes(0, tou);
> > String str = new String(tou,Charset.forName("utf-8"));
> > if (str.startsWith(" "
> > +""
> > +" "+"\0";
> > byte[] xmlarray =
> xml.getBytes(Charset.forName("utf-8"));
> > ChannelBuffer anquanHeader =
> ChannelBuffers.dynamicBuffer();
> > anquanHeader.writeBytes(xmlarray);
> > channel.write(anquanHeader);
> > return map;
> > }
> > buffer.readByte(); //i
> > buffer.readByte(); //c
> > short cmdNum = buffer.readShort(); //cmd
> > buffer.readByte(); //mainver
> > buffer.readByte(); //subver
> > short a = buffer.readShort(); //length
> > buffer.readByte();
> > byte[] content = new byte[a];
> > buffer.readBytes(content);
> > byte[] finalbuffer = new
> BufferEncrypt().CrevasseBuffer(content, 0, a, 1,
> > BufferEncrypt.m_RecvByteMap);
> > ChannelBuffer contentBuffer =
> ChannelBuffers.wrappedBuffer(finalbuffer);
> > map = new HashMap();
> > map.put(cmdNum, contentBuffer);
> > }
> > return map;
> > }
> > }
> >
> >
> > /** game socket handler
> > *
> > * @author chris
> > *
> > */
> > public class ActionHandler extends SimpleChannelHandler {
> > /**
> > *
> > */
> > private CommandSchedular command = null;
> > private static final Logger LOGGER = LoggerFactory.getLogger("sys");
> >
> > @Override
> > public void writeRequested(ChannelHandlerContext ctx, MessageEvent e)
> > throws Exception {
> > ChannelBuffer buffer = (ChannelBuffer) e.getMessage();
> > Channels.write(ctx, e.getFuture(), buffer);
> > }
> >
> > @Override
> > public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent
> e)
> > throws Exception {
> > e.getCause().printStackTrace();
> > //ctx.getChannel().close();
> > }
> >
> > @Override
> > public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
>
> > throws Exception {
> > Map map = (Map) e.getMessage();
> > Short cmdNum = map.keySet().iterator().next();
> > command.execute(cmdNum, map.get(cmdNum), e.getChannel());
> > }
> >
> > public void setCommand(CommandSchedular command) {
> > this.command = command;
> > }
> >
> > @Override
> > public void channelDisconnected(ChannelHandlerContext ctx,
> > ChannelStateEvent e) throws Exception {
> > e.getChannel().close();
> > }
> >
> > @Override
> > public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent
> e)
> > throws Exception {
> > Channel channel = e.getChannel();
> > int channelId = channel.getId();
> > channel.disconnect();
> > ChannelPersonMap channelPersonMap =
> > MahjongContext.getContext().getBean(BeanKey.CHANNELPERSONVIEWER,
> > ChannelPersonMap.class);
> > Player player =
> channelPersonMap.getOnlinePlayers().get(channelId);
> > MahjongTablePool tablePool =
> > MahjongContext.getContext().getBean(BeanKey.MAHJONGTABLEPOOL,
> > MahjongTablePool.class);
> > if (null == player) {
> >
> > return;
> > }
> > channelPersonMap.getOnlinePlayers().remove(channelId);
> > int tableId = player.getTableId();
> > int roomId = player.getRoomId();
> > MahjongTable table = tablePool.getTableByRoomIdAndTableId(roomId,
> > tableId);
> > if(table.getPersonGroup().isEmpty())
> > {
> > table.stopPlaying(true);
> > }
> >
> > if (Player.PLAYING != player.getStatus())
> > {
> >
> > table.setTimes(0);
> >
> > RoomPersonMap roomPersonViewer =
> > MahjongContext.getContext().getBean(BeanKey.ROOMPERSONVIEWER,
> > RoomPersonMap.class);
> > WaitingQueue waitingQueue =
> > MahjongContext.getContext().getBean(BeanKey.WAITINGQUEUE,
> > WaitingQueue.class);
> >
> > waitingQueue.removePersonByRoomIdAndPlayer(player);
> > tablePool.removePersonByRoomIdAndPlayer(player);
> >
> > table.getSeatMap().remove(player.getSeatId());
> > roomPersonViewer.deletePersonByRoomIdAndPlayer(player);
> > RoomEmptyTableMap tableMap =
> > MahjongContext.getContext().getBean(BeanKey.ROOMEMPTYTABLEVIEWER,
> > RoomEmptyTableMap.class);
> > List list = tableMap.getEmptyTableListByRoomId(roomId);
> > if (!list.contains(table)) {
> > list.add(table);
> > }
> > ChannelBuffer bufferHeader =
> writeHeader(CmdKey.PLAYERLOGOUTRESPONSE);
> > bufferHeader.writeDouble(player.getXiaoneiId());
> > ChannelBuffer bufferTail = writeTail(bufferHeader, null);
> > table.getPersonGroup().write(bufferTail);
> > } else
> > {
> >
> > synchronized (table.getTIMEOUTLOCK()) {
> > if (player.getXiaoneiId().longValue() ==
> >
> table.getNowDiscardPlayer().getXiaoneiId().longValue()&&table.getWaitingCount()==1)
>
> > {
> >
> > table.getResponse1List().clear();
> > table.getResponse3List().clear();
> > table.getTask().cancel();
> > table.getTimer().purge();
> > MahjongContext.getContext().getBean(BeanKey.DISCARD,
> > Discard.class).execute(RespBean.newDefaultDiscard(table, player));
> >
> > } else if(table.getWaitingCount()==3){
> >
> > player.setAuto(true);
> > List list = table.getResponse3List();
> > boolean flag = true;
> > for (RespBean bean : list) {
> > if (bean.getXiaoneiId() ==
> player.getXiaoneiId().longValue()) {
> > flag = false;
> > }
> > }
> > if (flag) {
> >
> > table.addResponse(RespBean.defaultInstance(table,
> (byte) 1,
> > player.getXiaoneiId()));
> > }
> > }
> > }
> > ChannelBuffer bufferHeader =
> writeHeader(CmdKey.PLAYERLOGOUTRESPONSE);
> > bufferHeader.writeDouble(player.getXiaoneiId());
> > ChannelBuffer bufferTail = writeTail(bufferHeader, null);
> > table.getPersonGroup().write(bufferTail);
> > }
> > super.channelClosed(ctx, e);
> > }
> >
> >
> > }
> >
> > /** *
> > * @author chris
> > *
> > */
> > public class MahjongChannelPipelineFactory implements
> ChannelPipelineFactory
> > {
> > /**
> > * handlers
> > */
> > private ChannelHandler[] handlers = null;
> >
> > @Override
> > public ChannelPipeline getPipeline() throws Exception
> > {
> > ChannelPipeline p = Channels.pipeline();
> > //p.addLast("lengthDecoder",
> > MahjongContext.getContext().getBean(BeanKey.LENGTHDECODER,
> > LengthFieldBasedFrameDecoder.class));
> > p.addLast("actionDecoder",
> > MahjongContext.getContext().getBean(BeanKey.ACTIONDECODER,
> > ActionDecoder.class));
> > p.addLast("actionHandler",
> > MahjongContext.getContext().getBean(BeanKey.ACTIONHANDLER,
> > ActionHandler.class));
> > return p;
> > }
> >
> >
> > }
> >
> >
> >
> >
> >
> >
> > public class MessageManager
> > {
> > private static final Logger LOGGER = LoggerFactory.getLogger("sys");
> > /**
> > * 统一成功编码
> > */
> > private static final int DEFAULT_SUCCESS_MESSAGE = 0;
> >
> > /**
> > * head的长度
> > */
> > private static final int HEAD_LENGTH=9;
> >
> > /**
> > * 系统统一的消息头两个字母
> > */
> > private static final String SIGN = "IC";
> >
> > /**
> > * 加密解密工具类
> > */
> > private static BufferEncrypt encrypt =
> > MahjongContext.getContext().getBean(BeanKey.BUFFERENCRYPT,
> > BufferEncrypt.class) ;
> >
> > /**
> > * 发送成功消息
> > * @param channel 消息要发送的管道
> > * @param cmdNum 命令号
> > */
> > public static ChannelFuture sendDefaultSuccessMessage(Channel
> channel,short
> > cmdNum)
> > {
> > ChannelBuffer buf = writeHeader(cmdNum);
> > buf.writeShort(DEFAULT_SUCCESS_MESSAGE);
> > ChannelBuffer buffer = writeTail(buf,null);
> > ChannelFuture future = channel.write(buffer);
> > return future;
> > }
> >
> > /**
> > * 发送失败消息
> > * @param channel 通道
> > * @param errorCode 错误码
> > * @param cmdNum 命令号
> > */
> > public static ChannelFuture sendFailureMessage(Channel channel,
> Integer
> > errorCode,short cmdNum)
> > {
> > ChannelBuffer buf = writeHeader(cmdNum);
> > buf.writeInt(errorCode);
> > ChannelBuffer buffer = writeTail(buf,null);
> > ChannelFuture future = channel.write(buffer);
> > return future;
> > }
> >
> > /**写头
> > *
> > * @param cmd 命令号
> > * @return ChannelBuffer 装有header的buffer
> > */
> > public static ChannelBuffer writeHeader(short cmd) {
> > LOGGER.debug("向前台发送命令:"+cmd);
> > ChannelBuffer buf = ChannelBuffers.dynamicBuffer();
> > byte[] signBytes = SIGN.getBytes(Charset.forName("utf-8"));
> > buf.writeBytes(signBytes);
> > buf.writeShort(cmd);
> > byte version = (byte)0;
> > buf.writeByte(version);
> > byte subVersion = (byte)0;
> > buf.writeByte(subVersion);
> > buf.writeByte(0);//body length 6
> > buf.writeByte(0);//body length 7
> > byte checkCode = (byte)0;
> > buf.writeByte(checkCode);
> > return buf;
> > }
> >
> > /** 写头
> > *
> > * @param sign 头两个字母
> > * @param cmd 命令号
> > * @param version 主版本
> > * @param subVersion 子版本
> > * @return ChannelBuffer 装有header的buffer
> > */
> > @Deprecated
> > public static ChannelBuffer writeHeader(String sign, short cmd, byte
> > version, byte subVersion) {
> > ChannelBuffer buf = ChannelBuffers.dynamicBuffer();
> >
> > return buf ;
> > }
> >
> > /**将Buffer重新整理,调整length field,使其正确
> > *
> > * @param buffer 整个包含头和内容的buffer
> > * @return ChannelBuffer 整理
> > */
> > public static ChannelBuffer writeTail(ChannelBuffer buffer,Integer
> sig){
> > if(null != sig)
> > {
> > buffer.writeInt(sig);
> > }
> >
> > byte[] data = buffer.array();
> > int length = data.length;
> > int bodyLength = length - HEAD_LENGTH;
> > buffer.setShort(6, (short)bodyLength);
> > byte[] t = buffer.array();
> > int bufferSize = t.length;
> > t = encrypt.encryptBuffer(t,HEAD_LENGTH, bufferSize,
> > BufferEncrypt.m_SendByteMap);
> > ChannelBuffer buf = ChannelBuffers.dynamicBuffer();
> > buf.writeBytes(t);
> > return buf;
> > }
> > }
> >
> > my spring bean is singleton
> >
> > thanks for Netty Forums.
> > --
> > View this message in context:
> http://netty-forums-and-mailing-lists.685743.n2.nabble.com/a-problem-in-my-app-Performance-Testing-tp5868665p5868665.html<http://netty-forums-and-mailing-lists.685743.n2.nabble.com/a-problem-in-my-app-Performance-Testing-tp5868665p5868665.html?by-user=t>
> > Sent from the Netty User Group mailing list archive at Nabble.com.
> >
> > _______________________________________________
> > netty-users mailing list
> > [hidden email] <http://user/SendEmail.jtp?type=node&node=5887488&i=1>
> > https://lists.jboss.org/mailman/listinfo/netty-users
>
> _______________________________________________
> netty-users mailing list
> [hidden email] <http://user/SendEmail.jtp?type=node&node=5887488&i=2>
> https://lists.jboss.org/mailman/listinfo/netty-users
> what we call human nature in actuality is human habit
> http://gleamynode.net/
>
>
> ------------------------------
> View message @
> http://netty-forums-and-mailing-lists.685743.n2.nabble.com/a-problem-in-my-app-Performance-Testing-tp5868665p5887488.html
> To unsubscribe from a problem in my app Performance Testing, click here<http://netty-forums-and-mailing-lists.685743.n2.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=5868665&code=enoxMjg0NzY0M0BnbWFpbC5jb218NTg2ODY2NXwtOTExNTUxOTIw>.
>
>
--
View this message in context: http://netty-forums-and-mailing-lists.685743.n2.nabble.com/a-problem-in-my-app-Performance-Testing-tp5868665p5887676.html
Sent from the Netty User Group mailing list archive at Nabble.com.
More information about the netty-users
mailing list