不同用户访问同一个Url时,如果他们应该根据自己的登录信息看到不同的内容,则Nginx有可能导致页面发送给错误的用户。即一个用户的页面让其他用户看到了,造成隐私泄漏。
对过程不感兴趣的朋友可以直接跳到步骤3.解决方案
1.问题起因
公司的网站使用两台Nginx做反向代理,两台2008Server+IIS7做后台。一段时间之前开始有用户抱怨说在进入自己的帐户页面时看到了不知道是谁的订单信息。但是只有在服务器十分繁忙的时候才会发生。
隐私问题一向很大条,所以在进行了一系列推断而得不到结果之后,不得不采取极端措施把Nginx临时从DNS解析中去掉,直接让IIS暴露在外。问题消失了,证明确实是Nginx的问题。
2.分析
这么严重的问题不要告诉我没人遇到过。于是一边上网搜索,一边在Nginx的邮件组里提问寻求解决方案。大失所望,真的没人遇到过。那新浪用这玩意儿怎么就不出问题呢?难道是版本问题?已经是最新的稳定版0.7.64了啊(现在到0.7.65了,还是存在同样的问题,即使最新的开发版0.8.33也还是)。又或者是人家财大气粗,服务器集群大得到不了繁忙的状况?无奈地研究了Nginx的各种编译参数,重新查看配置文档看是不是理解有误。还有改变配置,少用Worker个数等等,死了不少脑细胞,一无所获。开始盲目地进行各种测试看看能不能运气足够好地碰到解决方案。
最后的突破点在于找到了一个Bug重现的规律,就是在远程和局域网用我们自己人肉编写的压力测试工具会遇到这样一种状况:这个Bug并不是很容易重现,往往压力压了一阵才会出来。但是一旦出现之后就会反复出现,几率大了很多。这让我觉得这个问题跟proxy_cache有关。因为虽然我没有缓存那个页面,但是如果proxy_cache模块出了问题把它给存下来了,就确实会引发上面的现象,而且解释得通几率变大的问题。
试着把proxy_cache去掉,果然问题不出现了。又试着在出问题的时候在缓存文件夹中查找被缓存的是不是有出问题的页面。在一堆做过Hash的文件名里找一个文件不是很容易的事情。不过运气好没两下就让我碰到了,真的在!
先来看看之前的配置文件
大意是遇到aspx和ashx则不缓存,其他的通通缓存。现在换了个思路,
遇到静态内容缓存,其他内容通通不缓存。效果一样,但是问题就不存在了。个人怀疑是个proxy_cache的bug,邮件组也有人同意我的看法。所以遇到同样问题的朋友们不妨也试试这招管不管用吧。