Decomposing applications for deployability and scalability #springone2gx #s12gx

93
Decomposing applications for deployability and scalability Chris Richardson, Author of POJOs in Action, Founder of the original CloudFoundry.com @crichardson [email protected] http://plainoldobjects.com/

description

Today, there are several trends that are forcing application architectures to evolve. Users expect a rich, interactive and dynamic user experience on a wide variety of clients including mobile devices. Applications must be highly scalable, highly available and run on cloud environments. Organizations often want to frequently roll out updates, even multiple times a day. Consequently, it’s no longer adequate to develop simple, monolithic web applications that serve up HTML to desktop browsers. In this talk we describe the limitations of a monolithic architecture. You will learn how to use the scale cube to decompose your application into a set of narrowly focused, independently deployable back-end services and an HTML 5 client. We will also discuss the role of technologies such as NodeJS and AMQP brokers. You will learn how a modern PaaS such as Cloud Foundry simplifies the development and deployment of this style of application.

Transcript of Decomposing applications for deployability and scalability #springone2gx #s12gx

Page 1: Decomposing applications for deployability and scalability #springone2gx #s12gx

Decomposing applications for deployability and scalability

Chris Richardson, Author of POJOs in Action, Founder of the original CloudFoundry.com @[email protected]://plainoldobjects.com/

Page 2: Decomposing applications for deployability and scalability #springone2gx #s12gx

Presentation goal

2

How decomposing applications improves deployability and

scalability and

How Cloud Foundry helps

Page 3: Decomposing applications for deployability and scalability #springone2gx #s12gx

About Chris

3

Page 4: Decomposing applications for deployability and scalability #springone2gx #s12gx

(About Chris)

4

Page 5: Decomposing applications for deployability and scalability #springone2gx #s12gx

About Chris()

5

Page 6: Decomposing applications for deployability and scalability #springone2gx #s12gx

About Chris

6

Page 7: Decomposing applications for deployability and scalability #springone2gx #s12gx

About Chris

http://www.theregister.co.uk/2009/08/19/springsource_cloud_foundry/

7

Page 8: Decomposing applications for deployability and scalability #springone2gx #s12gx

vmc push About-Chris

8

Developer Advocate

Signup at http://cloudfoundry.com

Page 9: Decomposing applications for deployability and scalability #springone2gx #s12gx

9

AgendaThe (sometimes evil) monolithDecomposing applications into servicesHow do services communicate?Presentation layer designHow Cloud Foundry helps

Page 10: Decomposing applications for deployability and scalability #springone2gx #s12gx

Let’s imagine you are building an e-commerce application

10

Page 11: Decomposing applications for deployability and scalability #springone2gx #s12gx

Tomcat

Traditional web application architecture

11

Browser

WAR

MySQL Database

ShippingService

AccountingService

InventoryService

StoreFrontUI

developtestdeploy

Simple to

Apache

scale

Page 12: Decomposing applications for deployability and scalability #springone2gx #s12gx

But there are problems with a monolithic architecture

12

Page 13: Decomposing applications for deployability and scalability #springone2gx #s12gx

Users expect a rich, dynamic and interactive experience

13

Java Web ApplicationBrowser

HTTP Request

HTML/Javascript

Old style UI architecture isn’t good enough

Real-time web ≅ NodeJS

Page 14: Decomposing applications for deployability and scalability #springone2gx #s12gx

Intimidates developers

14

Page 15: Decomposing applications for deployability and scalability #springone2gx #s12gx

Obstacle to frequent deploymentsNeed to redeploy everything to change one componentInterrupts long running background (e.g. Quartz) jobsIncreases risk of failure

Fear of change

Updates will happen less oftene.g. Makes A/B testing UI really difficult

15

Page 16: Decomposing applications for deployability and scalability #springone2gx #s12gx

Overloads your IDE and container

16Slows down development

Page 17: Decomposing applications for deployability and scalability #springone2gx #s12gx

17

Shipping team

Accounting team

Engineering

Obstacle to scaling development

E-commerce application

Page 18: Decomposing applications for deployability and scalability #springone2gx #s12gx

18

WAR

Shipping

Accounting

InventoryService

StoreFrontUI

Shipping team

Accounting team

Inventory team

UI team

