Download - Developing polyglot applications on Cloud Foundry (#oredev 2012)

Transcript
Page 1: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Developing polyglot applications on Cloud Foundry

Chris Richardson

Author of POJOs in Action

Founder of the original CloudFoundry.com

@crichardson

[email protected]

http://plainoldobjects.com/

Page 2: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Presentation goal

Modular, polyglot applications:

what, why and how?

How Cloud Foundry simplifies

their development and deployment

Page 3: Developing polyglot applications on Cloud Foundry (#oredev 2012)

About Chris

Page 4: Developing polyglot applications on Cloud Foundry (#oredev 2012)

(About Chris)

Page 5: Developing polyglot applications on Cloud Foundry (#oredev 2012)

About Chris()

Page 6: Developing polyglot applications on Cloud Foundry (#oredev 2012)

About Chris

Page 7: Developing polyglot applications on Cloud Foundry (#oredev 2012)

About Chris

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

Page 8: Developing polyglot applications on Cloud Foundry (#oredev 2012)

vmc push About-Chris

Signup at http://cloudfoundry.com

Developer Advocate for CloudFoundry.com

Page 9: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Agenda

• The (sometimes evil) monolith

• Refactoring to a modular, polyglot architecture

• Deploying modular, polyglot applications

Page 10: Developing polyglot applications on Cloud Foundry (#oredev 2012)

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

Page 11: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Traditional web application architecture

Tomcat

Browser

WAR

MySQL Database

ShippingService

AccountingService

InventoryService

StoreFrontUI

developtestdeploy

Simple to

Apache

scale

Page 12: Developing polyglot applications on Cloud Foundry (#oredev 2012)

But there are problems

Page 13: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Users expect a rich, dynamic and interactive experience

Java Web ApplicationBrowser

HTTP Request

HTML/Javascript

Old style UI architecture isn’t good enough

Real-time web ≅ NodeJS

Page 14: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Limitations of relational databases

• Scalability

• Distribution

• Schema updates

• O/R impedance mismatch

• Handling semi-structured data

Page 15: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Monolithic architecture=

Problems

Page 16: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Intimidates developers

Page 17: Developing polyglot applications on Cloud Foundry (#oredev 2012)

• Need to redeploy everything to change one component

• Increases risk of failure, e.g. interrupts background jobs

Fear of change

• Extensive test cycle

• Updates will happen less often, e.g. Makes A/B testing UI really difficult

Obstacle to frequent deployments

Page 18: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Overloads your IDE and container

Slows down development

Page 19: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Lots of coordination and communication required

Obstacle to scaling developmentI want to update

the UI

But the backend is not working yet!

Page 20: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Requires long-term commitment to a technology stack

Page 21: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Agenda

• The (sometimes evil) monolith

• Refactoring to a modular, polyglot architecture

• Decomposing applications into services

• Using NoSQL

• Presentation layer design

• Deploying modular, polyglot applications

Page 22: Developing polyglot applications on Cloud Foundry (#oredev 2012)
Page 23: Developing polyglot applications on Cloud Foundry (#oredev 2012)

The scale cube

X axis - horizontal duplication

Z axis

- data

parti

tionin

g

Y axis - functionaldecomposition

Scale

by sp

litting

similar

thing

s

Scale by splitting different things

Page 24: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Y-axis scaling - application level

WAR

ShippingService

AccountingService

InventoryService

StoreFrontUI

Page 25: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Y-axis scaling - application level

Store front web application

shipping application

inventory application

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

ShippingService

AccountingService

InventoryServiceStoreFrontUI

accounting application

Page 26: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Drawbacks of Y-axis splits

• Complexity

• Partitioned databases and transaction management

• Deciding when to use this approach

Page 27: Developing polyglot applications on Cloud Foundry (#oredev 2012)

But there are many benefits

• Scales development: develop, deploy and scale each service independently

• Less for each developer to learn

• Doesn’t overload IDE or container

• Improves fault isolation

• Eliminates long-term commitment to a single technology stack

Page 28: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Two levels of architecture

System-level

ServicesInter-service glue: interfaces and communication mechanismsSlow changing

Service-level

Internal architecture of each serviceEach service can use a different technology stackPick the best tool for the jobRapidly evolving - regularly rewrite

Page 29: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Modular, polyglot, applications

Page 30: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Inter-service communication options

• Transports: Synchronous HTTP ⇔ asynchronous AMQP

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

Asynchronous is preferred but REST is fine

JSON is fashionable but binary format is more efficient

Page 31: Developing polyglot applications on Cloud Foundry (#oredev 2012)

StoreFrontUI

storefront web application

AccountingService

accounting application

InventoryService

inventory application

ShippingService

shipping application

MySQL

RabbitMQ(Message Broker)

Asynchronous message-based communication

Page 32: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Agenda

• The (sometimes evil) monolith

• Refactoring to a modular, polyglot architecture

• Decomposing applications into services

• Using NoSQL

• Presentation layer design

• Deploying modular, polyglot applications

Page 33: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Solution: Use NoSQL

Benefits

• Higher performance

• Higher scalability

• Richer data-model

• Schema-less

Drawbacks

• Limited transactions

• Limited querying

• Relaxed consistency

• Unconstrained data

Page 34: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Example NoSQL Databases

Database Key features

Cassandra Extensible column store, very scalable, distributed

Neo4j Graph database

MongoDB Document-oriented, fast, scalable

Redis Key-value store, very fast

http://nosql-database.org/ lists 122+ NoSQL databases

Page 35: Developing polyglot applications on Cloud Foundry (#oredev 2012)

NoSQL and the scale cube

MongoDB replica setsCassandra replication

Mongo

DB sha

rding

Cassan

dra

parti

tionin

g

Page 36: Developing polyglot applications on Cloud Foundry (#oredev 2012)

The future is polyglot

IEEE Software Sept/October 2010 - Debasish Ghosh / Twitter @debasishg

Page 37: Developing polyglot applications on Cloud Foundry (#oredev 2012)

StoreFrontUI

storefront web application

AccountingService

accounting application

InventoryService

inventory application

ShippingService

shipping application

MySQL

RabbitMQ(Message Broker)

Polyglot persistence architecture

Redis

Mongo

Page 38: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Agenda

• The (sometimes evil) monolith

• Refactoring to a modular, polyglot architecture

• Decomposing applications into services

• Using NoSQL

• Presentation layer design

• Deploying modular, polyglot applications

Page 39: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Modular application

Choice of presentation layer technology

Page 40: Developing polyglot applications on Cloud Foundry (#oredev 2012)

NodeJS is the fashionable technology

Page 41: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Why NodeJS?• Familiar JavaScript

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

• Over 13,000 17,000 modules developed by the community

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

Page 42: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Why not NodeJS?

a.k.a. callback hell

Page 43: Developing polyglot applications on Cloud Foundry (#oredev 2012)

A modern web application

BrowserService 1

Service 2

...

HTML 5ApplicationSocket.io

client

Events

REST

Server ApplicationSocket.io

server

Node JS

Page 44: Developing polyglot applications on Cloud Foundry (#oredev 2012)

NodeJS as a mediator

Node JS

Service

RabbitMQ Service

REST

AMQP AMQP

REST

Events

socket.io

Page 45: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Socket.io - server-sidevar express = require('express') , http = require('http') , amqp = require(‘amqp’) ....;

server.listen(8081);...var amqpCon = amqp.createConnection(...);

io.sockets.on('connection', function (socket) { function amqpMessageHandler(message, headers, deliveryInfo) { var m = JSON.parse(message.data.toString()); socket.emit(‘tick’, m); }; amqpCon.queue(“myQueue”, {}, function(queue) { queue.bind(“myExchange”, “myBindingKey”); queue.subscribe(amqpMessageHandler); });});

Handle socket.io connection

Subscribe to AMQP queue

Republish as socket.io event

Page 46: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Socket.io - client-side

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 event 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 47: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Inventory Service Shipping

NodeJS

Modular, polyglot architecture

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

How

do w

e dev

elop,

test

and d

eplo

y th

is?

Page 48: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Agenda

• The (sometimes evil) monolith

• Refactoring to a modular, polyglot architecture

• Deploying modular, polyglot applications

• Overview of Cloud Foundry

• Using Cloud Foundry

• Consuming Cloud Foundry services

Page 49: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Simple, Open, Flexible,

Scalable

The Open Platform as a Service

Deploy and scale polyglot applications in seconds, without

locking yourself into a single cloud

Page 50: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Applica'on  Service  Interface

OSS community

Private  Clouds  

PublicClouds

MicroClouds

Data Services

Other Services

Msg Services

vFabric Postgres

vFabric RabbitMQTM

Additional partners services …

Page 51: Developing polyglot applications on Cloud Foundry (#oredev 2012)

CloudFoundry.COM - Multi-tenant PaaS operated by VMware

Runtimes & FrameworksServices

vCenter / vSphere

CloudFoundry.COM (beta)

Infrastructure

Page 52: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Micro Cloud FoundryTM – Industry first downloadable PaaS

Open source Platform as a Service project

App Instances Services

A cloud packaged as a VMware Virtual Machine

Page 53: Developing polyglot applications on Cloud Foundry (#oredev 2012)

CloudFoundry.ORG - Vibrant Apache 2 licensed open-source project

CloudFoundry.ORG

DownloadCode

Setup Environment

Deploy Behind FirewallBOSH

Your Infrastructure

Page 54: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Cloud Foundry: you can trade-off effort vs flexibility

Public PaaS

Private PaaS

Custom Private PaaS

Less

More

Less

More

.COM....

....

git clone git://github.com/cloudfoundry/vcap.git

Effort Flexibility

Page 55: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Agenda

• The (sometimes evil) monolith

• Refactoring to a modular, polyglot architecture

• Deploying modular, polyglot applications

• Overview of Cloud Foundry

• Using Cloud Foundry

• Consuming Cloud Foundry services

Page 56: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Using Cloud Foundry

Page 57: Developing polyglot applications on Cloud Foundry (#oredev 2012)

$ vmc target <any cloud>

$ vmc login <credentials> $ vmc push <my-app>

> bind services? Yes

$ vmc update <my-app>

$ vmc instances <my-app> +100

Example vmc commands

Page 58: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Sinatra + Redisrequire 'sinatra'require 'redis'

configure do $r = Redis.new(:host => '127.0.0.1', :port => '6379') if !$r end

get '/' do "Hello World! " + $r.incr("hitcounter").to_send

http://sgce2012.cloudfoundry.com/

Connect to Redis

Increment hit counter

Page 59: Developing polyglot applications on Cloud Foundry (#oredev 2012)
Page 60: Developing polyglot applications on Cloud Foundry (#oredev 2012)

One step deployment--- applications: ./storefront: name: nodestore framework: name: node info: mem: 64M description: Node.js Application exec: url: ${name}.${target-base} mem: 64M instances: 1 services: si-redis: type: redis si-rabbit: type: rabbitmq

Path to application

Required platform services

Page 61: Developing polyglot applications on Cloud Foundry (#oredev 2012)

applications: standalone-inventory/target/appassembler: name: standalone-shipping framework: name: standalone info: description: Standalone Application exec: runtime: java command: bin/standalone-shipping url: mem: 512M instances: 1 services: si-rabbit: type: rabbitmq si-mongo: type: mongodb

One step deployment

Path to application

Required platform services

Page 62: Developing polyglot applications on Cloud Foundry (#oredev 2012)

One step deployment$ vmc push

Would you like to deploy from the current directory? [Yn]:

Pushing application 'inventory'...

Creating Application: OK

Creating Service [si-rabbit]: OK

Binding Service [si-rabbit]: OK

Creating Service [si-mongo]: OK

Binding Service [si-mongo]: OK

Creating Service [si-redis]: OK

Binding Service [si-redis]: OK

Uploading Application:

Checking for available resources: OK

Processing resources: OK

Packing application: OK

Uploading (12K): OK

Push Status: OK

Staging Application 'inventory': OK

Starting Application 'inventory': OK

Pushing application 'store'...

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

Page 63: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Micro Cloud Foundry = your sandbox

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 64: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Agenda

• The (sometimes evil) monolith

• Refactoring to a modular, polyglot architecture

• Deploying modular, polyglot applications

• Overview of Cloud Foundry

• Using Cloud Foundry

• Consuming Cloud Foundry services

Page 65: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Cloud Foundry services

Page 66: Developing polyglot applications on Cloud Foundry (#oredev 2012)

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

$ vmc services......

=========== Provisioned Services ============+-------------+---------+| Name | Service |+-------------+---------+| mysql1 | mysql |+-------------+---------+

$

Page 67: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Binding a service to an application

$ vmc push cer-spring --path web/target/Application Deployed URL [cer-spring.cloudfoundry.com]: Detected a Java SpringSource Spring Application, is this correct? [Yn]:

Memory Reservation (64M, 128M, 256M, 512M, 1G) [512M]:

Creating Application: OKWould you like to bind any services to 'cer-spring'? [yN]: y

Would you like to use an existing provisioned service? [yN]: yThe following provisioned services are available

1: mysql1

2: mysql-135e0Please select one you wish to use: 1

Binding Service [mysql1]: OKUploading Application:

Checking for available resources: OK

Processing resources: OK Packing application: OK

Uploading (12K): OK

Would you like to bind any services to 'cer-spring'? [yN]: yWould you like to use an existing provisioned service? [yN]: yThe following provisioned services are available1: mysql12: mysql-135e0Please select one you wish to use: 1Binding Service [mysql1]: OK

Page 68: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Bindings exposed through VCAP_SERVICES environment variable

{ "mysql-5.1": [{

"name": "mysql1", "label": "mysql-5.1",

"plan": "free", "tags": ["mysql", "mysql-5.1", "relational"],

"credentials": {

"name": "da81b57c25cca4c65929a223f0ed068a0",

"host": "172.99.99.99",

"port": 3306,

"username": "secretusername",

"password": "secretuserpassword"

....

}

}] }

Page 69: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Accessing bound services:low-level

var services = JSON.parse(process.env.VCAP_SERVICES);var creds = services['mysql-5.1'][0].credentials

configure do services = JSON.parse(ENV['VCAP_SERVICES']) mysql_key = services.keys.select { |svc| svc =~ /mysql/i }.first mysql = services[mysql_key].first['credentials'] mysql_conf = {:host => mysql['hostname'], :port => mysql['port'], :username => mysql['user'], :password => mysql['password']} @@client = Mysql2::Client.new mysql_confend

Page 70: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Accessing bound services:high-level, Spring/Java

<bean id="dataSource" class="…"> … DataSource for MySQL instance … </bean>

reconfigured automatically

CloudEnvironment environment = new CloudEnvironment();RdbmsServiceInfo mysqlSvc = environment.getServiceInfo("mysqlService", RdbmsServiceInfo.class);RdbmsServiceCreator dataSourceCreator = new RdbmsServiceCreator();DataSource dataSource = dataSourceCreator.createService(mysqlSvc);

<cloud:data-source id="dataSource" service-name="mysql1"> <cloud:pool pool-size="1-5"/> <cloud:connection properties="charset=utf-8"/></cloud:data-source>...

Page 71: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Accessing bound services:high-level, Ruby

RedisHost = "127.0.0.1"RedisPort = 10000$r = Redis.new(:host => RedisHost, :port => RedisPort) if !$r

reconfigured automatically

production: adapter: sqlite3 database: db/production.sqlite3 pool: 5 timeout: 5000

rewritten automatically

Page 72: Developing polyglot applications on Cloud Foundry (#oredev 2012)

The human body as a system

Page 73: Developing polyglot applications on Cloud Foundry (#oredev 2012)

50 to 70 billion of your cells die each day

Page 74: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Yet you (the system) remain you

Page 75: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Can we build software systems with these characteristics?

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

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

Page 76: Developing polyglot applications on Cloud Foundry (#oredev 2012)

Questions?

@crichardson [email protected]://plainoldobjects.com/presentations/

www.cloudfoundry.com @cloudfoundry