• nginx代理后如何获取用户真实访问的ip,以及访问耗时接口是nginx报504问题处理



    前言

    1、工作中遇到记录用户访问记录的操作,随即想到记录一篇nginx代理后获取用户真实ip的文章
    2、访问耗时接口时nginx报504错误,记录nginx配置访问接口超时时间的操作。


    一、nginx代理后获取用户真实ip

    1.1、背景:

    在实际应用中,我们可能需要获取用户的ip地址,比如做异地登陆的判断,或者统计ip访问次数等,通常情况下我们使用 request.getRemoteAddr() 就可以获取到客户端ip,但是当我们使用了nginx 作为反向代理后,使用 request.getRemoteAddr() 获取到的就一直是nginx 服务器的ip的地址。

    1.2、解决办法

    一个请求肯定是可以分为请求头和请求体的,而我们客户端的IP地址信息一般都是存储在请求头里的。如果你的服务器有用Nginx做负载均衡的话,你需要在你的location里面配置X-Real-IP和X-Forwarded-For请求头。

    location /api {
                    limit_req zone=allipse burst=24000 nodelay;
                    add_header 'Access-Control-Allow-Origin' '*';
                    add_header 'Access-Control-Allow-Credentials' 'true';
                    add_header 'Access-Control-Allow-Headers' 'x-requested-with,content-type';
                    proxy_pass http://api;
                    proxy_set_header   Host    $host;
                    proxy_set_header   Remote_Addr    $remote_addr;  
                    proxy_set_header   X-Real-IP    $remote_addr;  //一层代理时是用户真实ip,二层代理时是第一台nginxip
                    proxy_set_header   X-Forwarded-For    $proxy_add_x_forwarded_for;//一层代理时没有值,多层代理里面会存储多个ip值,第一个值就是真实用户ip
           }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    1)proxy_set_header X-real-ip $remote_addr;

    在web服务器端获得用户的真实ip。

    但是,实际上要获得用户的真实ip,不是只有这一个方法,下面我们继续看。

    2)proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    我们先看看这里有个X-Forwarded-For变量,这是一个squid开发的,用于识别通过HTTP代理或负载平衡器原始IP一个连接到Web服务器的客户机地址的非rfc标准,如果有做X-Forwarded-For设置的话,每次经过proxy转发都会有记录,格式就是client1,
    proxy1,
    proxy2,以逗号隔开各个地址,由于他是非rfc标准,所以默认是没有的,需要强制添加,在默认情况下经过proxy转发的请求,在后端看来远程地址都是proxy端的ip
    。也就是说在默认情况下我们使用request.getAttribute(“X-Forwarded-For”)获取不到用户的ip,如果我们想要通过这个变量获得用户的ip

    1.3、例子

    有一个web应用,在它之前通过了两个nginx转发,www.linuxidc.com 即用户访问该web通过两台nginx。

    在第一台nginx中,使用

    proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for;

    现在的KaTeX parse error: Double subscript at position 12: proxy_add_x_̲forwarded_for变量…remote_addr,而$remote_addr的值是用户的ip,于是赋值以后,X-Forwarded-For变量的值就是用户的真实的ip地址了。

    到了第二台nginx,使用

    proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for;

    现在的KaTeX parse error: Double subscript at position 12: proxy_add_x_̲forwarded_for变量…remote_addr部分的值是上一台nginx的ip地址,于是通过这个赋值以后现在的X-Forwarded-For的值就变成了“用户的真实ip,第一台nginx的ip”,这样就清楚了吧。

    最后我们看到还有一个KaTeX parse error: Double subscript at position 7: http_x_̲forwarded_for变量…http_x_forwarded_for时会发现,web服务器端使用request.getAttribute(“X-Forwarded-For”)获得的值是null。如果想要通过request.getAttribute(“X-Forwarded-For”)获得用户ip,就必须先使用proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for;这样就可以获得用户真实ip。

    1.4、总结

    存:配置在nginx的location块中配置以下请求头
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    取:在后端通过request.getHeader("X-Real-IP ‘’),request.getHeader("X-Forwarded-For ‘’)

    结论:一层代理时是用户真实ip用X-Real-IP配置取就可以,二层代理时是第一台nginxip,一层代理时没有值,多层代理里面会存储多个ip值,第一个值就是真实用户ip,这时就得用 X-Forwarded-For

    二、访问耗时接口nginx报错504

    2.1、问题原因

    nginx响应超时,页面出现504 gateway time-out
    
    • 1

    这种情况多发生在用 nginx 做反向代理的时候,例如用 nginx 做反向代理转发某一个 swagger 接口,当访问接口时报错,状态码一般为 504 ,也就是代理超时的问题,一般是访问一个响应慢的接口超出我们nginx接口访问的默认超时时间了。

    2.2、解决办法

    Proxy 方式
    一般我们用的是 nginx 的 proxy 机制做反向代理,此时我们需要修改 nginx 配置文件 nginx.conf ,在 http 或者 server 段添加如下内容:

    large_client_header_buffers 4 16k;
    client_max_body_size 30m;
    client_body_buffer_size 128k;
    
    proxy_connect_timeout 90; #后端服务器连接的超时时间,发起握手等候响应超时时间
    proxy_send_timeout 90;  #后端服务器数据回传时间,就是在规定时间内后端服务器必须传完所有的数据
    proxy_read_timeout 90;  #连接成功后,等候后端服务器响应时间,其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间,页面等待服务器响应时间)
    proxy_buffers 4 32k;  #4是数量 32k是大小 该指令设置缓存区的大小和数量,从被代理的后端服务器取得的第一部分响应内容,会放置到这里,默认情况下,一个缓存区的大小等于内存页面大小,可能是4k也可能是8k取决于平台
    proxy_busy_buffers_size 64k; #nginx在收到服务器数据后,会分配一部分缓冲区来用于向客户端发送数据,这个缓存区大小由proxy_busy_buffers_size决定的。大小通常是proxy_buffers单位大小的两倍,官网默认是8k/16k
    
    proxy_temp_file_write_size 64k;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    然后重启 nginx ,一般超时问题就会解决了。

    Fastcgi 方式
    大多数情况下我们用的是 proxy 方式,但是有时候我们还会遇到 fastcgi 的方式,例如用 nginx 处理 php 页面的场景。其实处理方式类似,同样是修改 nginx 配置文件 nginx.conf ,在 http 或者 server 段添加如下内容:

    large_client_header_buffers 4 16k;
    client_max_body_size 30m;
    client_body_buffer_size 128k;
    fastcgi_connect_timeout 600 :指定连接到后端FastCGI的超时时间。
    fastcgi_send_timeout 600 :向FastCGI传送请求的超时时间。
    fastcgi_read_timeout 600 :指定接收FastCGI应答的超时时间。
    fastcgi_buffer_size 64k :指定读取FastCGI应答第一部分需要用多大的缓冲区,默认的缓冲区大小为。fastcgi_buffers指令中的每块大小,可以将这个值设置更小。
    fastcgi_buffers 4 64k :指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求,如果一个php脚本所产生的页面大小为256KB,那么会分配4个64KB的缓冲区来缓存,如果页面大小大于256KB,那么大于256KB的部分会缓存到fastcgi_temp_path指定的路径中,但是这并不是好方法,因为内存中的数据处理速度要快于磁盘。一般这个值应该为站点中php脚本所产生的页面大小的中间值,如果站点大部分脚本所产生的页面大小为256KB,那么可以把这个值设置为“8 32K”、“4 64k”等。
    fastcgi_busy_buffers_size 128k :建议设置为fastcgi_buffers的两倍,繁忙时候的buffer。
    fastcgi_temp_file_write_size 128k :在写入fastcgi_temp_path时将用多大的数据块,默认值是fastcgi_buffers的两倍,该数值设置小时若负载上来时可能报502BadGateway。
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    然后重启 nginx ,一般超时问题就会解决了。

    例子:
    在这里插入图片描述

    2.3、结论

    主要在http块或者具体的代理server块中添加如下配置增加接口响应超时时间

    proxy_connect_timeout 90; #后端服务器连接的超时时间,发起握手等候响应超时时间
    proxy_send_timeout 90; #后端服务器数据回传时间,就是在规定时间内后端服务器必须传完所有的数据
    proxy_read_timeout 90;

  • 相关阅读:
    python爬虫:JavaScript 混淆、逆向技术
    错误码:spark_error_00000004
    自建or用SaaS|ToB企业如何玩转官网数字化改造
    在印度,越来越多的女性游戏开发者参与其中
    金仓数据库KingbaseES客户端编程接口指南-Python(5. 程序示例)
    BGP的基本配置
    创建谷歌账号 绕过手机验证(2023.11亲测有效)
    摆脱繁杂工作:Appwrite 带你高效开发 | 开源日报 No.50
    【Qt】Qt下配置OpenCV
    贴纸拼词 —— 记忆化搜索 / 状压DP
  • 原文地址:https://blog.csdn.net/wei1359765074410/article/details/127683608