Menyebarkan aplikasi Node.js Express dengan pengelompokan ke Elastic Beanstalk - AWS Elastic Beanstalk

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Menyebarkan aplikasi Node.js Express dengan pengelompokan ke Elastic Beanstalk

Tutorial ini memandu Anda melalui penerapan aplikasi sampel ke Elastic Beanstalk menggunakan Elastic Beanstalk Command CLI Line Interface (EB), dan kemudian memperbarui aplikasi untuk menggunakan framework Express, Amazon, dan clustering. ElastiCache Pengklasteran meningkatkan ketersediaan, performa, dan keamanan aplikasi web Anda yang tinggi. Untuk mempelajari lebih lanjut tentang Amazon ElastiCache, buka Apa itu Amazon ElastiCache (Memcached)? di Panduan Pengguna Amazon ElastiCache (Memcached).

catatan

Contoh ini menciptakan AWS sumber daya, yang mungkin dikenakan biaya untuk Anda. Untuk informasi lebih lanjut tentang AWS harga, lihathttps://aws.amazon.com/pricing/. Beberapa layanan adalah bagian dari Tingkat Penggunaan AWS Gratis. Jika Anda adalah pelanggan baru, Anda dapat menguji layanan ini secara gratis. Lihat https://aws.amazon.com/free/ untuk informasi selengkapnya.

Prasyarat

Tutorial ini membutuhkan prasyarat berikut:

  • Runtime Node.js

  • Perangkat lunak pengelola paket Node.js default, npm

  • Generator baris perintah Express

  • Antarmuka Baris Perintah Elastic Beanstalk (EB) CLI

Untuk detail tentang menginstal tiga komponen pertama yang terdaftar dan menyiapkan lingkungan pengembangan lokal Anda, lihatMenyiapkan lingkungan pengembangan Node.js Anda untuk Elastic Beanstalk. Untuk tutorial ini, Anda tidak perlu menginstal AWS SDK untuk Node.js, yang juga disebutkan dalam topik yang direferensikan.

Untuk detail tentang menginstal dan mengonfigurasi EBCLI, lihat Pasang Antarmuka Baris Perintah Elastic Beanstalk dan. Mengonfigurasi EB CLI

Membuat lingkungan Elastic Beanstalk

Direktori aplikasi Anda

Tutorial ini menggunakan direktori yang disebut nodejs-example-express-elasticache untuk bundel sumber aplikasi. Buat nodejs-example-express-elasticache direktori untuk tutorial ini.

~$ mkdir nodejs-example-express-elasticache
catatan

Setiap tutorial dalam chapter ini menggunakan direktorinya sendiri untuk bundel sumber aplikasi. Nama direktori cocok dengan nama aplikasi sampel yang digunakan oleh tutorial.

Ubah direktori kerja Anda saat ini menjadinodejs-example-express-elasticache.

~$ cd nodejs-example-express-elasticache

Sekarang, mari kita mengatur lingkungan Elastic Beanstalk yang menjalankan platform Node.js dan aplikasi sampel. Kita akan menggunakan antarmuka baris perintah Elastic Beanstalk (EB). CLI

