Socket.io - sticky sessions with nginx ingress controller for k8s [solved] #1061
Replies: 5 comments 7 replies
|
hi @DominicWatson 👋 Artillery uses the official Socket.io client under the hood, which should be taking care of storing & resending cookies when HTTP long polling is used. What does the output from Artillery look like when you run a test? |
|
More info on this. Adding the following in the test yaml, allowed the connections to work on a single pod without any errors: config:
socketio:
extraHeaders:
Cookie: "route=1623081686.647.13662.138379"However, I had to manually find out a valid route and use that rather than it being dynamic. Could be related to #1035 or #232 ? |
|
Ok, so the issue seems to be this one: socketio/socket.io-client#1159. Something to do with node not allowing the cookies here due to cross origin things. The workaround suggested is to set config:
socketio:
extraHeaders:
Cookie: "{{ ck }}"
scenarios:
- name: "Brief Test"
weight: 1
engine: "socketio"
flow:
- get:
url: /
capture:
header: "set-cookie"
as: "ck"
- loop:
- emit:
channel: "msg"
data: "hello brief world! {{ $randomString() }}"
namespace: "/simpleloadtest"
- think: 10
count: 2 |
|
Ok, so I have a solution that mods the core socketio engine in artillery by:
Then I use a config:
processor: "./functions.js"
# ...
scenarios:
- name: "my scenario"
beforeScenario: "fetchCookies" # sets the env.socketCookies variable after getting cookies by visiting a page on the site
socketio:
extraHeaders:
Cookie: "{{ socketCookies }}"
# ...Will make a fork and pull request with changes to the engine if you're interested @hassy Edit Here's the var request = require('sync-request');
var Cookie = require('request-cookies').Cookie;
module.exports = {
setupCookies: setupCookies
}
function setupCookies(context, ee, next) {
var resp = request( "GET", context.vars.target )
, rawcookies = resp.headers['set-cookie']
, formatted = []
, cookies, i;
for ( i in rawcookies ) {
var cookie = new Cookie( rawcookies[i] );
formatted.push( cookie.key + "=" + cookie.value );
}
context.vars.socketcookies = formatted.join( "; " );
return next();
} |
|
Ok, final thing on this.
config:
variables:
route:
- a
- b
- c
- d
- e
- f
- g
- h
- i
- j
scenarios:
- name: "A SocketIo scenario"
engine: "socketio"
socketio:
extraHeaders:
Cookie: "route={{ route }}"
flow:
# ...The workaround above works with my nginx ingress controllers load balancer implementation. It seems you can throw in your own |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Hi there, we have a java based application that implements a Socket.io server (i.e. not a nodejs server). Our Kubernetes cluster setup uses sticky sessions for our multi-replica deployment because as of now, our Engine.io/Socket.io server implementation does not support clustering for establishing a connection.
It appears, however, that Artillery is not storing and resending cookies during the Socket handshake. This means that requests are going to different servers which leads to failed handshakes. (hypothesis).
Is this correct and is it something that you might consider changing?
TIA
Updated with solution below
The below concept is a workaround for cookie issues using socket.io client with Artillery and using nginx ingress controller loadbalancing in k8s:
All reactions