Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
Déploiement d'une application Express avec une mise en cluster dans Elastic Beanstalk
Ce didacticiel explique comment déployer un exemple d'application sur Elastic Beanstalk à l'aide de l'CLIinterface de ligne de commande (EB) d'Elastic Beanstalk, puis comment mettre à jour l'application pour utiliser le framework Express, Amazon et le clustering. ElastiCache
Note
Cet exemple crée AWS des ressources qui peuvent vous être facturées. Pour plus d'informations sur la AWS tarification, consultezhttps://aws.amazon.com/pricing/
Prérequis
Ce tutoriel nécessite les prérequis suivants :
-
Les exécutions Node.js
-
Le logiciel de gestion des packages Node.js par défaut, npm
-
Le générateur de ligne de commande Express
-
L'interface de ligne de commande (EB) d'Elastic Beanstalk CLI
Pour plus d'informations sur l'installation des trois premiers composants et la configuration de votre environnement de développement local, consultez Configuration de votre environnement de développement Node.js. Pour ce didacticiel, il n'est pas nécessaire d'installer le fichier AWS SDK for Node.js, qui est également mentionné dans la rubrique référencée.
Pour plus de détails sur l'installation et la configuration de l'EBCLI, reportez-vous Installation de l'interface de ligne de commande EB aux sections etConfiguration de l'interface de ligne de commande EB.
Créer un environnement Elastic Beanstalk
Votre répertoire d'application
Ce tutoriel utilise un répertoire appelé nodejs-example-express-elasticache
pour la création de la solution groupée de l'application. Créez le répertoire nodejs-example-express-elasticache
pour ce tutoriel.
~$ mkdir nodejs-example-express-elasticache
Note
Chaque tutoriel de ce chapitre utilise son propre répertoire pour la solution groupée de l'application. Le nom du répertoire correspond au nom de l'exemple d'application utilisé par le tutoriel.
Changez votre répertoire de travail actuel vers nodejs-example-express-elasticache
.
~$ cd nodejs-example-express-elasticache
Configurons maintenant un environnement Elastic Beanstalk exécutant la plateforme Node.js et l'exemple d'application. Nous utiliserons l'interface de ligne de commande (EB) d'Elastic Beanstalk. CLI
Pour configurer un CLI référentiel EB pour votre application et créer un environnement Elastic Beanstalk exécutant la plateforme Node.js
-
Créez un référentiel à l'aide de la commande eb init.
~/nodejs-example-express-elasticache$
eb init --platform
node.js
--region<region>
Cette commande crée un fichier de configuration dans un dossier nommé
.elasticbeanstalk
qui spécifie les paramètres de création d'environnements pour votre application et crée une application Elastic Beanstalk dont le nom est basé sur le dossier actif. -
Créez un environnement qui exécute un exemple d'application à l'aide de la commande eb create.
~/nodejs-example-express-elasticache$
eb create --sample
nodejs-example-express-elasticache
Cette commande crée un environnement à charge équilibrée avec les paramètres par défaut de la plateforme Node.js et les ressources suivantes :
-
EC2instance — Une machine virtuelle Amazon Elastic Compute Cloud (AmazonEC2) configurée pour exécuter des applications Web sur la plateforme de votre choix.
Chaque plateforme exécute un ensemble spécifique de logiciels, de fichiers de configuration et de scripts pour prendre en charge une version de langage, une infrastructure ou un conteneur web spécifiques, ou une combinaison de ces éléments. La plupart des plateformes utilisent Apache ou NGINX un proxy inverse qui se trouve devant votre application Web, lui transmet les demandes, fournit des ressources statiques et génère des journaux d'accès et d'erreurs.
-
Groupe de sécurité d'instance : groupe EC2 de sécurité Amazon configuré pour autoriser le trafic entrant sur le port 80. Cette ressource permet au HTTP trafic provenant de l'équilibreur de charge d'atteindre l'EC2instance qui exécute votre application Web. Par défaut, le trafic n'est pas autorisé sur les autres ports.
-
Équilibreur de charge – Équilibreur de charge Elastic Load Balancing configuré pour répartir les demandes vers les instances exécutant votre application. De plus, l'équilibreur de charge vous évite d'exposer directement vos instances sur Internet.
-
Groupe de sécurité d'équilibrage de charge : groupe EC2 de sécurité Amazon configuré pour autoriser le trafic entrant sur le port 80. Cette ressource permet au HTTP trafic provenant d'Internet d'atteindre l'équilibreur de charge. Par défaut, le trafic n'est pas autorisé sur les autres ports.
-
Groupe Auto Scaling – Groupe Auto Scaling configuré pour remplacer une instance si elle est résiliée ou devient indisponible.
-
Compartiment Amazon S3 – Emplacement de stockage pour votre code source, les journaux et autres artefacts qui sont créés lorsque vous utilisez Elastic Beanstalk.
-
CloudWatch Alarmes Amazon : deux CloudWatch alarmes qui surveillent la charge sur les instances de votre environnement et qui sont déclenchées si la charge est trop élevée ou trop faible. Lorsqu'une alarme est déclenchée, votre groupe Auto Scaling s'adapte en fonction, à la hausse ou à la baisse.
-
AWS CloudFormation stack — Elastic AWS CloudFormation Beanstalk utilise pour lancer les ressources de votre environnement et propager les modifications de configuration. Les ressources sont définies dans un modèle, que vous pouvez afficher dans la console AWS CloudFormation
. -
Nom de domaine : nom de domaine qui permet d'accéder à votre application Web sous la forme
subdomain
.region
.elasticbeanstalk.com.Note
Pour renforcer la sécurité de vos applications Elastic Beanstalk, le domaine elasticbeanstalk.com est enregistré dans la liste des suffixes publics (). PSL
Pour plus de sécurité, nous vous recommandons d'utiliser des cookies avec un préfixe __Host-
si vous devez définir des cookies sensibles dans le nom de domaine par défaut de vos applications Elastic Beanstalk. Cette pratique vous aidera à défendre votre domaine contre les tentatives de falsification de requêtes intersites ()CSRF. Pour plus d'informations, consultez la page Set-Cookiedu Mozilla Developer Network.
-
-
Lorsque la création de l'environnement est terminée, utilisez la eb opencommande pour ouvrir l'environnement URL dans le navigateur par défaut.
~/nodejs-example-express-elasticache$
eb open
Vous avez maintenant créé un environnement Node.js Elastic Beanstalk avec un exemple d'application. Vous pouvez le mettre à jour avec votre propre application. Ensuite, nous mettons à jour l'exemple d'application afin d'utiliser l'infrastructure Express.
Mise à jour de l'application pour utiliser Express
Mettez à jour l'exemple d'application dans l'environnement Elastic Beanstalk pour utiliser le cadre Express.
Vous pouvez télécharger le code source final depuis le nodejs-example-express-elasticachefichier .zip.
Pour mettre à jour votre application afin d'utiliser Express
Une fois que vous avez créé un environnement avec un exemple d'application, vous pouvez le mettre à jour à l'aide de votre propre application. Dans cette procédure, nous exécutons d'abord les commandes express et npm install pour configurer le cadre Express dans votre répertoire d'application.
-
Exécutez la commande
express
. Il en résulte la génération depackage.json
,app.js
, et de quelques répertoires.~/nodejs-example-express-elasticache$
express
Lorsque vous êtes invité à continuer, tapez
y
.Note
Si la commande express ne fonctionne pas, il se peut que vous n'ayez pas installé le générateur de ligne de commande Express, comme décrit dans la section précédente sur les prérequis. Il se peut également que le chemin d'accès au répertoire de votre ordinateur local doive être configuré pour permettre l'exécution de la commande express. Consultez la section Prérequis pour connaître les étapes détaillées de la configuration de votre environnement de développement, afin de pouvoir poursuivre ce tutoriel.
-
Configurez les dépendances locales.
~/nodejs-example-express-elasticache$
npm install
-
(Facultatif) Vérifiez que le serveur de l'application web démarre.
~/nodejs-example-express-elasticache$
npm start
Vous devez voir des résultats similaires à ce qui suit :
> nodejs@0.0.0 start /home/local/user/node-express > node ./bin/www
Par défaut, le serveur s'exécute sur le port 3000. Pour le tester, lancez-le
curl http://localhost:3000
dans un autre terminal ou ouvrez un navigateur sur l'ordinateur local et entrez URL l'adressehttp://localhost:3000
.Appuyez sur Ctrl+C afin d'arrêter le serveur.
-
Renommez
nodejs-example-express-elasticache/app.js
ennodejs-example-express-elasticache/express-app.js
.~/nodejs-example-express-elasticache$
mv
app.js express-app.js
-
Mettez à jour la ligne
var app = express();
dansnodejs-example-express-elasticache/express-app.js
avec les éléments suivants :var app = module.exports = express();
-
Sur votre ordinateur local, créez un fichier nommé
nodejs-example-express-elasticache/app.js
avec le code suivant./** * Module dependencies. */ const express = require('express'), session = require('express-session'), bodyParser = require('body-parser'), methodOverride = require('method-override'), cookieParser = require('cookie-parser'), fs = require('fs'), filename = '/var/nodelist', app = express(); let MemcachedStore = require('connect-memcached')(session); function setup(cacheNodes) { app.use(bodyParser.raw()); app.use(methodOverride()); if (cacheNodes.length > 0) { app.use(cookieParser()); console.log('Using memcached store nodes:'); console.log(cacheNodes); app.use(session({ secret: 'your secret here', resave: false, saveUninitialized: false, store: new MemcachedStore({ 'hosts': cacheNodes }) })); } else { console.log('Not using memcached store.'); app.use(session({ resave: false, saveUninitialized: false, secret: 'your secret here' })); } app.get('/', function (req, resp) { if (req.session.views) { req.session.views++ resp.setHeader('Content-Type', 'text/html') resp.send(`You are session: ${req.session.id}. Views: ${req.session.views}`) } else { req.session.views = 1 resp.send(`You are session: ${req.session.id}. No views yet, refresh the page!`) } }); if (!module.parent) { console.log('Running express without cluster. Listening on port %d', process.env.PORT || 5000) app.listen(process.env.PORT || 5000) } } console.log("Reading elastic cache configuration") // Load elasticache configuration. fs.readFile(filename, 'UTF8', function (err, data) { if (err) throw err; let cacheNodes = [] if (data) { let lines = data.split('\n'); for (let i = 0; i < lines.length; i++) { if (lines[i].length > 0) { cacheNodes.push(lines[i]) } } } setup(cacheNodes) }); module.exports = app;
-
Remplacez le contenu du fichier
nodejs-example-express-elasticache/bin/www
par ce qui suit :#!/usr/bin/env node /** * Module dependencies. */ const app = require('../app'); const cluster = require('cluster'); const debug = require('debug')('nodejs-example-express-elasticache:server'); const http = require('http'); const workers = {}, count = require('os').cpus().length; function spawn() { const worker = cluster.fork(); workers[worker.pid] = worker; return worker; } /** * Get port from environment and store in Express. */ const port = normalizePort(process.env.PORT || '3000'); app.set('port', port); if (cluster.isMaster) { for (let i = 0; i < count; i++) { spawn(); } // If a worker dies, log it to the console and start another worker. cluster.on('exit', function (worker, code, signal) { console.log('Worker ' + worker.process.pid + ' died.'); cluster.fork(); }); // Log when a worker starts listening cluster.on('listening', function (worker, address) { console.log('Worker started with PID ' + worker.process.pid + '.'); }); } else { /** * Create HTTP server. */ let server = http.createServer(app); /** * Event listener for HTTP server "error" event. */ function onError(error) { if (error.syscall !== 'listen') { throw error; } const bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': console.error(bind + ' requires elevated privileges'); process.exit(1); break; case 'EADDRINUSE': console.error(bind + ' is already in use'); process.exit(1); break; default: throw error; } } /** * Event listener for HTTP server "listening" event. */ function onListening() { const addr = server.address(); const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); } /** * Listen on provided port, on all network interfaces. */ server.listen(port); server.on('error', onError); server.on('listening', onListening); } /** * Normalize a port into a number, string, or false. */ function normalizePort(val) { const port = parseInt(val, 10); if (isNaN(port)) { // named pipe return val; } if (port >= 0) { // port number return port; } return false; }
-
Déployez les modifications dans votre environnement Elastic Beanstalk avec la commande eb deploy.
~/nodejs-example-express-elasticache$
eb deploy
-
Votre environnement est mis à jour au bout de quelques minutes. Une fois que l'environnement est vert et prêt, actualisez-le URL pour vérifier qu'il fonctionne. Vous devriez voir une page web indiquant « Welcome to Express ».
Vous pouvez accéder aux journaux des EC2 instances qui exécutent votre application. Pour plus d'informations sur l'accès à vos journaux, consultez Affichage des journaux des instances Amazon EC2 dans votre environnement Elastic Beanstalk.
Ensuite, mettons à jour l'application Express pour utiliser Amazon ElastiCache.
Pour mettre à jour votre application Express afin d'utiliser Amazon ElastiCache
-
Sur votre ordinateur local, créez un répertoire
.ebextensions
dans le répertoire de niveau supérieur de votre groupe source. Dans cet exemple, nous utilisonsnodejs-example-express-elasticache/.ebextensions
. -
Créez un fichier de configuration
nodejs-example-express-elasticache/.ebextensions/elasticache-iam-with-script.config
avec l'extrait suivant. Pour plus d'informations sur le fichier de configuration, consultez Espaces de noms de la configuration Node.js. Cela crée un IAM utilisateur avec les autorisations requises pour découvrir les nœuds Elasticache et écrit dans un fichier chaque fois que le cache change. Vous pouvez également copier le fichier depuis un fichier nodejs-example-express-elasticache.zip. Pour plus d'informations sur les ElastiCache propriétés, consultezExemple : ElastiCache.Note
YAMLrepose sur une indentation cohérente. Respectez le niveau de retrait lorsque vous remplacez du contenu dans un exemple de fichier de configuration et veillez à ce que votre éditeur de texte utilise des espaces, et non des caractères de tabulation, pour la mise en retrait.
Resources: MyCacheSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: "Lock cache down to webserver access only" SecurityGroupIngress: - IpProtocol: tcp FromPort: Fn::GetOptionSetting: OptionName: CachePort DefaultValue: 11211 ToPort: Fn::GetOptionSetting: OptionName: CachePort DefaultValue: 11211 SourceSecurityGroupName: Ref: AWSEBSecurityGroup MyElastiCache: Type: 'AWS::ElastiCache::CacheCluster' Properties: CacheNodeType: Fn::GetOptionSetting: OptionName: CacheNodeType DefaultValue: cache.t2.micro NumCacheNodes: Fn::GetOptionSetting: OptionName: NumCacheNodes DefaultValue: 1 Engine: Fn::GetOptionSetting: OptionName: Engine DefaultValue: redis VpcSecurityGroupIds: - Fn::GetAtt: - MyCacheSecurityGroup - GroupId AWSEBAutoScalingGroup : Metadata : ElastiCacheConfig : CacheName : Ref : MyElastiCache CacheSize : Fn::GetOptionSetting: OptionName : NumCacheNodes DefaultValue: 1 WebServerUser : Type : AWS::IAM::User Properties : Path : "/" Policies: - PolicyName: root PolicyDocument : Statement : - Effect : Allow Action : - cloudformation:DescribeStackResource - cloudformation:ListStackResources - elasticache:DescribeCacheClusters Resource : "*" WebServerKeys : Type : AWS::IAM::AccessKey Properties : UserName : Ref: WebServerUser Outputs: WebsiteURL: Description: sample output only here to show inline string function parsing Value: | http://`{ "Fn::GetAtt" : [ "AWSEBLoadBalancer", "DNSName" ] }` MyElastiCacheName: Description: Name of the elasticache Value: Ref : MyElastiCache NumCacheNodes: Description: Number of cache nodes in MyElastiCache Value: Fn::GetOptionSetting: OptionName : NumCacheNodes DefaultValue: 1 files: "/etc/cfn/cfn-credentials" : content : | AWSAccessKeyId=`{ "Ref" : "WebServerKeys" }` AWSSecretKey=`{ "Fn::GetAtt" : ["WebServerKeys", "SecretAccessKey"] }` mode : "000400" owner : root group : root "/etc/cfn/get-cache-nodes" : content : | # Define environment variables for command line tools export AWS_ELASTICACHE_HOME="/home/ec2-user/elasticache/$(ls /home/ec2-user/elasticache/)" export AWS_CLOUDFORMATION_HOME=/opt/aws/apitools/cfn export PATH=$AWS_CLOUDFORMATION_HOME/bin:$AWS_ELASTICACHE_HOME/bin:$PATH export AWS_CREDENTIAL_FILE=/etc/cfn/cfn-credentials export JAVA_HOME=/usr/lib/jvm/jre # Grab the Cache node names and configure the PHP page aws cloudformation list-stack-resources --stack `{ "Ref" : "AWS::StackName" }` --region `{ "Ref" : "AWS::Region" }` --output text | grep MyElastiCache | awk '{print $4}' | xargs -I {} aws elasticache describe-cache-clusters --cache-cluster-id {} --region `{ "Ref" : "AWS::Region" }` --show-cache-node-info --output text | grep '^ENDPOINT' | awk '{print $2 ":" $3}' > `{ "Fn::GetOptionSetting" : { "OptionName" : "NodeListPath", "DefaultValue" : "/var/www/html/nodelist" } }` mode : "000500" owner : root group : root "/etc/cfn/hooks.d/cfn-cache-change.conf" : "content": | [cfn-cache-size-change] triggers=post.update path=Resources.AWSEBAutoScalingGroup.Metadata.ElastiCacheConfig action=/etc/cfn/get-cache-nodes runas=root sources : "/home/ec2-user/elasticache" : "https://elasticache-downloads.s3.amazonaws.com/AmazonElastiCacheCli-latest.zip" commands: make-elasticache-executable: command: chmod -R ugo+x /home/ec2-user/elasticache/*/bin/* packages : "yum" : "aws-apitools-cfn" : [] container_commands: initial_cache_nodes: command: /etc/cfn/get-cache-nodes
-
Sur votre ordinateur local, créez un fichier de configuration
nodejs-example-express-elasticache/.ebextensions/elasticache_settings.config
avec l'extrait de code suivant à configurer. ElastiCacheoption_settings: "aws:elasticbeanstalk:customoption": CacheNodeType: cache.t2.micro NumCacheNodes: 1 Engine: memcached NodeListPath: /var/nodelist
-
Sur votre ordinateur local, remplacez
nodejs-example-express-elasticache/express-app.js
par l'extrait suivant. Ce fichier lit la liste des nœuds depuis le disque (/var/nodelist
) et configure Express de façon à utilisermemcached
comme magasin de sessions s'il existe des nœuds. Votre fichier doit se présenter comme suit :/** * Module dependencies. */ var express = require('express'), session = require('express-session'), bodyParser = require('body-parser'), methodOverride = require('method-override'), cookieParser = require('cookie-parser'), fs = require('fs'), filename = '/var/nodelist', app = module.exports = express(); var MemcachedStore = require('connect-memcached')(session); function setup(cacheNodes) { app.use(bodyParser.raw()); app.use(methodOverride()); if (cacheNodes) { app.use(cookieParser()); console.log('Using memcached store nodes:'); console.log(cacheNodes); app.use(session({ secret: 'your secret here', resave: false, saveUninitialized: false, store: new MemcachedStore({'hosts': cacheNodes}) })); } else { console.log('Not using memcached store.'); app.use(cookieParser('your secret here')); app.use(session()); } app.get('/', function(req, resp){ if (req.session.views) { req.session.views++ resp.setHeader('Content-Type', 'text/html') resp.write('Views: ' + req.session.views) resp.end() } else { req.session.views = 1 resp.end('Refresh the page!') } }); if (!module.parent) { console.log('Running express without cluster.'); app.listen(process.env.PORT || 5000); } } // Load elasticache configuration. fs.readFile(filename, 'UTF8', function(err, data) { if (err) throw err; var cacheNodes = []; if (data) { var lines = data.split('\n'); for (var i = 0 ; i < lines.length ; i++) { if (lines[i].length > 0) { cacheNodes.push(lines[i]); } } } setup(cacheNodes); });
-
Sur votre ordinateur local, mettez à jour
package.json
avec le contenu suivant :"dependencies": { "cookie-parser": "~1.4.4", "debug": "~2.6.9", "express": "~4.16.1", "http-errors": "~1.6.3", "jade": "~1.11.0", "morgan": "~1.9.1", "connect-memcached": "*", "express-session": "*", "body-parser": "*", "method-override": "*" }
-
Exécutez npm install.
~/nodejs-example-express-elasticache$
npm install
-
Déployez l'application mise à jour.
~/nodejs-example-express-elasticache$
eb deploy
-
Votre environnement est mis à jour au bout de quelques minutes. Une fois que votre environnement est prêt (il apparaît en vert), assurez-vous que le code a fonctionné.
-
Consultez la CloudWatch console Amazon
pour consulter vos ElastiCache statistiques. Pour afficher vos ElastiCache statistiques, sélectionnez Métriques dans le volet de gauche, puis recherchez CurrItems. Sélectionnez ElastiCache > Mesures du nœud de cache, puis sélectionnez votre nœud de cache pour afficher le nombre d'éléments contenus dans le cache. Note
Vérifiez que vous consultez bien la même région que celle dans laquelle vous avez déployé votre application.
Si vous copiez et collez votre application URL dans un autre navigateur Web et que vous actualisez la page, vous devriez voir votre CurrItem compte augmenter au bout de 5 minutes.
-
Prenez un instantané de vos journaux. Pour de plus amples informations sur la récupération des journaux, veuillez consulter Affichage des journaux des instances Amazon EC2 dans votre environnement Elastic Beanstalk.
-
Vérifiez le fichier
/var/log/nodejs/nodejs.log
dans le groupe des journaux. Le résultat devrait être similaire à ce qui suit :Using memcached store nodes: [ 'aws-my-1oys9co8zt1uo.1iwtrn.0001.use1.cache.amazonaws.com:11211' ]
-
Nettoyage
Si vous ne souhaitez plus exécuter votre application, vous pouvez effectuer un nettoyage en suspendant votre environnement et en supprimant votre application.
Utilisez la commande eb terminate
pour mettre votre environnement hors service et la commande eb delete
pour supprimer votre application.
Pour résilier votre environnement
Depuis le répertoire où vous avez créé votre référentiel local, exécutez eb terminate
.
$ eb terminate
Ce processus peut prendre quelques minutes. Elastic Beanstalk affiche un message une fois que l'environnement est arrêté.