《利用ngx_http_mirror_module實現流量鏡像》要點:
本文介紹了利用ngx_http_mirror_module實現流量鏡像,希望對您有用。如果有疑問,可以聯系我們。
背景
最近 Nginx 官網發布了 Nginx 1.13.4,Nginx 1.13.4 中新增了一個 ngx_http_mirror_module
模塊.通過 mirror 模塊,可實現對原始請求創建后臺鏡像,鏡像子請求的輸出會被忽略.
利用這一功能我們就可以將線上實時訪問流量拷貝至其它環境,基于這些流量可以做版本發布前的預先驗證或者進行流量放大后的壓測等等.
在這之前與這一功能類似的軟件有:TCPCopy等,Nginx 自身支持后使用起來就更加方便了.下面我們來看看具體的如何配置:
mirror 模塊在 Nginx 1.13.4中默認是啟用的,如果要禁用這個功能可在編譯時加上 --without-http_mirror_module
參數.
$ apt-get install libreadline-dev libncurses5-dev libpcre3-dev libssl-dev perl make build-essential $ wget http://nginx.org/download/nginx-1.13.4.tar.gz $ tar xzvf nginx-1.13.4.tar.gz $ cd nginx-1.13.4/ $ ./configure $ make && make install
mirror 模塊配置分為兩部分:源地址和鏡像地址配置.配置位置可以為 Nginx 配置文件的 http
, server
, location
的上下文中,配置示例為:
# original配置 location / { ? ?mirror /mirror; ? ?mirror_request_body off; ? ?proxy_pass http://127.0.0.1:9502; } # mirror配置 location /mirror { ? ?internal; ? ?proxy_pass http://127.0.0.1:8081$request_uri; ? ?proxy_set_header X-Original-URI $request_uri; }
在這個示例中我們配置了兩組后臺服務器,http://127.0.0.1:9502
指向生產服務器, http://127.0.0.1:8081
指向測試服務器.用戶訪問生產服務器的同時,請求會被 Nginx 復制發送給測試服務器,需要注意的一點是 mirror 不會輸出 http 返回內容.
指定了源 uri 為 /
指定鏡像 uri 為 /mirror
指定是否鏡像請求 Body 部分,此選項與proxy_request_buffering
、fastcgi_request_buffering
、scgi_request_buffering
和 uwsgi_request_buffering
沖突,一旦開啟mirror_request_body
為 on,則請求自動緩存.
指定上游 Server 的地址.
指定此 location 只能被內部的請求調用,外部的調用請求會返回 Not found (404).
指定上游 Server 的地址.
設置鏡像流量的頭部.
按照上述配置,搭建了上圖所示的驗證環境,各個模塊均部署在本機,由curl發起請求:
$ curl 127.0.0.1
original 和 mirror 均為上游 Server PHP 腳本,其中 original 返回響應 response to client. 抓包結果如下圖:
分析抓包結果,整個請求流程為:
由此可見,在整個流程中 Nginx 將請求轉發送至 original 和 mirror,然后等待響應.幾乎不會對正常請求造成影響,整個處理過程是完全異步的.
static ngx_int_t ngx_http_mirror_handler_internal(ngx_http_request_t *r) { ? ?ngx_str_t ? ? ? ? ? ? ? ? ? *name; ? ?ngx_uint_t ? ? ? ? ? ? ? ? ? i; ? ?ngx_http_request_t ? ? ? ? ?*sr; ? ?ngx_http_mirror_loc_conf_t ?*mlcf; ? ?mlcf = ngx_http_get_module_loc_conf(r, ngx_http_mirror_module); ? ?name = mlcf->mirror->elts; ? ?for (i = 0; i < mlcf->mirror->nelts; i++) { ? ? ? ?if (ngx_http_subrequest(r, &name[i], &r->args, &sr, NULL, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?NGX_HTTP_SUBREQUEST_BACKGROUND) ? ? ? ? ? ?!= NGX_OK) ? ? ? ?{ ? ? ? ? ? ?return NGX_HTTP_INTERNAL_SERVER_ERROR; ? ? ? ?} ? ? ? ?sr->header_only = 1; ? ? ? ?sr->method = r->method; ? ? ? ?sr->method_name = r->method_name; ? ?} ? ?return NGX_DECLINED; }
Nginx 有關 mirror 的代碼位于文件 src/http/modules/ngx_http_mirror_module.c
文件,上述為文件中的 ngx_http_mirror_handler_internal
函數.在開啟了 mirror 之后此函數會被執行,可見其內部主要通過 ngx_http_subrequest
發起 http 子請求來實現的.
通過代碼可見,Nginx 支持配置多個 mirror uri,示例為:
location / { ? ?mirror /mirror; ? ?mirror /mirror2; ? ?mirror_request_body off; ? ?proxy_pass http://127.0.0.1:9502; } location /mirror { ? ?internal; ? ?proxy_pass http://127.0.0.1:8081$request_uri; } location /mirror2 { ? ?internal; ? ?proxy_pass http://127.0.0.1:8081$request_uri; }
http://www.google.com
http://blog.csdn.net/xhjcehust/article/details/77093074
http://nginx.org/en/docs/http/ngx_http_mirror_module.html
文章來自微信公眾號:運維之美
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/1969.html