Last active
January 22, 2016 20:29
-
-
Save murdoaird/c14a32fd248e99dfaa93 to your computer and use it in GitHub Desktop.
Resilient Load-Balanced Bash Web Cluster
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Resilient Load-Balanced Bash Web Cluster (Brooklyn Example) | |
# this final example shows some of the advanced functionality: | |
# defining custom sensors, and a cluster with a "spec", | |
# policies for resilience and scaling based on that sensor, | |
# and wiring a load balancer in front of the cluster | |
# combining this with the riak cluster in the previous example | |
# is left as a suggested exercise for the user | |
services: | |
# define a cluster of the web nodes | |
- type: cluster | |
name: Cluster of Bash Web Nodes | |
id: my-web-cluster | |
brooklyn.config: | |
initialSize: 1 | |
memberSpec: | |
$brooklyn:entitySpec: | |
# template 2 is used as the spec for items in this cluster | |
# with a new message overwriting the previous, | |
# and a lot of sensors defined | |
type: 2-bash-web-server-template | |
name: My Bash Web Server VM with Sensors | |
locations: [] | |
brooklyn.config: | |
my.message: "part of the cluster" | |
brooklyn.initializers: | |
# make a simple request-count sensor, by counting the number of 200 responses in output.txt | |
- type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor | |
brooklyn.config: | |
name: reqs.count | |
targetType: int | |
period: 5s | |
command: "cat output.txt | grep HTTP | grep 200 | wc | awk '{print $1}'" | |
# and publish the port as a sensor so the load-balancer can pick it up | |
- type: org.apache.brooklyn.core.sensor.StaticSensor | |
brooklyn.config: | |
name: app.port | |
targetType: int | |
static.value: $brooklyn:config("my.app.port") | |
brooklyn.enrichers: | |
# derive reqs.per_sec from reqs.count | |
- type: org.apache.brooklyn.enricher.stock.YamlTimeWeightedDeltaEnricher | |
brooklyn.config: | |
enricher.sourceSensor: reqs.count | |
enricher.targetSensor: reqs.per_sec | |
enricher.delta.period: 1s | |
# and take an average over 30s for reqs.per_sec into reqs.per_sec.windowed_30s | |
- type: org.apache.brooklyn.enricher.stock.YamlRollingTimeWindowMeanEnricher | |
brooklyn.config: | |
enricher.sourceSensor: reqs.per_sec | |
enricher.targetSensor: reqs.per_sec.windowed_30s | |
enricher.window.duration: 30s | |
# emit failure sensor if a failure connecting to the service is sustained for 30s | |
- type: org.apache.brooklyn.policy.ha.ServiceFailureDetector | |
brooklyn.config: | |
entityFailed.stabilizationDelay: 30s | |
brooklyn.policies: | |
# restart if a failure is detected (with a max of one restart in 2m, sensor will propagate otherwise) | |
- type: org.apache.brooklyn.policy.ha.ServiceRestarter | |
brooklyn.config: | |
failOnRecurringFailuresInThisDuration: 2m | |
# back at the cluster, create a total per-sec and some per-node average | |
brooklyn.enrichers: | |
- type: org.apache.brooklyn.enricher.stock.Aggregator | |
brooklyn.config: | |
enricher.sourceSensor: reqs.per_sec | |
enricher.targetSensor: reqs.per_sec | |
transformation: sum | |
- type: org.apache.brooklyn.enricher.stock.Aggregator | |
brooklyn.config: | |
enricher.sourceSensor: reqs.per_sec | |
enricher.targetSensor: reqs.per_sec.per_node | |
transformation: average | |
- type: org.apache.brooklyn.enricher.stock.Aggregator | |
brooklyn.config: | |
enricher.sourceSensor: reqs.per_sec.windowed_30s | |
enricher.targetSensor: reqs.per_sec.windowed_30s.per_node | |
transformation: average | |
brooklyn.policies: | |
# resilience: if a per-node restart policy fails, | |
# just throw that node away and create a new one | |
- type: org.apache.brooklyn.policy.ha.ServiceReplacer | |
# and scale based on reqs/sec | |
- type: org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy | |
brooklyn.config: | |
# scale based on reqs/sec (though in a real-world situation, | |
# reqs.per_sec.windowed_30s.per_node might be a better choice) | |
metric: reqs.per_sec.per_node | |
# really low numbers, so you can trigger a scale-out just by hitting reload a lot | |
metricUpperBound: 3 | |
metricLowerBound: 1 | |
# sustain 3 reqs/sec for 2s and it will scale out | |
resizeUpStabilizationDelay: 2s | |
# only scale down when sustained for 1m | |
resizeDownStabilizationDelay: 1m | |
maxPoolSize: 3 | |
# and add a load-balancer pointing at the cluster | |
- type: load-balancer | |
id: load-bal | |
brooklyn.config: | |
# point this load balancer at the cluster, specifying port to forward to | |
loadbalancer.serverpool: $brooklyn:entity("my-web-cluster") | |
member.sensor.portNumber: app.port | |
brooklyn.enrichers: | |
# publish a few useful info sensors and KPI's to the root of the app | |
- type: org.apache.brooklyn.enricher.stock.Propagator | |
brooklyn.config: | |
uniqueTag: propagate-load-balancer-url | |
producer: $brooklyn:entity("load-bal") | |
propagating: | |
- main.uri | |
- type: org.apache.brooklyn.enricher.stock.Propagator | |
brooklyn.config: | |
uniqueTag: propagate-reqs-per-sec | |
producer: $brooklyn:entity("my-web-cluster") | |
propagating: | |
- reqs.per_sec | |
- reqs.per_sec.windowed_30s.per_node | |
location: byon |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment