websocket性能测试工具调研对比

阿凡达2018-08-21 09:29

一、工具选型

  1. gatling
  2. node.js
  3. jmeter
  4. java websocket

这些工具都是可以支持websocket协议的工具,主要从以下几个方面进行对比:

  1. 工具使用的难易程度
  2. 测试工具的资源开销
  3. 和性能测试平台结合的难易程度

二、对比过程

对比场景

  1. 5000个用户,每秒钟发送100个登录请求,并保持链接
  2. 5000个用户,每隔5s发送一条点对点消息,即发送消息频率为1000

工具使用过程

1. gatling

工具简介:Gatling是一款基于Scala 开发的高性能服务器性能测试工具,它主要用于对服务器进行负载测试,并分析和测量服务器的各种性能指标。

工具语言:Scala语言

工具官网http://gatling.io/docs/2.0.0-RC2/index.html#

相关代码

    val httpConf = http
        .baseURL("http://host:port")
        .wsBaseURL("ws://host:port")

    val scn = scenario("WebSocket")
        .exec(http("handshark").get("/socket.io/1/?t=System.currentTimeMillis()")
        #因为服务端的协议特点,需要首先发送http请求,获取用户token,然后发送websocket协议
            .check(regex("""(^.+):90:60:""").saveAs("token")))
            #从请求返回的结果中提取出token
        .pause(1)
        .exec(ws("connect").open("/socket.io/1/websocket/${token}"))
        #websocket connect请求,请求中需要token参数
        .pause(1)
        .exec(ws("auth")
            .sendText("""3:::authInfos""")
            #链接建立成功后,发送登录请求
            .check(wsAwait.within(3 seconds).until(1).regex("200")))
            #验证是否登录成功 
        .repeat(5){
            exec(
                    ws("heartbeat")
                    .sendText("""2::""")
                    #需要自己管理心跳信息,每隔100s发送一次心跳信息
            )
            .pause(100)
        }
        .exec(ws("Close WS").close)

遇到的问题

  1. scale语言比较陌生,脚本编写时困难较多。目前暂未实现间隔一定时间,即发心跳又发消息的场景。
  2. 无法和性能测试平台结合,不过gatling本身的界面化就比较漂亮

2. node.js + socketIO

工具简介

  1. Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。
  2. socket.io一个是基于Nodejs架构体系的,支持websocket的协议用于时时通信的一个软件包。socket.io 给跨浏览器构建实时应用提供了完整的封装,socket.io完全由javascript实现。

工具语言:JavaScript

工具官网

相关代码

var io = require('socket.io-client');
var clients = require("./clients.js");
var fs = require('fs');

init = function(host, port, uid, token){
    var socket = io.connect(url,{path: '/socket.io/1/',transports: ['websocket']});

    socket.on('connect', function(){
        auth(this, uid, token);
    });

    socket.on('message', function(data){

    });

    socket.on('error', function(err){
        console.log('error: ' + err);
    });
};

var index = 0;

setInterval(function(){
    if(index < size){
        init(host, port, uid, token);
        index++;
    }
},authInterval);

function auth(socket, uid, token){
    if(socket) {
        var msg = '{"SID":2,"CID":3,"SER":11,"Q":[{"t":"property","v":{}}]}'
        socket.send(msg);
    }
}

遇到问题

  1. 如何进行分布式控制
  2. 如何和平台结合
3. jmeter

工具简介

jmeter是比较常见的性能测试开源工具,支持多种协议,可以自定义java请求,比较灵活。

工具语言

  1. java
  2. jmeter xml脚本文件

工具官网

  1. http://jmeter.apache.org/usermanual/get-started.html
  2. https://blog.flood.io/socket-io-and-websockets-with-gatling/

相关代码

遇到问题

  1. jmeter的工具本上是同步的,如果建立1w个链接的话,需要启动1w个线程处理,不适合测试高链接的场景

4. jetty websocketClient

工具简介

Jetty提供了功能更强的WebSocket API,使用一个公共的核心API供WebSockets的服务端和客户端使用。

工具语言:java

工具官网

  1. http://www.eclipse.org/jetty/documentation/9.3.9.v20160517/index.html

相关代码


@OnWebSocketClose
public void onClose(int statusCode, String reason) {
    System.out.printf("Connection closed: %d - %s%n", statusCode, reason);
    this.session = null;
    this.closeLatch.countDown();
}

@OnWebSocketConnect
public void onConnect(Session session) {
    System.out.printf("Got connect!");
    this.session = session;
    String authInfo = "3:::authinfo";
    try {
        Future<Void> fut = session.getRemote().sendStringByFuture(authInfo);
        fut.get(2, TimeUnit.SECONDS);
    } catch (Throwable t) {
        t.printStackTrace();
    }
}

@OnWebSocketMessage
public void onMessage(String msg) {
    System.out.printf("auth, 3-2");
}

遇到问题

  1. 需要自己写并发控制

三、对比结果总结

从选型上,最终比较倾向于gatling和socketIO

工具 gatling nodejs
脚本编写难易 scala语言不熟悉 node.js语言相对了解点
灵活性 略差 较好
结果数据 MRT:17ms、TPS:9.1 MRT:13.26ms,无TPS
client性能开销 CPU:20% 上下文切换:1.1w 内存:263m CPU 10% 上下文切换:3k 内存:321m
结果统计 gatling自己做的监控和数据分析,结果展示很漂亮 自己处理
其他 需要自己发送心跳包 心跳由socket.io自己控制



网易云新用户大礼包:https://www.163yun.com/gift

本文来自网易实践者社区,经作者侯本文授权发布。