转自:https://medium.com/better-programming/load-testing-socket-io-web-applications-and-infrastructure-3e96011898e0 关于artillery的一个实践

Are you shipping a scalable real-time back end? This article provides a tutorial for load testing your Socket.IO-based WebSocket server, to simulate production load and identify performance bottlenecks or scalability issues.

Socket.IO is a framework built on top of the WebSocket protocol, which upgrades an HTTP connection using an Upgrade: websocket header, initiating a WebSocket handshake.

This provides a persistent connection between a client and server where both parties can emit messages at any time, without the need for the client to poll the server.

Socket.IO adds additional functionality on top of this, such as increasing browser and device support of your application by providing an option to fall back to Ajax requests when using a client which does not support WebSockets, or a client on a network which restricts the upgrade HTTP header or protocol changes.


Setup

To follow along with this tutorial, you can either clone and run the demo repositorylocally (suggested), or you can use the version hosted by me on Heroku.

If you choose to run the app locally, you will need to clone the repository and install the required dependencies using npm. The npm start script will start the app on your configured PORT, or 8080 by default.

First, let’s get familiar with the application. Once running, the application should work as below.

The main features to note are being able to send a realtime message between users, and see a count of the current participants in the chat room.

Below is an example of two different users sending and receiving messages in realtime — great!

Application demo


Load Testing

Now that we’ve set up the application, we can start our load testing. For this, we’ll use the Artillery Community Edition tool, which is a free and open-source load testing and functional testing toolkit.

To install the Artillery.io toolkit globally:

$ npm install artillery -g

Next, we need to create a YAML configuration file, which will specify the test configuration and scenarios.

simple-test.yaml

config:
target: "wss://socketio-loadtest.herokuapp.com"
socketio:
transports: ["websocket"]
phases:
- duration: 10 # Run scenario for 10 seconds
arrivalCount: 20 # Create 20 virtual users per scenario
scenarios:
- engine: "socketio"
flow:
- emit:
channel: "add user"
data: "John Doe"
- emit:
channel: "new message"
data: "Hello! {{ $randomString() }}"
- think: 5 # do nothing for 5 seconds, then disconnect

In the above configuration file, we specify our target URL, and Socket.IO engine. We configure our phases section to specify the number of virtual users we will emulate and the duration of the test. Initially, these are low numbers.

In the scenarios section, we specify what WebSocket events we would like the artillery.io client to emit to the server.

For this simple example, we will add a new user to the chat, using the add user event in the demo application, then post a new message. After five seconds, the user leaves which disconnects the WebSocket.

To run the above script, we will use the artillery run command.

$ artillery run load-test/simple-test.yaml

