HTTP状态码429的含义

2020-12-01 16:14:54

今天我写了一个很简单的nodejs应用,使用module request同时向jianshu网站发起数个异步请求,通过分页的方式向简书请求我所有的文章列表。

var request = require('request');var jsdom = require("jsdom");var JSDOM = jsdom.JSDOM;const PREFIX = "https://www.jianshu.com";const PAGE = "https://www.jianshu.com/u/99b8712e8850?order_by=shared_at&page=";const MAX = 100;var mArticleResult = new Map();var pageNumber;/* a given article: https://www.jianshu.com/p/963cd23fb092
  value got from API: /p/5c1d0319dc42
*/var lastPageReached = false;var url = "";var aHandlers = [];// use limited for loop to ease testingfor(var i = 0; i < MAX; i++){
  pageNumber = i + 1;
  var url = PAGE + pageNumber;
  // console.log("current page: " + url);
  var pageOptions = {
        url: url,
        method: "GET",
        headers: {
            "Accept": "text/html"
        }
  };
  aHandlers.push(getArticles(pageOptions, pageNumber));
  if( lastPageReached)
    break;}console.log("promise handler size: " + aHandlers.length);Promise.all(aHandlers).then(function(){
  var articleIndex = 0;
  for (var [key, value] of mArticleResult) {
    console.log("Article[" + articleIndex++ + "]: " + key + " = " + value);
  }
  console.log("done");}
  );function getArticles(pageOptions, pageNumber) {
  return new Promise(function(resolve,reject){
      var requestC = request.defaults({jar: true});

      requestC(pageOptions,function(error,response,body){
        if( error){
          console.log("error: " + error);
          resolve(error);
        }
        var document = new JSDOM(body).window.document;
        var content = document.getElementsByTagName("li");

        for( var i =0; i < content.length; i++){
          var li = content[i];
          var children = li.childNodes;
          for( var j = 0; j < children.length; j++){
              var eachChild = children[j];
              if( eachChild.nodeName == "DIV"){
                var grandChild = eachChild.childNodes;
                for( var k = 0; k < grandChild.length; k++){
                  var grand = grandChild[k];
                  if( grand.nodeName == "A"){
                    var fragment = grand.getAttribute("href");
                    if( fragment.indexOf("/p") < 0)
                      continue;
                    // console.log("title: " + grand.text);
                    var wholeURL = PREFIX + fragment;
                    // console.log("url: " + wholeURL);
                    if( mArticleResult.has(grand.text)){
                      lastPageReached = true;
                      console.log("article size: " + mArticleResult.size);
                      resolve(pageNumber);
                    }
                    mArticleResult.set(grand.text, wholeURL);
                  }
                }
              }
          }
        }// end of outer loop
        resolve(pageNumber);
      }); 
     });}

我观察到一个很奇怪的现象:

当我把下图变量MAX的值设成很小,比如10以下,意思是一次只发送10个以下的并发请求,此时这个nodejs应用工作完全正常。

然而当我把MAX改成100后,发现很多请求的数据并没有从jianshu网站上返回。经过调试发现,这些出问题的请求,接到的statusCode为429.

百度学习了一下429的含义:

当你需要限制客户端请求某个服务的数量,也就是限制请求速度时,该状态码就会非常有用。在此之前,有一些类似的状态码。例如“509 Bandwidth Limit Exceeded”。 因此我这个应用要么降低并发请求的发送频率,要么把异步并发请求改成同步。":


  • 2019-08-07 09:57:48

    spring data jpa 实体类中字段不与数据库表映射

    当我们使用spring data jpa开发的时候,会将实体类中的成员变量与表中的字段一一对应,当我们在实体类中加上一个不与数据库表一一对应的成员变量的时候,此时我们只要在这个成员变量上加上注解@Transient @

  • 2019-08-07 17:16:53

    如何在 Node.js 中使用 import / export 的三种方法

    因为一些历史原因,虽然 Node.js 已经实现了 99% 的 ES6 新特性,不过截止 2018.8.10,How To Enable ES6 Imports in Node.JS 仍然是老大难问题,下面我来介绍三种方法可以让我们在 Node.js 中使用 import/export 。

  • 2019-08-13 08:56:46

    nuxtjs组合element

    添加elementUI 插件,plugins->ele.js,代码如下

  • 2019-08-13 20:06:42

    修改 Nginx 进程最大可打开文件数(worker_processes和worker_connections)

    worker_processes:操作系统启动多少个工作进程运行Nginx。注意是工作进程,不是有多少个nginx工程。在Nginx运行的时候,会启动两种进程,一种是主进程master process;一种是工作进程worker process。例如我在配置文件中将worker_processes设置为4,启动Nginx后,使用进程查看命令观察名字叫做nginx的进程信息,我会看到如下结果:

  • 2019-08-14 09:01:18

    linux下高并发服务器实现

    在做网络服务的时候tcp并发服务端程序的编写必不可少。tcp并发通常有几种固定的设计模式套路,他们各有优点,也各有应用之处。下面就简单的讨论下这几种模式的差异:

  • 2019-08-14 13:18:59

    Linux系统下CPU使用(load average)梳理

    在平时的运维工作中,当一台服务器的性能出现问题时,通常会去看当前的CPU使用情况,尤其是看下CPU的负载情况(load average)。对一般的系统来说,根据cpu数量去判断。比如有2颗cup的机器。如果平均负载始终在1.2以下,那么基本不会出现cpu不够用的情况。也就是Load平均要小于Cpu的数量。

  • 2019-08-14 14:27:35

    计算密集型和IO密集型

    在进行I/O操作的时候,是将任务交给DMA来处理,请求发出后CPU就不管了,在DMA处理完后通过中断通知CPU处理完成了。I/O操作消耗的cpu时间很少.

  • 2019-08-14 14:29:12

    浅谈nodejs和php

    现在,Web开发公司和开发人员可以选择多种技术栈来构建Web应用程序。早期网络发展,不同的技术被用于前端和后端开发。但是,随着Node.js的发布,布局发生了变化,因为它允许开发人员使用 JavaScript 编写后端代码。这最终催生了MEAN(MongoDB + Express +AngularJS + NodeJS )堆栈 web 开发框架,从前端到后端甚至是数据库(MongoDB -JSON)都使用 JavaScript。在 Node.js 之前,Web 开发通常是在 PHP 的帮助下完成的,因为它很容易与 HTML 集成,帮助开发人员立即构建动态网站。在这篇文章中,我们将比较 Node.js 和 PHP,看哪一个最适合当前的行业需求。