Sometimes you want to route traffic to different endpoints based on a http header.

Avoiding if statements in the nginx config is the most important part here.

The example below is based on the user-agent header that is send from the client.

Test nginx conf to view traffic flow

# create upstreams
# android and other non ios device
upstream android {
     server 127.0.0.1:8080;
}
# ios based devices
upstream ios {
     server 127.0.0.1:8081;
}

# map to different upstream backends based on user-agent header
map $http_user_agent $mobile_upstream {
     default    "android";
     ~iPod      "ios";
     ~iPad      "ios";
     ~iOS       "ios";
     ~iPhone    "ios";
}

server {
    listen 80;
    access_log off;
    location / {
        proxy_pass http://$mobile_upstream;
    }
}
server {
    listen 8080;
    access_log /var/log/nginx/default-android.log combined;

}
server {
    listen 8081;
    access_log /var/log/nginx/android-ios.log combined;
}

Another example, when you already have if in your upstream config inside you server{} block

# map function needs to before the server{} block 
# I use:  /etc/nginx/conf.d/00-map-mobile.conf
# set $mobile_device to 0 or 1 
map $http_user_agent $mobile_device {
  default      0;
  ~iPod        1;
  ~iPad        1;
  ~iOS 1;
  ~iPhone      1;
  ~mobile      1;
  ~Android     1;
}

# In the server{} block
include /etc/nginx/includes/ab-upstreams.conf
proxy_pass http://$upstream;

# Inside ab-upstreams.conf
# stuur naar nieuwe locatie       
if ($http_cookie ~ "version=new") {     
        set $upstream "new_cluster";      
} 
if ($request ~ "version=new") { 
        set $upstream "new_cluster";      
} 

# stuur user terug naar oude locatie      
if ($http_cookie ~ "version=old") {     
        set $upstream "old_cluster";        
} 
if ($request ~ "version=old") { 
        set $upstream "old_cluster";      
} 

# force modbile naar oude upstreams       
if ($mobile_device = 1) { 
        set $upstream "old_cluster";      
}

- Stein van Broekhoven


Comments

comments powered by Disqus