Exporter son site Next.js sans se faire DDOSer

Paul Grieselhuber

Paul Grieselhuber

Jun 27, 2019

Voici la situation dans laquelle nous nous trouvions alors que nous approchions du lancement d'un site web à contenu volumineux alimenté par Next.js. Nous étions à environ 3 semaines du lancement et voulions commencer la configuration du serveur de production, le déploiement des tests, les exportations, etc.

Tout se passait bien jusqu'à ce que nous arrivions à la partie du déploiement concernant les exportations statiques de Next.js. Jusqu'à présent dans le projet, notre équipe avait toujours exécuté des tests d'exportation statique à partir de leurs machines de développement locales qui se trouvaient à une certaine distance physique du serveur de production. Suffisamment loin pour que les machines de développement ne risquent pas de surcharger le serveur de production (l'emplacement de l'API pour le projet).

Si vous essayez toujours de mettre en place des exportations statiques sur votre projet, consultez notre article détaillé sur le blog WPGraphQL .

L'erreur préférée de tous : 502

Presque aussitôt que nous avons lancé l'exportation depuis le même serveur que l'API, nos terminaux se sont remplis d'erreurs 502, en particulier :

Error while running `getMarkupFromTree` { Error: Network error: Unexpected token < in JSON at position 0
    at new ApolloError (/var/www/next/node_modules/apollo-boost/node_modules/apollo-client/bundle.umd.js:92:26)
    at /var/www/next/node_modules/apollo-boost/node_modules/apollo-client/bundle.umd.js:1581:34
    at /var/www/next/node_modules/apollo-boost/node_modules/apollo-client/bundle.umd.js:2001:15
    at Set.forEach (<anonymous>)
    at /var/www/next/node_modules/apollo-boost/node_modules/apollo-client/bundle.umd.js:1999:26
    at Map.forEach (<anonymous>)
    at QueryManager.broadcastQueries (/var/www/next/node_modules/apollo-boost/node_modules/apollo-client/bundle.umd.js:1997:20)
    at /var/www/next/node_modules/apollo-boost/node_modules/apollo-client/bundle.umd.js:1476:29
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:228:7)
  graphQLErrors: [],
  networkError:
   { ServerParseError: Unexpected token < in JSON at position 0
    at JSON.parse (<anonymous>)
    at /var/www/next/node_modules/apollo-link-http-common/lib/index.js:35:25
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:228:7)
     name: 'ServerParseError',
     response:
      Response {
        size: 0,
        timeout: 0,
        [Symbol(Body internals)]: [Object],
        [Symbol(Response internals)]: [Object] },
     statusCode: 502,
     bodyText: '<html>\r\n<head><title>502 Bad Gateway</title></head>\r\n<body bgcolor="white">\r\n<center><h1>502 Bad Gateway</h1></center>\r\n<hr><center>nginx/1.10.3 (Ubuntu)</center>\r\n</body>\r\n</html>\r\n' },
  message: 'Network error: Unexpected token < in JSON at position 0',
  extraInfo: undefined }

Il s'agissait d'une API WPGraphQL ( our review)), exécutée à partir d'un site Wordpress. Si vous avez construit des sites Wordpress à grande échelle pendant un certain temps, vous pouvez probablement deviner l'erreur que nous avons obtenue de PHP :

[error] 1248#1248: *5807411 connect() to unix:/run/php/php7.0-fpm.sock failed (11: Resource temporarily unavailable) while connecting to upstream, client: xxx.xxx.xxx.xxx, server: website.com, request: "GET /this/page HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.0-fpm.sock:", host: "www.website.com"

Si vous avez déjà rencontré une erreur 502 sur un site Wordpress, vous savez aussi que votre journée a été gâchée. Il existe un nombre quasi infini de causes auxquelles cette erreur peut renvoyer.

De-DDOS yourself

Après une discussion avec @p-k sur Spectrum (ht pour l'excellente recherche sur ce sujet), il est devenu clair que le problème est que le processus d'exportation de Next.js s'exécute sur plusieurs threads, et en raison de la proximité des applications et de la vitesse d'exécution, vous vous DDOSez vous-même à chaque fois que vous exportez votre site.

Comme nous prévoyons d'exporter plusieurs fois par jour au fur et à mesure que le contenu du site est mis à jour, cela n'aurait évidemment pas été possible. C'est également la raison pour laquelle nous ne construisons pas le site localement et déployons simplement le site exporté vers la production.

Nous devons donc demander à Next.js de s'exécuter sur moins de threads et avec une concurrence plus faible afin de réussir à construire ce site sur le serveur de production.

C'est assez facile : mettez à jour vos options package.json file, specifically the export script to include the --threads and --concurrency, par exemple :

{
  "scripts": {
    ...
    "export": "next export --threads 1 --concurrency 1",
    ...
  },
  ...
}

Cela devrait résoudre le problème, mais les temps d'exportation seront beaucoup plus lents. Les nôtres sont passés d'environ 10-12 minutes à environ 60 minutes. D'autres tests nous aideront à déterminer ce que l'API peut supporter en termes de threads supplémentaires et de concurrence plus élevée. En attendant, cela nous permet d'atteindre notre objectif de plusieurs constructions par jour.

Découvrez le prochain article de notre série sur la construction de sites statiques Next.js, Next.js + Multiple Apollo Clients & GraphQL Sources

Paul Grieselhuber

Paul Grieselhuber

Founder, President

Paul has extensive background in software development and product design. Currently he runs rendr.

Réservez un appel de découverte avec nos experts produits.

Notre équipe d'experts en applications web et mobiles est impatiente de discuter avec vous de votre prochain projet.

Réservez un appel 👋