【问题标题】:node.js http server concurrency issuenode.js http服务器并发问题
【发布时间】:2013-12-22 00:03:00
【问题描述】:

每当我尝试连续发送快速HTTP Post时,服务器有时会崩溃(java.net.ConnectException:连接被拒绝:连接),有时会冻结(没有错误,但不能再使用它),有时会工作.. ..

如果我将 HTTP Post 缓慢地发送到服务器,似乎完全没有问题。

我在 node.js 中有一个 http 服务器的简单代码 - 我的猜测是有时 NodeJS 服务器会收到一个请求,然后在发出响应之前收到另一个请求,从而导致各种问题。如何让我的服务器能够同时接受多个请求?

var server = http.createServer(function (req, res) { 

     if (req.method != 'POST') {
          res.end();
     }
     else {
          req.on('data', function(chunk) {
               //Do some stuff here
               file1=JSON.parse(chunk.toString());
               console.log("Hello World") ;
          }

          req.on('end', function() {
               res.writeHead(200, "OK", {'Content-Type': 'text/html'});
               res.end();
          });
     }
} server.listen(9000);

编辑 这是发送 HTTP POSTS 的 java 程序

 public static String httpUrlRequest(String requestURL, String json) {
       URL url;
       String response = "";
       HttpURLConnection connection = null;
       InputStream is = null;
       try {
           url = new URL(requestURL);

           connection = (HttpURLConnection) url.openConnection();
           connection.setDoOutput(true);
           connection.setRequestMethod("POST");
           connection.getOutputStream().write(json.getBytes());
           connection.getOutputStream().flush();
           connection.getOutputStream().close();
           int code = connection.getResponseCode();
           System.out.println("code" + code);

       } catch (Exception e) {
           e.printStackTrace();
       } finally {
           connection.disconnect();
       }
       return response;
    }

    public static void main(String[] args) {
        Date date = new Date();
       Gson gson = new Gson();
       Map<String, Object> tempMap = gson.fromJson(json, new TypeToken<Map<String, Object>>(){}.getType());

       for(int i = 0; i < 10; i++){
           date = new Date();
           tempMap.put("GetOn", getDateString(date));
           httpUrlRequest("http://111.111.11.111:9000" ,gson.toJson(tempMap));
       }

    }

更新: 如果我在 nodejs 服务器中解析 JSON,那么有时我会收到连接被拒绝的错误。

所以当我解析请求数据时,由于某种原因,nodejs 无法接收到发送的整个 json 文件(5KB)。相反,它只收到一半,我的 Java 控制台显示连接错误。这个问题发生在 nodejs 正确解析大约 3 到 5 个请求之后。然后在下一个请求中,一切都出错了。如何判断是java断开连接导致只发送了一半的JSON,还是只发送了一半的JSON导致nodejs崩溃,最终导致连接错误。

如果我注释掉所有的解析,那么我就再也不会得到错误了。我什至不明白为什么 nodejs 中的 JSON.Parse 会引发 java 连接错误....

【问题讨论】:

  • 只有您正在使用的这个代码或任何其他代码?中间的代码块?
  • @AmGates 我在我的评论所在的地方做了一些 json 数据解析,但没有别的。
  • 您确定您的服务器没有耗尽资源吗?我很容易为您发布的代码获得 7000 个请求/秒。另外,“一些json数据解析”?您上传的数据有多大?
  • 可能是JSON数据解析有问题
  • 我得到的错误是 java.net.ConnectException: Connection refused: connect 。被解析的文件大约 5 KB

标签: java javascript node.js http concurrency


【解决方案1】:

你的问题在这里:

 req.on('data', function(chunk) {
   //Do some stuff here
   file1=JSON.parse(chunk.toString());
   console.log("Hello World") ;
 }

由于正文可以在多个数据包中发送,您可能会收到超过 1 个'data' 事件,从而尝试解析不完整的 JSON。试试这个:

var chunks = [];

req.on('data', function(chunk) {
  chunks.push(chunk);
}

req.on('end', function () {
  // assemble all chunks
  var body = Buffer.concat(chunks).toString(),
      file1 = JSON.parse(body);

  res.writeHead(200, "OK", {'Content-Type': 'text/html'});
  res.end();
});

【讨论】:

  • 我现在正为自己没有意识到请求数据是分块发送的。最让我失望的是,有时一个块包含整个 5KB 文件,有时它只包含一半 O_O
  • 现在我考虑得更多了。如果我每秒发送 1 个请求,则 5KB 会在一个块中传输。但是如果我在一秒钟内发送 10 个请求,它会决定拆分该块。为什么会这样-_-
【解决方案2】:

在这种测试期间,通过连接端口很容易达到最大吞吐量。

  1. http://www.slideshare.net/sh1mmer/a-million-connections-and-beyond-nodejs-at-scale
  2. https://groups.google.com/forum/#!topic/nodejs/cRRS7ZJkyzc

在运行 node.js 之前,简单的解决方案是 ulimit -n 100000。但是千万不要在生产中这样做,如果需要处理它,最好考虑使用集群来实现非常大的连接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-12
    • 2012-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-01
    • 1970-01-01
    • 2019-04-29
    相关资源
    最近更新 更多