Simple analysis of the process of using nginx for ab site

Due to business needs, two sets of front-end pages are deployed on the official website to divert traffic through specific fields (such as mobile phone numbers) to meet the requirements of station a/b, and then analyze the final data of station a/b to select which part of the page It will be better for user experience.

 

nginx request offloading

Consider leveraging nginx's offloading capabilities:

http://neoremind.com/2012/03/nginx%E6%A0%B9%E6%8D%AEcookie%E5%88%86%E6%B5%81/

 

Use brew install nginx under mac, the directory after installation is: /usr/local/Cellar/nginx/1.10.3 (depending on different versions)/, the directory where the nginx configuration file is located: /usr/local/ etc/nginx.

 

In Postman, you need to install and download the Postman Interceptor extension. At this time, you can send the content in the headers to achieve the purpose of sending cookies:

 



 

 

In nginx, you can make a matching judgment based on the cookie to determine the server upstream to be sent:

match cookie
set $stream stream0;
if ($http_cookie ~* "phone=([^;]+)(1$)"){
    set $stream stream1;
}
if ($http_cookie ~* "phone=([^;]+)(2$)"){
    set $stream stream2;
}

 

In the above example, only the last line of a single http_cookie can be matched. If we want to divide users according to the mobile phone tail number, we must match multiple attributes:

 

match cookie
        set $stream stream0;
        if ($http_cookie ~* "phone=([^;]+)([5-9]$)"){
            set $stream stream1;
        }
        if ($http_cookie ~* "phone=([^;]+)([0-4]$)"){
            set $stream stream2;
        }

 

Perform a range search. If it is between 5 and 9, it corresponds to stream1, otherwise it corresponds to stream2. If there is no such cookie, a default value of stream0 needs to be given.

 

The above situation occurs when the user is already logged in. If the request is in the process of registration/login, there is no cookie data at this time, but both operations are through POST requests, and there is a corresponding field phone number in the form. (phone), consider whether it can be filled according to the fields in the request body.

 

The introduction of variables in nginx is mainly as in the link:

https://moonbingbing.gitbooks.io/openresty-best-practices/content/openresty/inline_var.html

 

You can print out $request_body in the log, just add the $request_body attribute, if the data we add is "phone=111"

 

------WebKitFormBoundaryq2rbBAdTrAuTi6IG\x0D\x0AContent-Disposition: form-data; name=\x22phone\x22\x0D\x0A\x0D\x0A111\x0D\x0A------WebKitFormBoundaryq2rbBAdTrAuTi6IG--\x0D\x0A

 

It can be seen that these fields have undergone additional escape processing. If you want to analyze the fields in the request body, it is troublesome. nginx can only access the fields in the request body when the plug-in is modified to run (program nginx itself). .

 

Therefore, our solution is adjusted to write cookies after registration/login is completed, but the cache cannot be refreshed immediately, but the ajax request success callback on the page can be used to force the entire page to be refreshed to obtain the js/css resources corresponding to the a/b site, but May cause additional traffic loss.

 

 

Internal domain name resolution/translation

 

However, the service we deployed is theoretically on two docker containers, without a fixed IP, and is processed through different internal domain names. Therefore, when a domain name appears in the upstream, there will be a problem that cannot be forwarded, that is, the defined  http: //${url} is not replaced.

 

upstream main {
      server web1.local:80;
      server web2.local:80;
      server web3.local:80;
    }

 

To find through the problem, refer to one of the following articles:

http://serverfault.com/questions/598202/make-nginx-to-pass-hostname-of-the-upstream-when-reverseproxying

 

Tried the first way, setting proxy_set_header, and it didn't work:

 

    proxy_set_header Host            $host;
    proxy_set_header X-Forwarded-For $remote_addr;

 

The second method should be feasible in theory. It is to establish several virtual servers by opening multiple ports. However, since we deploy the system on lain (a practice of docker), there are many restrictions and only one can be opened. web port, so this method is not feasible in the lain environment.

server {
  listen      8001 default_server;
  server_name web1.example.com;
  location / {
    proxy_pass       http://web1.local:80;
    proxy_set_header Host web1.local:80;
  }
}

server {
  listen      8002 default_server;
  server_name web2.example.com;
  location / {
    proxy_pass       http://web2.local:80;
    proxy_set_header Host web2.local:80;
  }
}

server {
  listen      8003 default_server;
  server_name web3.example.com;
  location / {
    proxy_pass       http://web3.local:80;
    proxy_set_header Host web3.local:80;
  }
}

upstream main {
  server 127.0.0.1:8001;
  server 127.0.0.1:8002;
  server 127.0.0.1:8003;
}

server {
  listen      80;
  server_name example.com;
  location / {
    proxy_pass http://main;
  }
}

Tengine provides this support, http://tengine.taobao.org/document_cn/http_upstream_dynamic_cn.html, but through testing, it is found that this method supported by tengine may only be processed by the domain name that can be resolved by the external network. If it is an intranet domain name, it is still is the same as not configuring the module.

upstream stream80 {
        dynamic_resolve fallback=next fail_timeout=30s;
        #server www.xxx.cn;
        server xxx.xxapp.xyz;
    }

 

Transfer to xxx.xxapp.xyz, which is the internally resolved domain name:

 

[Snip20170302_2.png](http://pic.findyou.xin/38257ca397a84fc896e0d9f617f99cc0.png)

 

我们将转移到 www.xxx.cn,会发现已经进行了转换(错误是由于servername名称不匹配)

 

[Snip20170302_2.png](http://pic.findyou.xin/ba9885a13dcb4797ab9f50e473deae58.png)

 

基本判断tengine的这个模块应该是可用的,但域名解析可能用到了一些特殊的条件或算法,导致无法解析我们内网的域名,所以在只能部署单个对外端口的docker容器下,暂时不能解决内网upstream带server_name的问题(最终考虑将其部署在虚拟机上,开启多个端口来解决该问题,也就是参考链接中的第二条)。

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326612078&siteId=291194637