If we view our application in a browser (either locally, or at https://socketio-loadtest.herokuapp.com), virtual users can be seen joining the chatroom and leaving messages.

Simple socket.IO load test

The above simple script can be modified as you wish to increase the number of users in a scenario by tweaking the configuration values. For a more advanced test, you can find more verbose scenario examples below.


Assertions

Now that we have the tool setup, we can set the task to fail based on certain conditions, which is great for a CI environment.

We can choose to set a maximum allowed latency in milliseconds for minmaxmedianp95, and p99, or a maximum failure percentage rate. These can be configured to test again certain business rules, or SLOs.

To configure the above, we add an ensure entry to our configuration. Further examples can be found in the artillery.io documentation.

config:
target: "ws://localhost:8080"
ensure:
maxErrorRate: 1 # fail if error rate exceeds 1%
max: 500 # fail if max response time exceeds 500ms

Advanced Configuration

In the advanced example, dynamic variables are used to simulate a scenario which is closer to how the application will be used in production (real data). This is done using the faker npm module, inside a custom processor which allows us to run our custom code.

The load phase is configured to increase the arrival rate from 10 to 50 users over two minutes, followed by 10 minutes at 50 new users per second.

advanced-test.yaml

config:
target: "ws://localhost:8080"
ensure:
max: 500 # fail if max response time exceeds 500ms
maxErrorRate: 1 # fail if error rate exceeds 1%
socketio:
transports: ["websocket"]
processor: "./custom.js" # set a processor for dynamic variables
phases:
- duration: 120
arrivalRate: 10
rampTo: 50
name: "Warm up phase"
- duration: 600
arrivalRate: 50
name: "Sustained max load"
scenarios:
- engine: "socketio"
flow:
- function: "getChatData" # load variables
- emit:
channel: "add user"
data: "{{ name }}"
- emit:
channel: "new message"
data: "{{ greeting }}"
- think: 10 # stay connected for 10 seconds
- emit:
channel: "new message"
data: "{{ goodbye }}"

Run artillery using the advanced-test.yaml file

$ artillery run load-test/advanced-test.yaml

Advanced socket.IO load test

The above is a snippet of the ramp-up phase defined in the configuration file, where the arrival rate of virtual users increases from 10 to 50 users over two minutes.

The advanced scenario example can be tweaked in many ways depending on what type of test you want to run, such as how many concurrent connections can be handled, or maximum number of users before performance begins to degrade.


Recap

Load testing our Socket.IO applications is an important step in the application lifecycle, to learn:

  • The number of concurrent WebSocket connections the application can support.
  • How the application handles failure.
  • Determines if the current infrastructure is sufficient for the expected load.
  • Gives confidence in the system and its reliability and performance.
  • Helps ensure that degradation of any component in the stack doesn’t lower the state of security.

Next in the Socket.IO blog series will be a tutorial on how to debug memory leaks in Socket.IO applications. If you have any ideas on similar topics you’d be interested in, feel free to get in touch with those ideas.

Load Testing Socket.IO Web Applications and Infrastructure的更多相关文章

  1. node socket.io web

    soket.io & web http://socket.io/get-started/chat/ 新建一個文件夾 soketWeb ; 在sokertWeb 文件夾內新建一個 package ...

  2. Node学习笔记(三):基于socket.io web版你画我猜(二)

    上一篇基础实现的功能是客户端canvas作图,导出dataURL从而实现图片信息推送,下面具体讲下服务端的配置及客户端的配置同步 首先先画一个流程图,讲下大概思路 <canvas id=&quo ...

  3. Socket IO Web实时推送

    1服务器pom.xml引入 <!-- 服务端 --> <dependency> <groupId>com.corundumstudio.socketio</g ...

  4. Node学习笔记(三):基于socket.io web版你画我猜(一)

    经过惨淡的面试,也是知道了自己的不足,刚好最近在学习node,心中便有了做一个web版的你画我猜的想法 首先说下思路,在做准备工作的时候,有两个大概的思路: 1.规定一块div,捕捉鼠标事件,动态生成 ...

  5. tsung: an open-source multi-protocol distributed load testing tool

     ROPERTIES::type: KnowledgeBase_Cloud:END: 开源.多协议.分布式的压力测试工具   Item Summary tsung-recorder start 通过p ...

  6. [Node.js]29. Level 6: Socket.io: Setting up Socket.io server-side & Client socket.io setup

    Below we've already created an express server, but we want to start building a real-time Q&A mod ...

  7. [Node.js] Level 6. Socket.io

    6.2 Setting Up socket.io Server-Side So far we've created an Express server. Now we want to start bu ...

  8. 基于Node.js+socket.IO创建的Web聊天室

    这段时间进了一个新的项目组,项目是用Appcan来做一个跨平台的移动运维系统,其中前台和后台之间本来是打算用WebSocket来实现的,但写好了示例后发现android不支持WebSocket,大为受 ...

  9. 使用Node.js的socket.io模块开发实时web程序

    首发:个人博客,更新&纠错&回复 今天的思维漫游如下:从.net的windows程序开发,摸到nodejs的桌面程序开发,又熟悉了一下nodejs,对“异步”的理解有了上上周对操作系统 ...

随机推荐

  1. - Git常用命令 基础 总结 MD

    目录 目录 Git常用命令 帮助 help 常用操作 初始化 clone init 提交 push 暂存 更新 撤销修改 分支 branch 查看分支 创建分支 切换分支 checkout 删除分支 ...

  2. K8S学习笔记之Pod的Volume emptyDir和hostPath

    0x00 Volume的类型 Volume是Kubernetes Pod中多个容器访问的共享目录. Volume被定义在Pod上,被这个Pod里的多个容器挂在到相同或不同的路径下. Volume的生命 ...

  3. ajax 执行成功以后返回的数据走的是error方法而不是success方法的问题

    今天在一个功能的时候发现写的ajax的方法执行后台代码成功后返回前台时执行的是error方法而不是success方法,代码如下 jQuery('#form').ajaxSubmit({ type: & ...

  4. C# vb .net图像合成-合成自定义路径

    在.net中,如何简单快捷地实现图像合成呢,比如合成文字,合成艺术字,多张图片叠加合成等等?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码 ...

  5. 理解 Kubernetes 的亲和性调度

    这次给大家介绍下k8s的亲和性调度:nodeSelector.nodeAffinity.podAffinity.Taints以及Tolerations用法. 一般情况下我们部署的 POD 是通过集群自 ...

  6. 电脑远程连接windows阿里云服务器解决卡顿【小白教程】

    我们在阿里云服务器网页上进行远程连接进行操作,会卡顿.解决办法如下: 1.登录阿里云服务器,进入服务器控制台,复制服务器IP:  2.回到桌面,打开cmd命令窗口,输入mstsc  3.在‘’计算机’ ...

  7. Fedora搭dokuwiki的步骤 以apache2.4为例

    官网下载dokuwiki的包,解压到/var/www/html/下 修改dokuwiki的权限.拥有者/组 为apache 安装PHP 在/etc/httpd/conf 创建dokuwiki的配置文件 ...

  8. ML- 线性回归推导

    线性回归, 这部分算是我最为擅长的了, 真的不吹, 6年经验, 我高中时代就已经会推导了, 当然是最最小二乘法和统计学(假设检验, 参数分布等)的角度. 后来上了大学, 又是从最小二乘和统计学角度, ...

  9. (七)Kubernetes Service资源

    Service概述 为什么要使用Service Kubernetes Pod是平凡的,由Deployment等控制器管理的Pod对象都是有生命周期的,它们会被创建,也会意外挂掉.虽然它们可以由控制器自 ...

  10. 执行shell脚本时提示/bin/sh^M: bad interpreter: No such file or directory

    执行脚本时提示解释器有问题,错误提示如下: 这种提示一般是脚本在windows系统之通过记事本写的,记事本修改过的文本,会默认在文本前面加上一些看不到的标记,导致shell脚本不能被shell解释器识 ...