Determine the load the system can handle in websocket connections.
Background
The difficulty is that websockets require a "handshake" to transform a http request to a tcp connection. I initial looked at Gatling ( http://gatling-tool.org/) with the websockets addon( https://github.com/gilt/gatling-websocket ). But I did not want learn scala or performing scripting. I wanted something that displayed output like apache bench. My research led me to Thor (https://www.npmjs.org/package/thor)
We have a user thor which we are going to run thor cd /home/thor wget http://nodejs.org/dist/v0.10.26/node-v0.10.26-linux-x64.tar.gz tar -xvf node-v0.10.26-linux-x64.tar.gz vi hello_nodes.js var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello Node.js\n'); }).listen(8124, "server"); console.log('Server running at http://server:8124/'); ./node-v0.10.26-linux-x64/bin/node hello_node.js Server running at http://server:8124/ In a browser : http://server:8124/
Install npm
My first attempt to install on Centos 5.8 was to find the rpms. npm and nodes.js was suppose to be in epel repo. wget http://dl.fedoraproject.org/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm rpm -Uvh epel-release-5-4.noarch.rpm yum search --enablerepo=epel-testing --enablerepo=epel npm No Matches found yum provides --enablerepo=epel-testing --enablerepo=epel npm */npm No Matches found I decided to build from source https://github.com/npm/npm export PATH=$PATH:/home/thor/node-v0.10.26-linux-x64/bin yum install git -y git clone https://github.com/npm/npm.git cd npm make install cd .. which npm /home/thor/node-v0.10.26-linux-x64/bin/npm
Install Thor
https://www.npmjs.org/package/thor npm install thor Example You can setup an apache tomcat websocket server Here. ws ./npm/node_modules/thor/bin/thor --amount 100 ws://websocket:8080/examples/websocket/chat ./npm/node_modules/thor/bin/thor --amount 1000 ws://websocket:8080/examples/websocket/chat ./npm/node_modules/thor/bin/thor --amount 100 --concurrent 5 ws://websocket:8080/examples/websocket/chat apache ws ./npm/node_modules/thor/bin/thor --amount 100 ws://websocket:9090/examples/websocket/chat ./npm/node_modules/thor/bin/thor --amount 1000 ws://websocket:9090/examples/websocket/chat ./npm/node_modules/thor/bin/thor --amount 100 --concurrent 5 ws://websocket:9090/examples/websocket/chat
Output
Thor: version: 1.0.0
God of Thunder, son of Odin and smasher of WebSockets!
Thou shall: - Spawn 1 workers. - Create 2 concurrent/parallel connections. - Smash 100 connections with the mighty Mjölnir.
The answers you seek shall be yours, once I claim what is mine.
Connecting to ws://websocket:8080/examples/websocket/chat
Opened 100 connections
Online 439 milliseconds Time taken 441 milliseconds Connected 100 Disconnected 0 Failed 0 Total transferred 132.62kB Total received 71.85kB
Durations (ms):
min mean stddev median max Handshaking 1 5 3 4 20 Latency 0 0 1 0 3
We need a specific version of python other that the default version install by the OS. For instance Centos 5.8 comes with python version 2.4.3. Under no circumstance we should replace the python version the OS requires. Bad things will happen.
Current Installation
#python Python 2.4.3 (#1, Jun 18 2012, 08:55:23) [GCC 4.1.2 20080704 (Red Hat 4.1.2-52)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> print sys.path ['', '/usr/lib/python2.4/site-packages/setuptools-0.6c11-py2.4.egg', '/usr/lib/python2.4/site-packages/chardet-1.0.1-py2.4.egg', '/usr/lib/python2.4/site-packages/autobahntestsuite-0.6.1-py2.4.egg', '/usr/lib/python2.4/site-packages/klein-0.2.3-py2.4.egg', '/usr/lib/python2.4/site-packages/Jinja2-2.7.2-py2.4.egg', '/usr/lib64/python24.zip', '/usr/lib64/python2.4', '/usr/lib64/python2.4/plat-linux2', '/usr/lib64/python2.4/lib-tk', '/usr/lib64/python2.4/lib-dynload', '/usr/lib64/python2.4/site-packages', '/usr/lib64/python2.4/site-packages/Numeric', '/usr/lib64/python2.4/site-packages/gtk-2.0', '/usr/lib/python2.4/site-packages']
Installation in a different location
python2.7 http://www.python.org/ftp/python/2.7.2/Python-2.7.2.tgz tar -xvf Python-2.7.2.tgz cd Python-2.7.2 ./configure make make altinstall
We have poor performance using http via apache mod_jk to talk to tomcat. Upon researching different options such as comet, ajp, long polling, websockets appeared to be the most efficient method to communicate with tomcat. The issue we encountered in our production environment is that the software release is set to specific version and we need to have it support websockets.
Websocket Basics
Websocket connection starts out as a ws or wss protocol request from a client such as browser:
We will install all the software on hostname "server"
Tomcat 7.0.27
As of version 7.0 tomcat has built in support and example application of websocket.
Install Tomcat
tar -xvf apache-tomcat-7.0.27.tar.gz cd apache-tomcat-7.0.27/bin sh startup.sh I recommend using chrome as the test browser. It has tools to debug the connection. Click Customize and Control Google Chrome > Tools > Developer tools
Now we established that tomcat websockets works, we will add the additional layer of the http server. Websockets was implemented in Apache version 2.4.5 but we only have version 2.2.15. We will need to build httpd apache proxy_wstunnel from source.
Build backport from source
Reference : https://gist.github.com/vitkin/6661683 svn co http://svn.apache.org/repos/asf/httpd/httpd/tags/2.2.15 httpd-2.2.15
wget https://gist.github.com/vitkin/6661683/raw/873dd8b4de4ad1ff69757ffe48fc574374aedc57/apache-2.2-wstunnel.patch cd httpd-2.2.15 patch -p1 -i ../apache-2.2-wstunnel.patch svn co http://svn.apache.org/repos/asf/apr/apr/branches/1.5.x/ srclib/apr svn co http://svn.apache.org/repos/asf/apr/apr-util/branches/1.5.x/ srclib/apr-util #autoconf not work ./buildconf ./configure --enable-so --enable-proxy --enable-proxy_wstunnel=shared make ./modules/proxy/.libs/mod_proxy_wstunnel.so cp ./modules/proxy/.libs/mod_proxy_wstunnel.so /usr/lib64/httpd/modules/
Edit apache configuration to support websockets
vi /etc/httpd/conf/httpd.conf LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so Listen 9090 ServerName server ProxyPass / ws://localhost:8080/ ProxyPassReverse / ws://localhost:8080/ ProxyPass / wss://localhost:8080/ ProxyPassReverse / wss://localhost:8080/ ProxyPass / http://localhost:8080/ ProxyPassReverse / http://localhost:8080/ Note ws, wss need to go before http service httpd restart apachectl -t -D DUMP_MODULES | grep proxy proxy_module (shared) proxy_balancer_module (shared) proxy_ftp_module (shared) proxy_http_module (shared) proxy_connect_module (shared) proxy_wstunnel_module (shared)
Testing websockets through apache httpd server
http://server:9090/examples/websocket/chat.html
TroubleShooting
When implementing the apache server, apache server would not return the websocket connection tomcat directly client : get /examples/websocket/chat.hmtl client : get /examples/websocket/chat, upgrade:websocket server : 101 Switching procotol
tomcat proxy via apache client : get /examples/websocket/chat.hmtl server : 200 client : get /examples/websocket/chat, upgrade:websocket server : 101 Switching procotol server : 502 Proxy.Error