Git Product home page Git Product logo

galaxy-autoscale's Introduction

Depreciated

After updating my Meteor application to 1.6.x, I could not longer get phantom-js and webdriverio running properly to perform scaling operations on Galaxy. I tested using puppeteer as a replacement, and it was running locally but unable to properly start up on Galaxy instances.

Rather than spend additional time working around Galaxy's shortcomings, I transitioned my application to AWS using MUP where I'm getting massively better performance at a lower cost. I wrote a post on the issues I encountered while transitioning and the overall benefits of being on AWS.

If you still want to use this package, v2.2.0 should still work with Meteor 1.5.x, and I'd be happy to accept PR's and help provide support if someone is still relying on this package, but I am no longer using it myself.

For more discussion see #4.


A package to allow a Meteor app deployed on Meteor Galaxy to determine current usage and adjust the number of running containers.

Since there is no API to access this information, this package uses phantomjs and webdriverio to scrape the information and interact with the Meteor Galaxy portal.

Quickstart

Install the package

meteor add avariodev:galaxy-autoscale

Create the following file somewhere where it will only be loaded on the server /imports/server/galaxy-autoscale.js

import { GalaxyAutoScale } from 'meteor/avariodev:galaxy-autoscale';

Meteor.startup(() => {
  GalaxyAutoScale.config({
    appUrl: Meteor.settings.galaxy.appUrl,
    username: Meteor.settings.galaxy.username,
    password: Meteor.settings.galaxy.password,
    scalingRules: {
      containersMin: 1,
      containersMax: 3,
      connectionsPerContainerMax: 80,
      connectionsPerContainerMin: 40,
    },
    alertRules: {
      cpuPercentageMax: 80,
    },
  });

  GalaxyAutoScale.addSyncedCronJob();

  GalaxyAutoScale.startSyncedCron();
});

Updating to V3.0.0

Phantomjs-prebuilt and webdriverio were removed and replaced by puppeteer. You can remove phantomjs-prebuilt and webdriverio from your existing project, as puppeteer properly works with Npm.depends.

Screenshots of Auto-Scaling in Action

Galaxy APM graphs of up-scaling with steadily rising connections autoscale-graph

Meteor Galaxy log of down-scaling autoscale-logs

Important Note if Already Using Synced-Cron

This package uses percolate:synced-cron to manage the timing of running the script, along with ensuring the script only gets run once per interval in a multiple-server deployment.

If you are already using synced-cron in your app, then do not run GalaxyAutoScale.start(); as that is simply a wrapper around SyncedCron.start().

Configuration Information

appUrl

This should be the entire URL used to access your apps Galaxy management page, such as https://galaxy.meteor.com/app/www.yourapp.com.

V2.0.0 and earlier only used appName, which assumed https://galaxy.meteor.com/app/ only allowing the package to work in us-east-1. This was left in for compatibility.

Scaling logic

Eventually I may add in better CPU/Memory based scaling, but since those numbers are more dynamic, I went with number of connections to start out.