Untuk mengonfigurasi CLI repositori EB untuk aplikasi Anda dan membuat lingkungan Elastic Beanstalk yang menjalankan platform Node.js
  1. Buat repositori dengan perintah eb init.

    ~/nodejs-example-express-elasticache$ eb init --platform node.js --region <region>

    Perintah ini membuat file konfigurasi dalam folder bernama .elasticbeanstalk yang menentukan pengaturan dalam membuat lingkungan untuk aplikasi Anda, dan membuat sebuah aplikasi Elastic Beanstalk yang diambil dari nama folder saat ini.

  2. Buat lingkungan yang menjalankan aplikasi sampel dengan perintah eb create.

    ~/nodejs-example-express-elasticache$ eb create --sample nodejs-example-express-elasticache

    Perintah ini membuat lingkungan yang seimbang beban dengan pengaturan default untuk platform Node.js dan sumber daya berikut:

    • EC2instance — Mesin virtual Amazon Elastic Compute Cloud (AmazonEC2) yang dikonfigurasi untuk menjalankan aplikasi web pada platform yang Anda pilih.

      Setiap platform menjalankan satu set perangkat lunak, file konfigurasi dan penulisan tertentu untuk mendukung versi bahasa, kerangka kerja, kontainer web tertentu, atau kombinasi dari semua ini. Sebagian besar platform menggunakan Apache atau NGINX sebagai proxy terbalik yang berada di depan aplikasi web Anda, meneruskan permintaan ke sana, menyajikan aset statis, dan menghasilkan akses dan log kesalahan.

    • Grup keamanan instans — Grup EC2 keamanan Amazon yang dikonfigurasi untuk memungkinkan lalu lintas masuk pada port 80. Sumber daya ini memungkinkan HTTP lalu lintas dari penyeimbang beban mencapai EC2 instance yang menjalankan aplikasi web Anda. Secara default, lalu lintas tidak diizinkan di port lain.

    • Penyeimbang beban – Penyeimbang beban Elastic Load Balancing yang dikonfigurasi untuk mendistribusikan permintaan ke instans yang menjalankan aplikasi Anda. Penyeimbang beban juga menghilangkan kebutuhan untuk mengekspos instans Anda langsung ke internet.

    • Grup keamanan penyeimbang beban - Grup EC2 keamanan Amazon yang dikonfigurasi untuk memungkinkan lalu lintas masuk di port 80. Sumber daya ini memungkinkan HTTP lalu lintas dari internet mencapai penyeimbang beban. Secara default, lalu lintas tidak diizinkan di port lain.

    • Grup Auto Scaling – Grup Auto Scaling yang dikonfigurasi untuk menggantikan instans jika diakhiri atau menjadi tidak tersedia.

    • Bucket Amazon S3 – Lokasi penyimpanan untuk kode sumber, log, dan artifact lainnya yang dibuat saat Anda menggunakan Elastic Beanstalk.

    • CloudWatch Alarm Amazon — Dua CloudWatch alarm yang memantau beban pada instans di lingkungan Anda dan yang dipicu jika beban terlalu tinggi atau terlalu rendah. Saat alarm terpicu, grup Auto Scaling Anda akan menaikkan atau menurunkan skala sebagai respons.

    • AWS CloudFormation stack - Elastic AWS CloudFormation Beanstalk digunakan untuk meluncurkan sumber daya di lingkungan Anda dan menyebarkan perubahan konfigurasi. Sumber daya ditentukan di sebuah templat yang dapat Anda lihat di Konsol AWS CloudFormation.

    • Nama domain — Nama domain yang merutekan ke aplikasi web Anda dalam formulir subdomain.region.elasticbeanstalk.com.

      catatan

      Untuk meningkatkan keamanan aplikasi Elastic Beanstalk Anda, domain elasticbeanstalk.com terdaftar di Daftar Akhiran Publik (). PSL Untuk keamanan lebih lanjut, kami menyarankan Anda menggunakan cookie dengan __Host- awalan jika Anda perlu mengatur cookie sensitif di nama domain default untuk aplikasi Elastic Beanstalk Anda. Praktik ini akan membantu mempertahankan domain Anda dari upaya pemalsuan permintaan lintas situs (). CSRF Untuk informasi selengkapnya, lihat halaman Set-Cookie di Jaringan Pengembang Mozilla.

  3. Saat pembuatan lingkungan selesai, gunakan eb openperintah untuk membuka lingkungan URL di browser default.

    ~/nodejs-example-express-elasticache$ eb open

Anda sekarang telah membuat lingkungan Elastic Beanstalk Node.js dengan aplikasi sampel. Anda dapat memperbaruinya dengan aplikasi Anda sendiri. Selanjutnya, kami memperbarui aplikasi sampel untuk menggunakan kerangka kerja Express.

