原:nginx请求转发问题

这段时间系统上出现一个很怪异现象,即生成很多重复订单,从生成时间上看,有同一时间的,也有相隔几分钟的。开始怀疑是程序上的问题,排查程序,没有找到问题原因。进而怀疑是nginx的配置问题,那么先需要证明这个怀疑。要证明这个怀疑就得找到--通过nginx的http请求与生成订单的关联,即客户端的一个请求,在nginx上被处理了两次。

办法:加日志。

1. nginx日志:加上客户端IP和请求会话的sessionid。

ip:使用Nginx作为反向代理时,后端应用服务器日志记录的客户端IP就不是真实的客户端IP,而是Nginx代理的IP。要解决这个问题可以在Nginx配置一个新的Header,用来存储$remote_add,然后获取记录这个值。

nginx配置:

 

location / {
            proxy_pass        http://test/;
            proxy_set_header        X-Real-IP $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header        Host $http_host;
        }

jboss配置:修改配置文件service.xml

 

<Valve className="org.apache.catalina.valves.AccessLogValve"
                prefix="localhost_access_log." suffix=".log"
                pattern="%h %{X-Real-IP}i %l %u %S %t %r %s %b" directory="${jboss.server.log.dir}" 
                resolveHosts="false" />

 

sessionid:

nginx配置:

 

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" "$http_cookie"';

 

OK,日志都配置好了,后面的日志分析就不具体写出来了。事实证明确实是nginx对于一个请求处理了两次,为什么呢,是这样的,系统有个后端平台经常响应超时,nginx有个机制对于time_out或者其他错误的请求响应会将请求再次转发到其他负载的机器上,这样一个正常的订单逻辑还在处理过程中,nginx认为超时了,重新转发了请求到另一台负载主机上,造成重复订单(其实程序上也有些问题,对于重复订单应该有控制)。

参见:官网说明

 

proxy_next_upstream
语法: proxy_next_upstream [error|timeout|invalid_header|http_500|http_503|http_404|off]

默认值: proxy_next_upstream error timeout

上下文: http, server, location

Directive determines, in what cases the request will be transmitted to the next server:

error — an error has occurred while connecting to the server, sending a request to it, or reading its response;
timeout — occurred timeout during the connection with the server, transfer the requst or while reading response from the server;
invalid_header — server returned a empty or incorrect answer;
http_500 — server returned answer with code 500
http_503 — server returned answer with code 503
http_404 — server returned answer with code 404
off — it forbids the request transfer to the next server
Transferring the request to the next server is only possible when nothing has been transferred to the client -- that is, if an error or timeout arises in the middle of the transfer of the request, then it is not possible to retry the current request on a different server.

在nginx层面有两种解决办法:一个是去掉这里的timeout这种情况,另一个是将这个模块关闭。

 

还有一种做法应该是可以延长超时时间,但是暂时不考虑。

 

 

 

猜你喜欢

转载自liu-g927.iteye.com/blog/1513309