题外话
该问题还是在公司项目终于到的,边记录下来分享一下。公司一个项目采用的前后端分离,前端在请求后端接口是,后端日志无法获取到请求的参数,进过查看代码日志也未发现请求参数,边考虑通过 nginx 的日志文件来处理。
配置前的记录信息
设置后的信息
两者对比
通过上面的对比,我们很容易看得出,后者多记录了一些请求参数。例如 content,type 等字段。这些都是 nginx 配置的 log 日志格式。第一张图是 nginx 默认的配置格式,我们完全可以自定义一些格式信息。配置一些我们需要的格式信息,边与我们排除错误,方便查看请求信息。
配置步骤
第一步、找到 nginx 的默认配置文件 nginx.conf 文件,在 http 配置段里面配置如下信息
1 | log_format是配置日志格式的前缀,固定 |
第二步、在域名配置文件中引用该配置信息
例如,我配置了一个 www.test.com.conf 的域名配置文件。在配置下面该项配置时,直接在后面加一个 main 即可。
1 | access_log /data/logs/nginx/www.test.com.log main; |
第三步、访问 www.test.com 的域名,查看/data/logs/nginx/www.test.com.log 该文件,即可看到类似与图二的信息。
nginx 的日志常见配置项
1 | args #请求中的参数值 |
nginx 代理处理
在实际的项目中,可能我们的请求可能会遇到一些代理服务器,这时候我们是无法获取到真实的客服端信息的。这就需要我们配置一些请求头信息。大致的原理就是,代理服务器和我们的服务器之间有一个默认的协议,代理服务器在向我们服务器发送请求的时候,实际会把真实的 ip 地址传递过来,只需要我们配置一些参数即可获取。(代理服务器大致的工作流程就是,客户端在请求我们的服务器时,先是去访问代理服务器,代理服务器在把这个请求转发给我们真实的服务器,真实的服务器在返回给代理服务器,会后客户端在从代理服务器获取到相关的数据信息)。下面实例择抄至网络。
正确设置 nginx 中 remote_addr 和 x_forwarded_for 参数
什么是 remote_addr?
remote_addr 代表客户端的 IP,但它的值不是由客户端提供的,而是服务端根据客户端的 ip 指定的,当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的 web 服务器(Nginx,Apache 等)就会把 remote_addr 设为你的机器 IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站,这样 web 服务器就会把 remote_addr 设为这台代理机器的 IP
什么是 x_forwarded_for?
正如上面所述,当你使用了代理时,web 服务器就不知道你的真实 IP 了,为了避免这个情况,代理服务器通常会增加一个叫做 x_forwarded_for 的头信息,把连接它的客户端 IP(即你的上网机器 IP)加到这个头信息里,这样就能保证网站的 web 服务器能获取到真实 IP
使用 HAProxy 做反向代理时
通常网站为了支撑更大的访问量,会增加很多 web 服务器,并在这些服务器前面增加一个反向代理(如 HAProxy),它可以把负载均匀的分布到这些机器上。你的浏览器访问的首先是这台反向代理,它再把你的请求转发到后面的 web 服务器,这就使得 web 服务器会把 remote_addr 设为这台反向代理的 IP,为了能让你的程序获取到真实的客户端 IP,你需要给 HAProxy 增加以下配置
1 | option forwardfor |
它的作用就像上面说的,增加一个 x_forwarded_for 的头信息,把客户端的 ip 添加进去,否则的话经测试为空值
如上面的日志格式所示:$http_x_forwarded_for 是客户端真实的IP地址,$remote_addr 是前端 Haproxy 的 IP 地址
或者:
当 Nginx 处在 HAProxy 后面时,就会把 remote_addr 设为 HAProxy 的 IP,这个值其实是毫无意义的,你可以通过 nginx 的 realip 模块,让它使用 x_forwarded_for 里的值。使用这个模块需要重新编译 Nginx,增加–with-http_realip_module 参数
1 | ./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module \ --with-http_realip_module --http-log-path=/data/logs/nginx/access.log --error-log-path=/data/logs/nginx/error.log |
1 | set_real_ip_from 10.1.10.0/24; |
上面的两行配置就是把从 10.1.10 这一网段过来的请求全部使用 X-Forwarded-For 里的头信息作为 remote_addr,这样此时 remote_addr 就是客户端真实的 IP 地址。
X-Forwarded-For 和 X-Real-IP 获取客户端的 ip 的区别:
一般来说,X-Forwarded-For 是用于记录代理信息的,每经过一级代理(匿名代理除外),代理服务器都会把这次请求的来源 IP 追加在 X-Forwarded-For 中 来自 4.4.4.4 的一个请求,header 包含这样一行 X-Forwarded-For: 1.1.1.1, 2.2.2.2, 3.3.3.3 代表 请求由 1.1.1.1 发出,经过三层代理,第一层是 2.2.2.2,第二层是 3.3.3.3,而本次请求的来源 IP 4.4.4.4 是第三层代理 而 X-Real-IP,一般只记录真实发出请求的客户端 IP,上面的例子,如果配置了 X-Read-IP,将会是 X-Real-IP: 1.1.1.1 所以 ,如果只有一层代理,这两个头的值就是一样的。
更多文章
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!