问题
最近在重构一个服务 , 为了在不影响目前正在运行的服务情况下 , 我用了 nginx 的 mirror 模块来观察和测试重构的服务 . 但是在比对新服务和老服务之间的 access_log 时 , 发现 mirror 的 access_log 丢失了一部分 . 在 google 后发现目前没人遇到和我同样的问题 ,所以这个问题特此记录下 .
mirror 模块如何配置 access_log
在解决这个问题之前我们先看看如何在 mirror 模块中配置 access_log 的 .
在 mirror 下是不能直接配置 access_log 的 , 一开始我还不知道 , nginx 的配置检测也通过了 , 但是就是不记录日志 . 错误的配置方式如下
1
2
3
4
5
6
7
8
9
10
11
|
location /max {
access_log logs/max.log;
mirror /mirror;
default_type text/html;
return 200;
}
location /mirror {
access_log logs/mirror.log;
default_type text/html;
return 200;
}
|
我想实现的效果是在访问 /max 时会同时在 max.log 和 mirror.log 产生两条记录 . 可惜这种直观的方式不行 .
但是我们可以使用在 mirror 中使用反向代理 , 在代理的配置块中配置 access_log , 这种配置方式如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
server {
listen 80;
location /max {
access_log logs/max.log;
mirror /mirror;
default_type text/html;
return 200;
}
location /mirror {
proxy_pass http://127.0.0.1:10901$request_uri;
}
}
server {
listen 127.0.0.1:10901;
location /mirror {
default_type text/html;
access_log logs/mirror.log;
return 200;
}
}
|
排查
在对比两份 access_log 的过程中 , 我发现 mirror 丢失的都是 post 请求 , 并且这些请求的 request body 都比较大 , 大到一个请求记录一屏都放不下 . 所以怀疑是不是 client_max_body_size 配置的问题 . 看了配置文件后发现 nginx 源请求的 client_max_body_size 的值是 100m , mirror 没有配置该项 , 默认值是 1m . 感觉大概率是由于 mirror 的 max_body 太小导致的 . 但是一般来说 request body 的大小超过 client_max_body_size 肯定会返回 413 的状态码 , 而不是直接就丢失 access_log 的记录 , 所以我尝试在本地环境能不能复现 .
复现
本地 nginx 的配置文件如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
server {
listen 80;
location /max {
access_log logs/max.log;
mirror /mirror;
client_max_body_size 2k;
default_type text/html;
return 200;
}
location /mirror {
proxy_pass http://127.0.0.1:10901$request_uri;
}
}
server {
listen 127.0.0.1:10901;
location /mirror {
default_type text/html;
client_max_body_size 1k;
access_log logs/mirror.log;
return 200;
}
}
|
发送 body 很小的 request