nginx mirror 流量镜像的具体使用
作者:lgq2016
流量镜像 (Traffic Mirroring),也称为流量影子 (Traffic Shadowing),是一种强大的、无风险的测试应用版本的方法,它将实时流量的副本发送给被镜像的服务。
采用这种方法,您可以搭建一个与原环境类似的环境以进行验收测试,从而提前发现问题。由于镜像流量存在于主服务关键请求路径带外,终端用户在测试全过程不会受到影响。
nginx_http_mirror_module模块特性
利用 mirror 模块,可以将线上实时流量拷贝至其他环境同时不影响源站请求的响应,因为 Nginx 会丢弃 mirror 的响应
mirror 模块可用于以下几个场景:
- 通过预生产环境测试来观察新系统对生产环境流量的处理能力
- 复制请求日志以进行安全分析
- 复制请求用于数据科学研究
将生产环境的流量拷贝到预上线环境或测试环境的好处:
- 可以验证功能是否正常,以及服务的性能;
- 用真实有效的流量请求去验证,又不用造数据,不影响线上正常访问;
- 这跟灰度发布还不太一样,镜像流量不会影响真实流量;
- 可以用来排查线上问题;
- 重构,假如服务做了重构,这也是一种测试方式;
Nginx的流量镜像是只复制镜像,发送到配置好的后端,但是后端响应返回到nginx之后,nginx是自动丢弃掉的,这个特性就保证了镜像后端的不管任何处理不会影响到正常客户端的请求。
错误的说法:复制的镜像请求和原始请求是相关联的,只要镜像请求没有处理完成,原始请求就会被阻塞。
经过测试,镜像 的接口很慢,或者500都不影响原始请求的响应。
Nginx 如何实现流量镜像
当请求到达 Nginx 时,如果 Nginx 开启了流量镜像功能,就会将请求复制一份,并根据 mirror location 中的配置来处理这份复制的请求。复制的镜像请求和原始请求是没有关联,镜像 的接口很慢,或者500都不影响原始请求的响应。
Nginx 流量镜像配置
upstream bd_interface { server 10.1.1.1:8080; check interval=3000 rise=2 fall=5 timeout=2000 type=http; check_http_send "HEAD / HTTP/1.0\r\n\r\n"; check_http_expect_alive http_2xx http_3xx http_4xx; } #镜像流量也可以负载均衡 upstream mirror_interface1 { server 10.2.1.1:9090; check interval=3000 rise=2 fall=5 timeout=2000 type=http; check_http_send "HEAD / HTTP/1.0\r\n\r\n"; check_http_expect_alive http_2xx http_3xx http_4xx; } #镜像流量也可以负载均衡 upstream mirror_interface2 { server 10.3.1.1:9090; check interval=3000 rise=2 fall=5 timeout=2000 type=http; check_http_send "HEAD / HTTP/1.0\r\n\r\n"; check_http_expect_alive http_2xx http_3xx http_4xx; } server { listen 80; server_name xxx; access_log logs/bd-interface.log access_json; charset utf8; client_max_body_size 800M; gzip on; gzip_min_length 5k; gzip_comp_level 8; gzip_types application/javascript text/css text/javascript image/jpeg image/gif image/png application/json; proxy_read_timeout 600s; proxy_connect_timeout 600s; proxy_send_timeout 600s; location / { mirror /mirror1; mirror /mirror2; #两份镜像 mirror_request_body on; proxy_http_version 1.1; proxy_pass http://bd_interface; proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 20; proxy_read_timeout 1000; proxy_send_timeout 300; proxy_buffer_size 64k; proxy_buffers 32 32k; proxy_busy_buffers_size 128k; } location /mirror1 { internal; #只有内部请求可以调用 proxy_pass http://127.0.0.1:10991$request_uri; #配置镜像日志,mirror本身不支持日志 proxy_set_header X-Original-URI $request_uri; } location /mirror2 { internal; #只有内部请求可以调用 proxy_pass http://127.0.0.1:10992$request_uri; #配置镜像日志,mirror本身不支持日志 proxy_set_header X-Original-URI $request_uri; } #状态监控 location /nginx_status { stub_status on; access_log off; } #状态监控 location /check_status { check_status; access_log off; } } server { listen 10992; server_name 127.0.0.1; client_max_body_size 800M; proxy_read_timeout 600s; proxy_connect_timeout 600s; proxy_send_timeout 600s; access_log logs/bd-interface.log access_json; location / { proxy_http_version 1.1; #流量和并发大时必须使用http1.1 proxy_pass http://mirror_interface2; } } server { listen 10991; server_name 127.0.0.1; client_max_body_size 800M; proxy_read_timeout 600s; proxy_connect_timeout 600s; proxy_send_timeout 600s; access_log logs/bd-interface.log access_json; location / { proxy_http_version 1.1;#流量和并发大时必须使用http1.1 proxy_pass http://mirror_interface1; } }
Nginx流量拷贝的注意事项
mirror_request_body/proxy_pass_request_body与Content-Length需配置一致。如果mirror_request_body或者proxy_pass_request_body设置为 off,则Content-Length必须设置为"",因为nginx(mirror_request_body)或tomcat(mirror_request_body)处理post请求时,会根据Content-Length获取请求体,如果Content-Length不为空,而由于mirror_request_body或者proxy_pass_request_body设置为off,处理方以为post有内容,当request_body中没有,处理方会一直等待至超时。mirror_request_body为off,nginx会报upstream请求超时;proxy_pass_request_body为off,tomcat会报异常。
案例一
最近某个机房a空间不够,考虑迁移到分公司的机房b,从当前机房a到新机房b有将近2000公里,往返时延41ms。而老机房a在内网环境下延小于1ms。拍脑袋计划使用nginx流量镜像双写到a和b两个机房,反向代理到a机房,镜像到b机房。先不说方案的问题,比如无法保证数据一致性。仅仅从流量复制来说就有问题。大流量高并发测试发现,nginx报400的错误,kafka客户端报超时的错误,并发稍微增加就会出现这两种报错,到b机房流量的吞吐量远不及a机房。
错误如下所示:
原因:
使用nginx mirror进行流量镜像,压测时发现,情况1(反向代理到机房a,流量镜像到机房b),kafka客户端报超时错误,nginx代理报400错误,推测主要原因是:到a机房延时1ms, 到b机房延时41ms, 在情况1时,假设a服务端每秒处理10个请求,b由于延时较长,导致请求一定程度的堆积(压测时发送的请求速度是以a的消费能力为准的,镜像到b只是顺带着做转发),结果就是b服务端每秒钟要处理的请求>10个,处理不过来抛出错误。
反向佐证,如果是情况2(直连b服务),情况3(只反向代理到b),情况4(反向代理到b,同时流量镜像到a),情况5(情况1在并发请求数较小时)都不会出现报错的问题。
参考文章
到此这篇关于nginx mirror 流量镜像的具体使用的文章就介绍到这了,更多相关nginx mirror 流量镜像内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!