Perbarui aplikasi untuk menggunakan Express

Memperbarui aplikasi sampel di lingkungan Elastic Beanstalk untuk menggunakan kerangka kerja Express.

Anda dapat mengunduh kode sumber akhir nodejs-example-express-elasticachedari.zip.

Memperbarui aplikasi Anda untuk menggunakan Express

Setelah Anda membuat lingkungan dengan aplikasi sampel, Anda dapat memperbaruinya dengan aplikasi Anda sendiri. Dalam prosedur ini, pertama-tama kita menjalankan npm install perintah express dan untuk mengatur kerangka kerja Express di direktori aplikasi Anda.

  1. Jalankan perintah express. Perintah menghasilkan package.json, app.js, dan beberapa direktori.

    ~/nodejs-example-express-elasticache$ express

    Saat diminta, ketik y jika Anda ingin melanjutkan.

    catatan

    Jika express perintah tidak berfungsi, Anda mungkin belum menginstal generator baris perintah Express seperti yang dijelaskan di bagian Prasyarat sebelumnya. Atau pengaturan jalur direktori untuk mesin lokal Anda mungkin perlu diatur untuk menjalankan express perintah. Lihat bagian Prasyarat untuk langkah-langkah rinci tentang pengaturan lingkungan pengembangan Anda, sehingga Anda dapat melanjutkan dengan tutorial ini.

  2. Persiapkan dependensi lokal.

    ~/nodejs-example-express-elasticache$ npm install
  3. (Opsional) Verifikasi server aplikasi web dimulai.

    ~/nodejs-example-express-elasticache$ npm start

    Anda akan melihat output yang serupa dengan yang berikut:

    > nodejs@0.0.0 start /home/local/user/node-express > node ./bin/www

    Server berjalan pada port 3000 secara default. Untuk mengujinya, jalankan curl http://localhost:3000 di terminal lain, atau buka browser di komputer lokal dan masukkan URL alamathttp://localhost:3000.

    Tekan Ctrl+C untuk menghentikan server.

  4. Ganti nama nodejs-example-express-elasticache/app.js ke nodejs-example-express-elasticache/express-app.js.

    ~/nodejs-example-express-elasticache$ mv app.js express-app.js
  5. Perbarui baris var app = express(); dalam nodejs-example-express-elasticache/express-app.js ke berikut ini:

    var app = module.exports = express();
  6. Di komputer lokal Anda, buat file bernama nodejs-example-express-elasticache/app.js dengan kode berikut.

    /** * 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;
  7. Ganti isi nodejs-example-express-elasticache/bin/www file dengan yang berikut ini:

    #!/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; }
  8. Terapkan perubahan ke lingkungan Elastic Beanstalk Anda dengan perintah. eb deploy

    ~/nodejs-example-express-elasticache$ eb deploy
  9. Lingkungan Anda akan diperbarui setelah beberapa menit. Setelah lingkungan hijau dan siap, segarkan URL untuk memverifikasi itu berfungsi. Anda akan melihat halaman web yang bertuliskan "Selamat Datang di Express".

Anda dapat mengakses log untuk EC2 instance yang menjalankan aplikasi Anda. Untuk petunjuk tentang mengakses log Anda, lihat Melihat log dari EC2 instans Amazon di lingkungan Elastic Beanstalk Anda.

Selanjutnya, mari kita perbarui aplikasi Express untuk menggunakan Amazon ElastiCache.

Untuk memperbarui aplikasi Express Anda untuk menggunakan Amazon ElastiCache
  1. Di komputer lokal Anda, buat direktori .ebextensions di direktori tingkat atas paket sumber Anda. Dalam contoh ini, kami menggunakan nodejs-example-express-elasticache/.ebextensions.

  2. Buat file konfigurasi nodejs-example-express-elasticache/.ebextensions/elasticache-iam-with-script.config dengan snippet berikut. Untuk informasi lebih lanjut tentang file konfigurasi, lihat Node.js konfigurasi namespace. Ini membuat IAM pengguna dengan izin yang diperlukan untuk menemukan node elasticache dan menulis ke file kapan saja cache berubah. Anda juga dapat menyalin file nodejs-example-express-elasticachedari.zip. Untuk informasi lebih lanjut tentang ElastiCache properti, lihatContoh:ElastiCache.

    catatan

    YAMLbergantung pada lekukan yang konsisten. Cocokkan tingkat indentasi saat mengganti konten dalam file konfigurasi contoh dan pastikan bahwa editor teks Anda menggunakan spasi, bukan karakter tab, untuk indentasi.

    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
  3. Di komputer lokal Anda, buat file konfigurasi nodejs-example-express-elasticache/.ebextensions/elasticache_settings.config dengan cuplikan berikut untuk dikonfigurasi. ElastiCache

    option_settings: "aws:elasticbeanstalk:customoption": CacheNodeType: cache.t2.micro NumCacheNodes: 1 Engine: memcached NodeListPath: /var/nodelist
  4. Di komputer lokal Anda, ganti nodejs-example-express-elasticache/express-app.js dengan snippet berikut. File ini membaca daftar simpul dari disk (/var/nodelist) dan mengonfigurasi express untuk menggunakan memcached sebagai penyimpanan sesi jika ada simpul. File Anda akan terlihat seperti berikut.

    /** * 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); });
  5. Di komputer lokal Anda, perbarui package.json dengan konten berikut:

    "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": "*" }
  6. Jalankan npm install.

    ~/nodejs-example-express-elasticache$ npm install
  7. Men-deploy aplikasi yang diperbarui.

    ~/nodejs-example-express-elasticache$ eb deploy
  8. Lingkungan Anda akan diperbarui setelah beberapa menit. Setelah lingkungan Anda berwarna hijau dan siap, verifikasi apakah kode berfungsi.

    1. Periksa CloudWatch konsol Amazon untuk melihat ElastiCache metrik Anda. Untuk melihat ElastiCache metrik, pilih Metrik di panel kiri, lalu cari. CurrItems Pilih ElastiCache > Metrik Node Cache, lalu pilih node cache Anda untuk melihat jumlah item dalam cache.

      CloudWatch dashboard showing CurrItems metric for an ElastiCache node over time.
      catatan

      Pastikan Anda melihat wilayahnya sama dengan tempat Anda men-deploy aplikasi Anda.

      Jika Anda menyalin dan menempelkan aplikasi Anda URL ke browser web lain dan menyegarkan halaman, Anda akan melihat CurrItem jumlah Anda naik setelah 5 menit.

    2. Ambil snapshot log Anda. Untuk informasi selengkapnya tentang mendapatkan log kembali, lihat Melihat log dari EC2 instans Amazon di lingkungan Elastic Beanstalk Anda.

    3. Memeriksa file /var/log/nodejs/nodejs.log dalam paket log. Anda akan melihat sesuatu yang serupa dengan yang berikut:

      Using memcached store nodes: [ 'aws-my-1oys9co8zt1uo.1iwtrn.0001.use1.cache.amazonaws.com:11211' ]

Pembersihan

Jika aplikasi tidak ingin dijalankan, Anda dapat membersihkan dengan mengakhiri lingkungan dan menghapus aplikasi Anda.

Gunakan perintah eb terminate untuk mengakhiri lingkungan Anda dan perintah eb delete untuk menghapus aplikasi Anda.

Untuk mengakhiri lingkungan Anda

Dari direktori tempat Anda membuat repositori lokal, jalankan eb terminate.

$ eb terminate

Proses ini dapat menghabiskan waktu beberapa menit. Elastic Beanstalk menampilkan pesan setelah lingkungan berhasil diakhiri.