Obstacle to scaling development

Page 19: Decomposing applications for deployability and scalability #springone2gx #s12gx

19

Lots of coordination and communication required

Obstacle to scaling developmentUI team Accounting team

Page 20: Decomposing applications for deployability and scalability #springone2gx #s12gx

20

Requires long-term commitment to a technology stack

Page 21: Decomposing applications for deployability and scalability #springone2gx #s12gx

21

AgendaThe (sometimes evil) monolithDecomposing applications into servicesHow do services communicate?Presentation layer designHow Cloud Foundry helps

Page 22: Decomposing applications for deployability and scalability #springone2gx #s12gx

22

Page 23: Decomposing applications for deployability and scalability #springone2gx #s12gx

The scale cube

23

X axis - horizontal duplication

Z axi

s - da

ta pa

rtitio

ning

Y axis - functionaldecomposition

Scale

by sp

litting

simila

r

thing

s

Scale by splitting different things

Page 24: Decomposing applications for deployability and scalability #springone2gx #s12gx

Y-axis scaling - application level

24

WAR

ShippingService

AccountingService

InventoryService

StoreFrontUI

Page 25: Decomposing applications for deployability and scalability #springone2gx #s12gx

Y-axis scaling - application level

25

Store front web application

shipping web application

inventory web application

Apply X axis cloning and/or Z axis partitioning to each service

ShippingService

AccountingService

InventoryServiceStoreFrontUI

accounting web application

Page 26: Decomposing applications for deployability and scalability #springone2gx #s12gx

Partitioning strategiesPartition by verb, e.g. shipping servicePartition by noun, e.g. inventory serviceSingle Responsibility PrincipleUnix utilities - do one focussed thing well

26

Something of an art

Page 27: Decomposing applications for deployability and scalability #springone2gx #s12gx

Real world examples

27

http://highscalability.com/amazon-architecture

Between 100-150 services are accessed to build a page.

http://techblog.netflix.com/

http://www.addsimplicity.com/downloads/eBaySDForum2006-11-29.pdf

http://queue.acm.org/detail.cfm?id=1394128

Page 28: Decomposing applications for deployability and scalability #springone2gx #s12gx

There are drawbacks

28

Page 29: Decomposing applications for deployability and scalability #springone2gx #s12gx

Complexity

29

See Steve Yegge’s Google Platforms Rant re Amazon.com

Page 30: Decomposing applications for deployability and scalability #springone2gx #s12gx

Multiple databases =

Transaction management challenges

30

Page 31: Decomposing applications for deployability and scalability #springone2gx #s12gx

When to use it?

31

In the beginning: •You don’t need it •It will slow you down

Later on:•You need it•Refactoring is painful

Page 32: Decomposing applications for deployability and scalability #springone2gx #s12gx

But there are many benefitsScales development: develop, deploy and scale each service independentlyUpdate UI independentlyImproves fault isolationEliminates long-term commitment to a single technology stack

32

Modular, polyglot, multi-framework applications

Page 33: Decomposing applications for deployability and scalability #springone2gx #s12gx

Two levels of architecture

33

System-level

ServicesInter-service glue: interfaces and communication mechanismsSlow changing

Service-level

Internal architecture of each serviceEach service could use a different technology stackPick the best tool for the jobRapidly evolving

Page 34: Decomposing applications for deployability and scalability #springone2gx #s12gx

If services are small...Regularly rewrite using a better technology stackAdapt system to changing requirements and better technology without a total rewritePick the best developers rather than best <pick a language> developers ⇒ polyglot culture

34

Fred George “Developer Anarchy”

Page 35: Decomposing applications for deployability and scalability #springone2gx #s12gx

The human body as a system

35

Page 36: Decomposing applications for deployability and scalability #springone2gx #s12gx

50 to 70 billion of your cells die each day

36

Page 37: Decomposing applications for deployability and scalability #springone2gx #s12gx

Yet you (the system) remain you

37

Page 38: Decomposing applications for deployability and scalability #springone2gx #s12gx

Can we build software systems with these characteristics?

38

http://dreamsongs.com/Files/WhitherSoftware.pdf

http://dreamsongs.com/Files/DesignBeyondHumanAbilitiesSimp.pdf

Page 39: Decomposing applications for deployability and scalability #springone2gx #s12gx

39

AgendaThe (sometimes evil) monolithDecomposing applications into servicesHow do services communicate?Presentation layer designHow Cloud Foundry helps

Page 40: Decomposing applications for deployability and scalability #springone2gx #s12gx

Inter-service communication optionsSynchronous HTTP ⇔ asynchronous AMQP

Formats: JSON, XML, Protocol Buffers, Thrift, ...

Even via the database

40

Asynchronous is preferred

JSON is fashionable but binary format is more efficient

Page 41: Decomposing applications for deployability and scalability #springone2gx #s12gx

StoreFrontUI

wgrus-store.war

AccountingService

wgrus-billing.war

InventoryService

wgrus-inventory.war

ShippingService

wgrus-shipping.war

MySQL

41

RabbitMQ(Message Broker)

Asynchronous message-based communication

Page 42: Decomposing applications for deployability and scalability #springone2gx #s12gx

BenefitsDecouples caller from serverCaller unaware of server’s coordinates (URL)Message broker buffers message when server is down/slow

42

Page 43: Decomposing applications for deployability and scalability #springone2gx #s12gx

DrawbacksAdditional complexity of message broker RPC using messaging is more complex

43

Page 44: Decomposing applications for deployability and scalability #springone2gx #s12gx

Writing code that calls services

44

Page 45: Decomposing applications for deployability and scalability #springone2gx #s12gx

The need for parallelism

45

Service A

Service B

Service C

Service D

b = serviceB()

c = serviceC()

d = serviceD(b, c)

Call in parallel

Page 46: Decomposing applications for deployability and scalability #springone2gx #s12gx

Java Futures are a great concurrency abstraction

46

http://en.wikipedia.org/wiki/Futures_and_promises

Page 47: Decomposing applications for deployability and scalability #springone2gx #s12gx

Using Java Futures

47

public class Client {

private ExecutorService executorService; private RemoteServiceProxy remoteServiceProxy;

public void doSomething() throws ... { Future<Integer> result =

executorService.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { return remoteServiceProxy.invokeRemoteService(); } });

/// Do other things

int r = result.get(500, TimeUnit.MILLISECONDS);

System.out.println(r);

}}

Eventually contains result

When needed wait for result

Page 48: Decomposing applications for deployability and scalability #springone2gx #s12gx

Akka’s composable futures are even better

48

Page 49: Decomposing applications for deployability and scalability #springone2gx #s12gx

Composable Futures

49

val f1 = Future { ... ; 1 }val f2 = Future { ... ; 2 }

val f4 = f2.map(_ * 2)assertEquals(4, Await.result(f4, 1 second))

val fzip = f1 zip f2assertEquals((1, 2), Await.result(fzip, 1 second))

http://doc.akka.io/docs/akka/2.0.1/scala/futures.html

Transforms Future

Combines two futures

Page 50: Decomposing applications for deployability and scalability #springone2gx #s12gx

Using Akka futures

50

def callB() : Future[...] = ...def callC() : Future[...] = ...def callD() : Future[...] = ...

val future = for { (b, c) <- callB() zip callC(); d <- callD(b, c) } yield d

val result = Await.result(future, 1 second)

http://doc.akka.io/docs/akka/2.0.1/scala/futures.html

Two calls execute in parallel

And then invokes D

Get the result of D

Page 51: Decomposing applications for deployability and scalability #springone2gx #s12gx

Spring IntegrationProvides the building blocks for a pipes and filters architectureEnables development of application components that are•loosely coupled•insulated from messaging infrastructureMessaging defined declaratively

51

Page 52: Decomposing applications for deployability and scalability #springone2gx #s12gx

Handling failure

52

Service A Service B

Errors happen in distributed systems

Page 53: Decomposing applications for deployability and scalability #springone2gx #s12gx

About Netflix

53

> 1B API calls/day1 API call ⇒ average 6 service calls

Fault tolerance is essential

http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html

Page 54: Decomposing applications for deployability and scalability #springone2gx #s12gx

How to run out of threads

54

Tomcat

Execute thread pool

HTTP Request

Thread 1

Thread 2

...

Thread N

Service A Service B

If service B is down then thread will be

blocked

XXXXX

Eventually all threads will be blocked

Page 55: Decomposing applications for deployability and scalability #springone2gx #s12gx

Use timeouts and retries

55

Never wait forever

Errors can be transient ⇒ retry

http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html

Page 56: Decomposing applications for deployability and scalability #springone2gx #s12gx

Service A

Service B

Use per-dependency bounded thread pool

56http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html

Runnable 1

Runnable 2

Runnable ...

bounded queue

Task 1

Task 2

Task ...

bounded thread pool

Limits number of outstanding requests

Fails fast if service is slow or down

Page 57: Decomposing applications for deployability and scalability #springone2gx #s12gx

Use a circuit breakerHigh error rate ⇒ stop calling temporarily

Down ⇒ wait for it to come back up

Slow ⇒ gives it a chance to recover

57http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html

Page 58: Decomposing applications for deployability and scalability #springone2gx #s12gx

On failureReturn cached data

Return default data

Fail fast

58http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html

AvoidFailing

Page 59: Decomposing applications for deployability and scalability #springone2gx #s12gx

WorkerActor

Aspects + Actors

CallerDependency

InvokerAspect

DependencyStub

CircuitBreakerActor

WorkerActor

Implements circuit breaker state

machine

Equivalent of thread pool

59

Page 60: Decomposing applications for deployability and scalability #springone2gx #s12gx

@DependencyProxy annotation

@Service@DependencyProxy(circuitBreaker = "factualCircuitBreaker", timeoutInMilliseconds=750)class FactualRestaurantService extends RestaurantService { ...}

trait RestaurantService { def findNearbyRestaurants(location: Location) : Future[FindNearbyRestaurantResponse]}

60

Page 61: Decomposing applications for deployability and scalability #springone2gx #s12gx

Aspect-based Async Execution

@Aspectclass DependencyInvokingAspect {

@Pointcut("execution(* (@DependencyProxy *).*(..))") def dependencyProxyMethods {}

@Around("dependencyProxyMethods()") def invoke(jp: ProceedingJoinPoint) = { val a = AnnotationUtils.findAnnotation(jp.getTarget.getClass, classOf[DependencyProxy]) val actor = findActor(a) val timeout = Timeout(a.timeoutInMilliseconds milliseconds) actor.ask(InvokeDependency( () => jp.proceed())) (timeout) }

}

Ask actor to invoke jp.proceed() and return Future

61

Page 62: Decomposing applications for deployability and scalability #springone2gx #s12gx

See https://github.com/cer/votemeeteat

for the Actor code

62

Page 63: Decomposing applications for deployability and scalability #springone2gx #s12gx

63

AgendaThe (sometimes evil) monolithDecomposing applications into servicesHow do services communicate?Presentation layer designHow Cloud Foundry helps

Page 64: Decomposing applications for deployability and scalability #springone2gx #s12gx

Modular application

Choice of presentation layer technology

64

Page 65: Decomposing applications for deployability and scalability #springone2gx #s12gx

NodeJS is the fashionable technology

65

Page 66: Decomposing applications for deployability and scalability #springone2gx #s12gx

Why NodeJS?

66

Familiar Javascript

High-performance, scalable event-driven, non-blocking I/O model

Over 13,000 modules developed by the community

Many JavaScript client frameworks have a NodeJS counterpart, e.g. socket.io

Page 67: Decomposing applications for deployability and scalability #springone2gx #s12gx

NodeJS example

67

var http = require('http');var fs = require("fs");

http.createServer(function (req, res) { fs.readFile('somefile.txt', function (err, data) { if (err) throw err; res.writeHead(200, {'Content-Type': 'text/plain'}); res.end(data); });}).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');

Handle HTTP request

Handle file read

Page 68: Decomposing applications for deployability and scalability #springone2gx #s12gx

Socket.io - server-side

68

var express = require('express') , http = require('http') , app = express() , server = http.createServer(app) , io = require('socket.io').listen(server) ;

app.configure(function(){ app.use(express.static(__dirname + '/public'));});

server.listen(8081);

io.sockets.on('connection', function (socket) { var counter = 0; function tick() { counter = counter + 1; socket.emit('tick', counter); }; setInterval(tick, 1000);});

Serve static content from public dir

Publish event

Create a timer for socket.io client

Listen on port 8081

Page 69: Decomposing applications for deployability and scalability #springone2gx #s12gx

Socket.io - client-side

69

var socket = io.connect(location.hostname);

function ClockModel() { self.ticker = ko.observable(1); socket.on('tick', function (data) { self.ticker(data); });};

ko.applyBindings(new ClockModel());

<html><body>

The time is <span data-bind="text: ticker"></span>

<script src="/socket.io/socket.io.js"></script><script src="/knockout-2.0.0.js"></script><script src="/clock.js"></script>

</body></html>

clock.js

Connect to socket.io server

Subscribe to tick event

Bind to model

Update model

Page 70: Decomposing applications for deployability and scalability #springone2gx #s12gx

NodeJS isn’t the only game in town

70

JVM-based http://vertx.io/

Page 71: Decomposing applications for deployability and scalability #springone2gx #s12gx

A modern web application

71

Browser

Service 1

Service 2

...

HTML 5Application

Socket.ioclient

Events

RESTful WS

Server Application

Socket.ioserver

Node JS

Page 72: Decomposing applications for deployability and scalability #springone2gx #s12gx

NodeJS - using RESTful WS and AMQP

72

Node JS

Service

RabbitMQ Service

REST

AMQP AMQP

RESTRequests

Events

socket.io

Page 73: Decomposing applications for deployability and scalability #springone2gx #s12gx

73

AgendaThe (sometimes evil) monolithDecomposing applications into servicesHow do services communicate?Presentation layer designHow Cloud Foundry helps

Page 74: Decomposing applications for deployability and scalability #springone2gx #s12gx

Tomcat

Original architecture

74

Browser

WAR

MySQL Database

ShippingService

AccountingService

InventoryService

StoreFrontUI

Apache

Page 75: Decomposing applications for deployability and scalability #springone2gx #s12gx

Inventory Service Shipping Service

NodeJS

Modern architecture

75

RabbitMQ

NodeJS

Inventory Service Shipping Service

Billing Service Redis Inventory Database

Mongo Order Database

Standalone“headless” Spring/Java applications

Spring/Scala web application

MySQL Customer Database

Desktop Browser Native Mobile application HTML5 mobile application

StoreUI StoreUI StoreUI

StoreUIJavascriptAsynchronous, scalable

communication

Page 76: Decomposing applications for deployability and scalability #springone2gx #s12gx

Traditional tools: monolithic applications

76

Page 77: Decomposing applications for deployability and scalability #springone2gx #s12gx

Developing modular apps is more difficultMany more moving parts to manage•Platform services: SQL, NoSQL, RabbitMQ•Application services: your code

Who is going to setup the environments:•the developer sandbox?•...•QA environments?

77

But Cloud Foundry helps...

Page 78: Decomposing applications for deployability and scalability #springone2gx #s12gx

Applica'on  Service  Interface

Data Services

Other Services

Msg Services

Easy polyglot application deployment and service provisioning

vFabric Postgres

vFabric RabbitMQTM

Additional partners services …

OSS community

Private  Clouds  

PublicClouds

MicroClouds

Page 79: Decomposing applications for deployability and scalability #springone2gx #s12gx

Creating a platform service instance$ vmc create-service mysql --name mysql1Creating Service: OK

$ vmc services......

=========== Provisioned Services ============

+-------------+---------+| Name | Service |+-------------+---------+| mysql1 | mysql |+-------------+---------+

Page 80: Decomposing applications for deployability and scalability #springone2gx #s12gx

Multi-application manifest - part 1--- applications: inventory/target: name: inventory url: cer-inventory.chrisr.cloudfoundry.me framework: name: spring info: mem: 512M description: Java SpringSource Spring Application exec: mem: 512M instances: 1 services: si-rabbit: type: :rabbitmq si-mongo: type: :mongodb si-redis: type: :redis

80

Path to application

Required platform services

Page 81: Decomposing applications for deployability and scalability #springone2gx #s12gx

Multi-application manifest - part 2 store/target: name: store url: cer-store.chrisr.cloudfoundry.me framework: name: spring info: mem: 512M description: Java SpringSource Spring Application exec: mem: 512M instances: 1 services: si-mongo: type: :mongodb si-rabbit: type: :rabbitmq

81

Path to application

Required platform services

Page 82: Decomposing applications for deployability and scalability #springone2gx #s12gx

One command to create platform services and deploy application

$ vmc push Would you like to deploy from the current directory? [Yn]: Pushing application 'inventory'...Creating Application: OKCreating Service [si-rabbit]: OKBinding Service [si-rabbit]: OKCreating Service [si-mongo]: OKBinding Service [si-mongo]: OKCreating Service [si-redis]: OKBinding Service [si-redis]: OKUploading Application: Checking for available resources: OK Processing resources: OK Packing application: OK Uploading (12K): OK Push Status: OKStaging Application 'inventory': OK Starting Application 'inventory': OK Pushing application 'store'...Creating Application: OKBinding Service [si-mongo]: OKBinding Service [si-rabbit]: OKUploading Application: Checking for available resources: OK Processing resources: OK Packing application: OK 82

vmc push:•Reads the manifest file•Creates the required platform services•Deploys all the applications

Page 83: Decomposing applications for deployability and scalability #springone2gx #s12gx

Micro Cloud Foundry: new developer sandbox

83

Open source Platform as a Service project

App Instances Services

10.04

A PaaS packaged as a VMware Virtual Machine

Use as a developer sandbox• Use the services from Junit integration tests

• Deploy your application for functional testing

• Remote debugging from STS

Page 84: Decomposing applications for deployability and scalability #springone2gx #s12gx

Using Caldecott to tunnel into your services

84

Page 85: Decomposing applications for deployability and scalability #springone2gx #s12gx

Caldecott = TCP over HTTP

85

Your computer

Caldecott gem

Cloud Foundry

Caldecott application

Service

HTTPnative

protocol

Port NNN

Service client

nativeprotocol

Page 86: Decomposing applications for deployability and scalability #springone2gx #s12gx

Using Caldecott…$ vmc tunnel1: mysql-135e02: mysql1Which service to tunnel to?: 2Password: ********

Stopping Application: OKRedeploying tunnel application 'caldecott'.Uploading Application: Checking for available resources: OK Packing application: OK

Uploading (1K): OK Push Status: OKBinding Service [mysql1]: OKStaging Application: OK Starting Application: OK

Getting tunnel connection info: OK

Service connection info: username : uMe6Apgw00AhS password : pKcD76PcZR7GZ

name : d7cb8afb52f084f3d9bdc269e7d99ab50

Starting tunnel to mysql1 on port 10000.1: none2: mysql

Which client would you like to start?: 2

Page 87: Decomposing applications for deployability and scalability #springone2gx #s12gx

…Using CaldecottLaunching 'mysql --protocol=TCP --host=localhost --port=10000 --user=uMe6Apgw00AhS --

password=pKcD76PcZR7GZ d7cb8afb52f084f3d9bdc269e7d99ab50'

Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 10944342Server version: 5.1.54-rel12.5 Percona Server with XtraDB (GPL), Release 12.5, Revision 188

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Page 88: Decomposing applications for deployability and scalability #springone2gx #s12gx

Running JUnit test with Caldecott

88

Configure your test code to use port + connection info

Page 89: Decomposing applications for deployability and scalability #springone2gx #s12gx

Summary

89

Page 90: Decomposing applications for deployability and scalability #springone2gx #s12gx

Monolithic applications are simple to develop and deploy

BUT have significant drawbacks

90

Page 91: Decomposing applications for deployability and scalability #springone2gx #s12gx

Apply the scale cube

91

X axis - horizontal duplicationZ ax

is - d

ata pa

rtitio

ning

Y axis - functionaldecomposition

Modular, polyglot, and scalable applicationsServices developed, deployed and scaled independently

Page 92: Decomposing applications for deployability and scalability #springone2gx #s12gx

Cloud  Provider  Interface

Applica'on  Service  Interface

Private  Clouds  

PublicClouds

MicroClouds

Data Services

Other Services

Msg Services

.js

Cloud Foundry helps

Page 93: Decomposing applications for deployability and scalability #springone2gx #s12gx

Questions?

@crichardson [email protected]://slideshare.net/chris.e.richardson/

www.cloudfoundry.com @cloudfoundry