问题描述
当我们使用下面的 nginx 配置部署 tornado 应用后
upstream frontends {server 127.0.0.1:8000;server 127.0.0.1:8001;server 127.0.0.1:8002;server 127.0.0.1:8003; }
在 tornado.log 中请求ip全部都会显示成 127.0.0.1 ,类似下面这样[I 130125 21:44:54 web:1447] 200 GET / (127.0.0.1) 16.00ms
如何在 nginx 反向代理的情况下让 tornado.log 中的ip地址也能显示成真实的ip呢?
正确答案:除了 nginx 配置正确, 更重要的是需要在 tornado httpserver 中设置 xheaders=Truetornado.httpserver.HTTPServer(Application(), xheaders=True)
问题解答
回答1:tornado中可以通过
self.request.remote_ip
来获取,不过可能有时候有些问题,见github上的这个issue:https://github.com/facebook/tornado/i...
原理是读一些HTTP头
类似的,PHP中的实现如下:
function _get_client_ip() { $clientip = ’’; if(getenv(’HTTP_CLIENT_IP’)&& strcasecmp(getenv(’HTTP_CLIENT_IP’), ’unknown’)) {$clientip = getenv(’HTTP_CLIENT_IP’); } elseif(getenv(’HTTP_X_FORWARDED_FOR’)&& strcasecmp(getenv(’HTTP_X_FORWARDED_FOR’), ’unknown’)) {$clientip = getenv(’HTTP_X_FORWARDED_FOR’); } elseif(getenv(’REMOTE_ADDR’)&& strcasecmp(getenv(’REMOTE_ADDR’), ’unknown’)) {$clientip = getenv(’REMOTE_ADDR’); } elseif(isset($_SERVER[’REMOTE_ADDR’])&& $_SERVER[’REMOTE_ADDR’]&& strcasecmp($_SERVER[’REMOTE_ADDR’], ’unknown’)) {$clientip = $_SERVER[’REMOTE_ADDR’]; } preg_match('/[d.]{7,15}/', $clientip, $clientipmatches); $clientip = $clientipmatches[0] ? $clientipmatches[0] : ’unknown’; return $clientip;}回答2:
如果是反向代理的话可以在nginx 中加入这么一个配置:proxy_pass http://frontends;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;