4

我目前正在 nginx 后面运行一系列 Node.js express 应用程序。但是,尽管我的应用程序运行良好,但我现在在某些情况下会遇到间歇性 502 Bad Gateway 错误。

主要实例是用户尝试登录的地方。通常,第一次登录尝试会返回 502 错误(并且此错误将是瞬时的,而不是在延迟后发生),而随后的第二次尝试将正常处理,请求标头没有变化。

我检查了 nginx 和 express 的日志,似乎在第一个实例中,尽​​管细节相同,但第一次尝试返回 500 错误(正如在登录尝试错误的情况下所计划的那样)。然后这会在 nginx 中触发 502 错误。

Nginx 错误日志:

2013/10/21 19:32:57 [error] 8178#0: *32101 upstream prematurely closed connection while reading response header from upstream, client: 82.40.77.228, server: instok.net, request: "POST /login HTTP/1.1", upstream: "https://127.0.0.1:5001/login", host: "instok.net", referrer: "https://instok.net/"

Nginx 访问日志:

- [21/Oct/2013:19:32:57 +0000] "POST /login HTTP/1.1" 502 172 "https://instok.net/" "Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Firefox/24.0" "-"82.40.77.228 - 
- [21/Oct/2013:19:32:59 +0000] "POST /login HTTP/1.1" 200 5 "https://instok.net/" "Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Firefox/24.0" "-"82.40.77.228 - 

快速访问日志:

- [Mon, 21 Oct 2013 19:32:57 GMT] \"POST /login HTTP/1.0\" 500 69 \"https://instok.net/\" 
- [Mon, 21 Oct 2013 19:32:59 GMT] \"POST /login HTTP/1.0\" 200 - \"https://instok.net/\"

服务器端认证

function authenticate(name, pass, fn) {

  User.findOne({_id: name}, function(err, user) {
   if (!user) {  return fn(new Error("Cannot find user"))}; 

   bcrypt.compare(pass, user.hash, function(err, res){
     if (err || !res) { return fn(err) }

     else {
        return fn(null, user);
        }
    })
  })
}

exports.logIn = function(req, res){
 authenticate(req.body.username, req.body.password, function(err, user){
  if (user){
      req.session.regenerate(function(){
        req.session.user = user;
        res.status(200).send();
      })
  }
  else {
    res.status(500).send({message: "Error with username or password - please try again"})
  }

 });
}

我的 nginx.conf 文件的相关部分位于https://gist.github.com/grabbeh/6721046,我还使用同一文件运行其他几个 node.js 应用程序。

在客户端,我使用 Angular.js 和 $http.post 将登录详细信息发送到服务器,并根据服务器发回的 200 或 500 错误进行条件处理。

我还使用 routeChangeError 事件来重定向来自服务器的 500 错误,以重定向到尝试在登录之外访问路由的登录页面。但是我不认为客户端处理是相关的,因为错误是在任何客户端处理之前返回的。

很可能有一种更好的方法来处理身份验证,这当然可以解决上述问题,但是目前我想深入了解间歇性 502 错误。

该错误似乎确实源于 Express 返回 500,而它应该返回 200,但尽管使用了代码,但我无法确定问题所在。任何意见将不胜感激。应用程序本身运行在https://instok.net可以查看所有客户端代码的位置。

出于兴趣,502 和有效请求的详细信息如下:

502 有效请求

编辑

我缺少的一点是我使用https://github.com/nodejitsu/forever来保持应用程序在发生崩溃时运行。检查 Forever 日志后,很明显问题是连接到 MongoDB 数据库失败导致应用程序崩溃。此错误未在应用程序中捕获,因此据我了解,Express 日志中未引用此错误。现在已经解决了这个问题,而且我已经切换到另一个 MongoDB 实例,我希望它能解决问题。

4

1 回答 1

3

我相信我已经找到了问题,即由于 mongoose 无法连接到 MongoDB 实例而导致未捕获的错误。我现在已经处理了错误并将数据库切换到不同的实例。触摸木头,我目前没有任何进一步的问题。

于 2013-10-24T14:17:04.567 回答