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