Grayscale publishing refers to a publishing method that can smoothly transition between black and white. AB test is a grayscale release method, allowing some users to continue to use A and some users to start using B. If users have no objection to B, then gradually expand the scope and migrate all users to B.
Grayscale publishing can ensure the stability of the overall system, and problems can be found and adjusted at the initial grayscale to ensure their impact.
A/B testing process


Nginx implements grayscale publishing based on cookies
Query the value of the Cookie key as version according to the Cookie. If the Cookie value is V1, it will be forwarded to tomcat1, and if it is V2, it will be forwarded to tomcat2. If the Cookie values do not match, the server corresponding to tomcat1 is used by default.
The two servers are defined as:
copytomcat1 192.168.1.80:8888 tomcat2 192.168.1.80:8080
Implemented with the if command
copyupstream tomcat1 { server 192.168.1.80:8888 max_fails=1 fail_timeout=60; } upstream tomcat2 { server 192.168.1.80:8080 max_fails=1 fail_timeout=60; } upstream default { server 192.168.1.80:8888 max_fails=1 fail_timeout=60; } server { listen 80 default_server; listen [::]:80 default_server; server_name _; # root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; set $group "default"; if ($http_cookie ~* "version=V1"){ set $group tomcat1; } if ($http_cookie ~* "version=V2"){ set $group tomcat2; } location / { proxy_pass http://$group; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; index index.html index.htm; } }
access test http://192.168.1.80
- no cookie value

- Set the cookie value to version=V1

- Set the cookie value to version=V2

Implemented with the map command
Configure a mapping in Nginx, COOKIE_version can parse out the version field in the Cookie. group is a variable, and {} contains mapping rules.
If a user whose version is V1 visits, the group is equal to tomcat1. When used in the server, it will be proxied to http://tomcat1. For users whose version is V2 to access, the group is equal to tomcat2. When used in the server, it will be proxied to http://tomcat2. If the Cookie values do not match, the server corresponding to tomcat1 is used by default.
copyupstream tomcat1 { server 192.168.1.80:8888 max_fails=1 fail_timeout=60; } upstream tomcat2 { server 192.168.1.80:8080 max_fails=1 fail_timeout=60; } upstream default { server 192.168.1.80:8888 max_fails=1 fail_timeout=60; } map $COOKIE_version $group { ~*V1$ tomcat1; ~*V2$ tomcat2; default default; } server { listen 80 default_server; listen [::]:80 default_server; server_name _; # root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { proxy_pass http://$group; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; index index.html index.htm; } }
Nginx implements grayscale publishing based on the source IP
If it is an internal IP, reverse proxy to tomcat2 (pre-release environment); if not, reverse proxy to tomcat1 (production environment)
copyupstream tomcat1 { server 192.168.1.80:8888 max_fails=1 fail_timeout=60; } upstream tomcat2 { server 192.168.1.80:8080 max_fails=1 fail_timeout=60; } upstream default { server 192.168.1.80:8888 max_fails=1 fail_timeout=60; } server { listen 80 default_server; listen [::]:80 default_server; server_name _; # root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; set $group default; if ($remote_addr ~ "192.168.1.250") { set $group tomcat2; } location / { proxy_pass http://$group; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; index index.html index.htm; } }
When accessing from the local browser, it is 192.168.1.250

When accessing from the server intranet, it is 127.0.0.1

If you only have a single server, you can set different website root directories according to different IP s to achieve the same purpose.
copyserver { listen 80; server_name www.XXXXX.com; access_log logs/www.XXXX.com.log main; set $rootdir "/var/www/html"; if ($remote_addr ~ "192.168.1.250") { set $rootdir "/var/www/test"; } location / { root $rootdir; } }