The script does some basic math to calculate stats not provided by the Galaxy page:

  • The overall CPU percentage being used (not currently used)

    • Total CPU ECU used / (# of containers * ECU per container)
  • The overall connections per container

    • Number of connections / number of containers

containersMin/containersMax

It will not scale above/below these numbers.

connectionsPerContainerMax

Once the connections per container reaches this number, it will add a single container.

connectionsPerContainerMin

Once the connections per container reaches this number, it will remove a single container.

Scaling Interval

By default it runs every 15 minutes. To change this, add an interval value to the config. This interval value is passed to synced-cron which uses the later.js library.

GalaxyAutoScale.config({ interval: 'every 15 minutes' });

Manual Scaling Execution

If for whatever reason you want to manually run the auto-scaling script, call GalaxyAutoScale.runAutoScale(). Ensure you set your config settings first.

Logging

By default it will log to console, you can disable logging by setting GalaxyAutoScale.config({ log: false }), or you can pass a custom logger in which it will use. For example:

const loggerWrapper = ({ level, message }) => {
  myWinstonLogger.log(level, message);
};

Meteor.startup(() => {
  GalaxyAutoScale.config({
    ...
    logger: loggerWrapper,
  });
  ...
});

alertRules

Basic checks to configure warning log notifications. Currently the only rule created is cpuPercentageMax, if the overall cpu percentage used exceeds this, a log even with severity warn will be created, allowing for automatic notifications if your log stream is configured for that.

Troubleshooting

MUP deployment failure - Insufficient Memory

If you get an error during the MUP deploy process and it's not clear what is going wrong, you probably don't have enough memory on the server to complete the install. When deploying with my relatively small project, the install would fail at the phantomjs install script with a cryptic 137 error if the server only had 512 MB of memory, it needed at least 1 GB to complete the install.

If you want to run a maintenance server on as small a server as possible, you can deploy to a 1 GB server and then downsize it after the install script is completed. I was able to run this on a 512 MB t2.nano AWS EC2 instance.

Alternative to running as Meteor package

While working out how to do this, I started with a standalone scrip that can be run on Node. I set up a nano AWS EC2 instance, set the script to run with cron, and it works just fine. If you want to keep this browser scraping script out of your webserver, than you can set it up that way.

After running the script on a Galaxy compact container with zero connections, CPU went to about 90% (0.4 ECU) and memory up by ~90MB for the 30 seconds this was running, so it does cause a brief impact on your webserver. On the other hand, if you are auto-scaling then you should always have some extra capacity, right? :D

Tests

First ensure dependencies are installed with npm install and then run the tests with npm test.

autoscale-tests

License

MIT

galaxy-autoscale's People

Contributors

jehartzog avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

galaxy-autoscale's Issues

Error while adding package

Meteor version: 1.6.0-beta.31
System: linux 64 bits.
TL;DR: seems like request-progress is missing in the NPM's depends.

 => Errors while adding packages:

While loading avariodev:[email protected]...:
error: Command failed: /home/fermuch/.meteor/packages/meteor-tool/.1.6.0-beta.31.nr39v5++os.linux.x86_64+web.browser+web.cordova/mt-os.linux.x86_64/dev_bundle/bin/npm rebuild --update-binary
module.js:529
throw err;
^

Error: Cannot find module 'request-progress'
at Function.Module._resolveFilename (module.js:527:15)
at Function.Module._load (module.js:476:23)
at Module.require (module.js:568:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/tmp/mt-1il0fdv.mkno/npm/node_modules1/.temp-1617jpq.25kxf/node_modules/phantomjs-prebuilt/install.js:9:23)
at Module._compile (module.js:624:30)
at Object.Module._extensions..js (module.js:635:10)
at Module.load (module.js:545:32)
at tryModuleLoad (module.js:508:12)
at Function.Module._load (module.js:500:3)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: `node install.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/fermuch/.npm/_logs/2017-09-26T14_15_50_580Z-debug.log
module.js:529
throw err;
^

Error: Cannot find module 'request-progress'
at Function.Module._resolveFilename (module.js:527:15)
at Function.Module._load (module.js:476:23)
at Module.require (module.js:568:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/tmp/mt-1il0fdv.mkno/npm/node_modules1/.temp-1617jpq.25kxf/node_modules/phantomjs-prebuilt/install.js:9:23)
at Module._compile (module.js:624:30)
at Object.Module._extensions..js (module.js:635:10)
at Module.load (module.js:545:32)
at tryModuleLoad (module.js:508:12)
at Function.Module._load (module.js:500:3)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: `node install.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/fermuch/.npm/_logs/2017-09-26T14_15_50_580Z-debug.log


Startup error: Failed to launch chrome

Hey thx for this package :)
I get this error when trying out autoscale:

2018-02-16 08:45:00+01:00Error
vy32b
2018-02-16 08:45:00+01:00Failed to launch chrome!
vy32b
2018-02-16 08:45:00+01:00/app/bundle/programs/server/npm/node_modules/meteor/avariodev_galaxy-autoscale/node_modules/puppeteer/.local-chromium/linux-515411/chrome-linux/chrome: error while loading shared libraries: libXcomposite.so.1: cannot open shared object file: No such file or directory
vy32b
2018-02-16 08:45:00+01:00
vy32b
2018-02-16 08:45:00+01:00
vy32b
2018-02-16 08:45:00+01:00TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md
vy32b
2018-02-16 08:45:00+01:00
vy32b
2018-02-16 08:45:00+01:00Error: Failed to launch chrome!
vy32b
2018-02-16 08:45:00+01:00/app/bundle/programs/server/npm/node_modules/meteor/avariodev_galaxy-autoscale/node_modules/puppeteer/.local-chromium/linux-515411/chrome-linux/chrome: error while loading shared libraries: libXcomposite.so.1: cannot open shared object file: No such file or directory
vy32b
2018-02-16 08:45:00+01:00
vy32b
2018-02-16 08:45:00+01:00
vy32b
2018-02-16 08:45:00+01:00TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md
vy32b
2018-02-16 08:45:00+01:00
vy32b
2018-02-16 08:45:00+01:00 at onClose (/app/bundle/programs/server/npm/node_modules/meteor/avariodev_galaxy-autoscale/node_modules/puppeteer/lib/Launcher.js:211:14)
vy32b
2018-02-16 08:45:00+01:00 at Interface.helper.addEventListener (/app/bundle/programs/server/npm/node_modules/meteor/avariodev_galaxy-autoscale/node_modules/puppeteer/lib/Launcher.js:200:50)
vy32b
2018-02-16 08:45:00+01:00 at emitNone (events.js:111:20)
vy32b
2018-02-16 08:45:00+01:00 at Interface.emit (events.js:208:7)
vy32b
2018-02-16 08:45:00+01:00 at Interface.close (readline.js:370:8)
vy32b
2018-02-16 08:45:00+01:00 at Socket.onend (readline.js:149:10)
vy32b
2018-02-16 08:45:00+01:00 at emitNone (events.js:111:20)
vy32b
2018-02-16 08:45:00+01:00 at Socket.emit (events.js:208:7)
vy32b
2018-02-16 08:45:00+01:00 at endReadableNT (_stream_readable.js:1055:12)
vy32b
2018-02-16 08:45:00+01:00 at _combinedTickCallback (internal/process/next_tick.js:138:11)
vy32b
2018-02-16 08:45:00+01:00 at process._tickCallback (internal/process/next_tick.js:180:9)
vy32b
2018-02-16 08:45:00+01:00 => awaited here:
vy32b
2018-02-16 08:45:00+01:00 at Function.Promise.await (/app/bundle/programs/server/npm/node_modules/meteor/promise/node_modules/meteor-promise/promise_server.js:56:12)
vy32b
2018-02-16 08:45:00+01:00 at Promise.asyncApply (packages/avariodev:galaxy-autoscale/lib/autoscale.js:16:15)
vy32b
2018-02-16 08:45:00+01:00 at /app/bundle/programs/server/npm/node_modules/meteor/promise/node_modules/meteor-promise/fiber_pool.js:43:40
vy32b
2018-02-16 08:45:00+01:00(node:7) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): ReferenceError: page is not defined
vy32b
2018-02-16 08:45:00+01:00(node:7) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

I installed this package and start it like this:

GalaxyAutoScale.config({
      appUrl: Meteor.settings.galaxy.appUrl,
      username: Meteor.settings.galaxy.username,
      password: Meteor.settings.galaxy.password,
      scalingRules: {
        containersMin: 1,
        containersMax: 6,
        connectionsPerContainerMax: 120,
        connectionsPerContainerMin: 80
      },
      alertRules: {
        cpuPercentageMax: 80
      }
    });

    GalaxyAutoScale.addSyncedCronJob();

    GalaxyAutoScale.startSyncedCron(); // The README.md says GalaxyAutoScale.start(), but I think this is correct

I am using the default docker galaxy image.

Can't use Npm.depends to install NPM dependencies

Using the default Npm.depends causes errors when adding the package #1 due to modules being not found. The missing modules seem to shift, and shifting versions around while testing seems to clear the issue.

Creating this for tracking after switching over to requiring the npm dependencies to be manually installed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.