10分で作る Node.js Auto Scale 環境 with CloudFormation

Embed Size (px)

DESCRIPTION

東京Node学園 6時限目で発表した資料です。 http://connpass.com/event/611/

Citation preview

  • 1. Node.js Auto Scalingin 10 minuteswith AWS CloudFormation 2012/6/28 Node6@hakobera

2. QuestionAWSNode.js 3. Node.js1/ 1 => 417 => 7 => 1200 4. AWS 5. AWS EC2AMI (VM)Node.js ELBAuto ScaleCloudWatch Auto Scale Group DeployUpdate 6. AWS EC2AMI (VM)Node.js ELB orzAuto ScaleCloudWatch Auto Scale Group DeployUpdate 7. AWS CloudFormation http://aws.amazon.com/jp/cloudformation/ AWS JSON (Noder DynamoDBCloudFront 8. PaaS 9. Tempalte: https://cf-templates-for-nodejs.s3.amazonaws.com/cf-node-autoscale-tmpl.jsonApp: https://github.com/hakobera/tng6_sample/zipball/masterGitHub: https://github.com/hakobera/tng6_sample 10. Node.js CloudFormation Node.js AutoScaleElastic LoadBalancer Deploy UpdateWebSocket 11. Node.js 12. Node.js micro Node.js Installing Node.js via package managerhttps://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager $ sudo yum localinstall --nogpgcheck http://nodejs.tchol.org/repocfg/amzn1/nodejs-stable-release.noarch.rpm $ sudo yum install nodejs-compat-symlinks npm v0.8 13. Node.jsCloud Init "AppServerLaunchCong": {"Type" : "AWS::AutoScaling::LaunchConguration","Metadata": { "AWS::CloudFormation::Init": {"cong": { "packages": { "rpm" : { "nodejs" : "http://nodejs.tchol.org/repocfg/amzn1/nodejs-stable-release.noarch.rpm" }, "yum": { "gcc-c++": [], "make": [], "git" : [], "nodejs-compat-symlinks": [], "npm": [] } }, "sources" : { "/var/opt/app" : { "Ref": "AppURL" } }}, ... 14. Node.js Cloud Init "Properties": {"UserData": { "Fn::Base64": {"Fn::Base64": { "Fn::Join": ["", ["#!/bin/bash -vn","yum update -y aws-cfn-bootstrapn", "# Helper functionn", "function error_exitn", "{n", " /opt/aws/bin/cfn-signal -e 1 -r "$1" ", { "Ref": "WaitHandle" }, "n", " exit 1n", "}n", "# Install packagesn", "/opt/aws/bin/cfn-init -s ", { "Ref": "AWS::StackName" }, " -r AppServerLaunchCong ", " --access-key ", { "Ref": "HostKeys" }, " --secret-key ", { "Fn::GetAtt": ["HostKeys", "SecretAccessKey"] }, " --region ", { "Ref": "AWS::Region" }, " || error_exit Failed to run cfn-initn", 15. Auto Scale 16. Cloud Watch http://aws.amazon.com/jp/cloudwatch/ http://aws.amazon.com/jp/autoscaling/Auto Scale Cloud Watch CPUUtilization, DiskReadBytes, DiskReadOps, DiskWriteBytes, DiskWriteOps, NetworkIn, NetworkOut Node.js CPUUtilization NetworkOut OK 17. : CPUUtilization"AppServerScaleUpPolicy" : { "Type" : "AWS::AutoScaling::ScalingPolicy", "Properties" : { "AdjustmentType" : "ChangeInCapacity", "AutoScalingGroupName" : { "Ref" : "AppServerGroup" }, "Cooldown" : "60", "ScalingAdjustment" : "2" } }, "CPUAlarmHigh": {"Type": "AWS::CloudWatch::Alarm","Properties": {"AlarmDescription": "Scale-up if CPU > 90% for 10 minutes","MetricName": "CPUUtilization","Namespace": "AWS/EC2","Statistic": "Average","Period": "300","EvaluationPeriods": "2","Threshold": "90","AlarmActions": [ { "Ref": "AppServerScaleUpPolicy" } ],"Dimensions": [ { "Name": "AutoScalingGroupName", "Value": { "Ref": "AppServerGroup" } }], 18. Deploy Update 19. Deploy"AppServerLaunchCong": {"Type" : "AWS::AutoScaling::LaunchConguration","Metadata": {"AWS::CloudFormation::Init": { "sources" : {"/var/opt/app" : { "Ref": "AppURL" }}}, ... }},"Properties": {"UserData": {zipball tarball URL "Fn::Base64": {"Fn::Base64": {"Fn::Join": ["", ["# Start applicationn","cd /var/opt/appn","npm cong set PORT ", { "Ref": "AppServerPort" }, "n","npm install --productionn","NODE_ENV=production npm start > app.log 2>&1 &n",npm start OK 20. /**NPM package cong * Returns a value related by given key. * This method search following priority.NPM cong (global) *process.env * 1. NPM package cong * 2. NPM cong * 3. process.env * * @param {String} key Environment key * @param {String} [defaultValue] Default value if key not found. * @return {String} */module.exports = function (key, defaultValue) {var NPM_PACKAGE_PREFIX = npm_package_cong_;var NPM_PREFIX = npm_cong_;var value = process.env[NPM_PACKAGE_PREFIX + key];if (!value) {value = process.env[NPM_PREFIX + key];if (!value) {value = process.env[key];}}value = (!value && defaultValue) ? defaultValue : value;return value;}; 21. package.json { var http = require(http),"name": "harite", env = require(./env);"version": "0.1.0","scripts": { var server = http.createServer(function (req, res) {"start": "node app.js", res.writeHead(200, { Content-Type: text/plain });"test": "make test" res.end(hello);}, });"cong": { server.listen(env(PORT), function () {"PORT": 5100, console.log(Server is running on port %d, server.address().port);"REDIS_URL": "redis://localhost" });}}"npm cong set harite:HOST_NAME `curl http://169.254.169.254/latest/meta-data/public-hostname`", "n","npm cong set harite:PORT ", { "Ref": "HariteServerPort" }, "n","npm cong set harite:REDIS_URL ", { "Fn::Join" : [ "", [ "redis://", { "Fn::GetAtt" : [ "RedisServer", "PrivateIp" ]}, n","npm install --productionn", AWS CloudInit "NODE_ENV=production npm start > harite.log 2>&1 &n", http://d.hatena.ne.jp/sugyan/20110909/1315575343http://d.hatena.ne.jp/Jxck/20120410/1334071898 22. Github Branch zipball https://github.com/hakobera/tng6_sample/zipball/master 23. UpdateUpdate Stack =>LoadBalancer AutoScale zipball tarball URL API => 24. WebSocket 25. ELBHTTPHTTP1.1 UpdateWebSocket TCP (Socket.IO 60 Socket.IO or WebSocket AmazonELB http://d.hatena.ne.jp/Jxck/20120228/1330444857 26. AutoScaleAutoScale WebSocket EC2 27. WebSocket URL API ELB HTTPEC2 Public DNS curl http://169.254.169.254/latest/meta-data/public-hostname EC2 ELB WebSocket URLWebSocket 28. 29. Pusher https://github.com/hakobera/tuppari https://github.com/hakobera/tuppari-servers CloudFormation 30. Any Question ?