Skip to content

Instantly share code, notes, and snippets.

@jmervine
Last active November 27, 2021 16:04
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save jmervine/6077243 to your computer and use it in GitHub Desktop.
Save jmervine/6077243 to your computer and use it in GitHub Desktop.
Nginx Based A/B testing.
worker_processes 1;
events {
worker_connections 1024;
}
http {
include /home/t/nginx/conf/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
userid on;
userid_name vrid;
userid_domain example.com;
userid_expires max;
split_clients "${uid_set}${uid_got}" $bucketid {
10% "bucketOne";
* "bucketTwo";
}
upstream @appone {
server 0.0.0.0:3000;
}
server {
listen 80;
server_name localhost;
location / {
if ($cookie_bucket) {
set $bucketid $cookie_bucket;
}
proxy_set_header X-Bucket-ID $bucketid;
add_header X-Bucket-ID $bucketid;
proxy_pass http://@appone;
}
}
}
[jmervine@jmervine01 ~]$ curl localhost -i
HTTP/1.1 200 OK
Server: nginx/1.4.2
Date: Thu, 25 Jul 2013 05:58:46 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
X-Bucket-ID: bucketTwo
Set-Cookie: vrid=fwAAAVHwvpZmaHXrAwMFAg==; expires=Thu, 31-Dec-37 23:55:55 GMT; domain=example.com; path=/

Hello bucketTwo

[jmervine@jmervine01 ~]$ curl localhost -i
HTTP/1.1 200 OK
Server: nginx/1.4.2
Date: Thu, 25 Jul 2013 05:58:52 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
X-Bucket-ID: bucketOne
Set-Cookie: vrid=fwAAAVHwvpxmaHXrAwMGAg==; expires=Thu, 31-Dec-37 23:55:55 GMT; domain=example.com; path=/

Hello bucketOne
[jmervine@jmervine01 ~]$ curl -i -b "bucket=bucketThree" localhost
HTTP/1.1 200 OK
Server: nginx/1.4.2
Date: Thu, 25 Jul 2013 20:01:04 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
X-Bucket-ID: bucketThree
Set-Cookie: vrid=fwAAAVHxhACHOyT4AwMKAg==; expires=Thu, 31-Dec-37 23:55:55 GMT; domain=yellowpages.com; path=/

Hello bucketThree
var http = require('http');
var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
var bucketId = request.headers['x-bucket-id'];
response.end("Hello "+bucketId+"\n");
});
server.listen(3000);
console.log("Server running at http://127.0.0.1:3000/");
@cyx
Copy link

cyx commented Jul 25, 2013

Very nice :-)

@wookimiii
Copy link

I looked up uid_set and uid_got and its the setting and retrieving of the cookie for the user_id which you named vrid. So what is line 20 doing? Is it concatenating?

@jmervine
Copy link
Author

See split_client docs for details, but...

  1. uid_set is uid if no uid exists and is set, otherwise it's blank
  2. uid_got is uid if uid exists, otherwise is blank.
  3. "${uid_set}${uid_got}" will always equal uid.
  4. In split_clients, the first string is a unique identifier to set bucket, that string will always return the same bucket.

Clearer?

@wookimiii
Copy link

Thanks! Make sense

@sergeytsivin
Copy link

Thaks for helpful hint

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment