【cocos creator与C++知识分享】 三.websocket服务端压力测试

系统环境
本文适用于使用websocket网络通讯框架,需要测试执行具体业务对服务端造成的压力情况的小伙伴们。
百度一下网络测试有很多方案,比如jmeter,loadrunner等等,这里我们选择的是jmeter
首先安装jmeter
具体安装步骤请参考
安装jmeter

在eclipse中创建一个maven项目,修改pom.xml



以上就是所有需要引用的jar包,另外建议修改一下setting.xml中的镜像。


建议在mirrors中增加如上的镜像地址,这个库很全,基本上需要的jar包在这个里面都能找到。
完成之后回到eclipse增加三个类

MainClass

package xxxxx;

import java.net.URI;
import java.util.concurrent.TimeUnit;

import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient;

public class MainClass {
private static final String WS_URL = “ws://www.xxx.com/xxx”;
public static void main(String[] args) {
// TODO Auto-generated method stub
WebSocketClient client = new WebSocketClient();
SimpleEchoSocket socket = new SimpleEchoSocket();
try
{
client.start();
URI echoUri = new URI(WS_URL);
ClientUpgradeRequest request = new ClientUpgradeRequest();
client.connect(socket,echoUri,request);
System.out.printf(“Connecting to : %s%n”,echoUri);

        // wait for closed socket connection.
        socket.awaitClose(5,TimeUnit.HOURS);
    }
    catch (Throwable t)
    {
        t.printStackTrace();
    }
    finally
    {
        try
        {
            client.stop();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

}

}

LogicSampler

package gameServerJMeter;

import java.net.URI;
import java.util.concurrent.TimeUnit;

import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient;
public class LogicSampler extends AbstractJavaSamplerClient {
private static final String WS_URL = “ws://www.xxxx.com/websocket”;
public SampleResult runTest(JavaSamplerContext arg0) {
// TODO Auto-generated method stub

    WebSocketClient client = new WebSocketClient();
    SimpleEchoSocket socket = new SimpleEchoSocket();
    try
    {
        client.start();
        URI echoUri = new URI(WS_URL);
        ClientUpgradeRequest request = new ClientUpgradeRequest();
        client.connect(socket,echoUri,request);
        System.out.printf("Connecting to : %s%n",echoUri);
        // wait for closed socket connection.
        socket.awaitClose(5,TimeUnit.HOURS);
    }
    catch (Throwable t)
    {
        t.printStackTrace();
    }
    finally
    {
        try
        {
            client.stop();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
  return null;

}
}

SimpleEchoSocket

package gameServerJMeter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**

  • Basic Echo Client Socket
    */
    @WebSocket(maxTextMessageSize = 64 * 1024)
    public class SimpleEchoSocket
    {
    private final CountDownLatch closeLatch;
    @SuppressWarnings(“unused”)
    private Session session;
    private JSONObject userObj;
    private JSONObject[] players;
    private Integer roomId;
    private Integer onlinePlayerCount =0;
    private boolean diceThrowed = false;
    private int startCount = 0;

    private Map<Integer,Integer> lackedMapping;
    public SimpleEchoSocket()
    {
    this.closeLatch = new CountDownLatch(1);
    }

public boolean awaitClose(int duration, TimeUnit unit) throws InterruptedException
{
    return this.closeLatch.await(duration,unit);
}
@OnWebSocketClose
public void onClose(int statusCode, String reason)
{
    System.out.printf("Connection closed: %d - %s%n",statusCode,reason);
    this.session = null;
    this.closeLatch.countDown(); // trigger latch
}
@OnWebSocketConnect
public void onConnect(Session session)
{
    System.out.printf("Got connect: %s%n",session.getRemoteAddress());
    this.session = session;
    try
    {
    	testLogin();
    }
    catch (Throwable t)
    {
        t.printStackTrace();
    }
}
@OnWebSocketMessage
public void onMessage(String msg) throws InterruptedException
{
	System.out.println(msg);
	//在这里就可以写你得到服务端消息的时候需要进行的处理,
    //建议在这里模拟客户端的真实操作,这样能具体模拟出使用场景,以便于观察服务端的真实运行情况。
}

}

完成之后将项目导出为jar包。
进入jmeter目录,将以下包放入lib/ext目录中


然后回到bin目录,运行jmeter.bat

安装线程组,建议如果要执行多个的话就多添加几个线程组,一个线程组的线程数量开的太大会爆卡。

因为我要测试1万人同时在线,4个线程组2500个线程,每个线程就是一个牌桌,我在每个牌桌里会有4个玩家 所以,每个线程组我开625个线程。

然后添加java请求


这里选择你刚才导出的包,注意这个jar包是和刚才其他需要添加的包一起放到lib/ext里面了。
然后按照这个方法再添加4个线程组就可以点击开始运行了。
在服务端可以使用top命令查看内存和cpu的运行情况,如果要检测网络情况请安装nload,很好很强大。
在top命令之后可以按数字1调出所有CPU的情况展示。然后运行的时候观测各个指标即可。
如果要检测响应超时什么的可以在服务端返回给客户端消息的时候就带上响应时间参数。

这个测试方案研究了几天了,基本上可以模拟出业务系统运行状况,但是貌似不能获得jmeter的图形化展示结果,正在研究中…

如果哪位大神有更好的方案,记得给小弟分享下。万分感谢!!

4赞

多谢分享

手动帮顶,先收藏以后用到的时候看