thinking outside the container: deploying standalone apps to cloud foundry
DESCRIPTION
Some applications simply cannot be contained. Perhaps you want to write a worker that periodically polls for updates or performs a maintenance task. Perhaps you would like to use a new lightweight web framework. You don’t necessarily want to build a WAR for these types of apps. With Cloud Foundry, you don’t have to! In this session from SpringOne 2012, we will build and deploy several types of standalone applications, from distributed workers built with Spring Integration and Akka, to container-less web applications built with vert.x and spray, to bring-your-own-container apps that embed Jetty. If you’re a Java or Scala developer who likes to “think outside the container”, this talk is for you!TRANSCRIPT
Thinking Outside the Container:Deploying Standalone Apps to Cloud Foundry
Jennifer Hickey
© 2012 SpringOne 2GX. All rights reserved. Do not distribute without permission.
Saturday, October 20, 2012
About Jennifer• Engineer @ Cloud Foundry• Focused on framework support• Long time SpringSource-er• Contributed to many Spring and SpringSource projects• Passionate about increasing developer productivity in the
cloud.
2
Contact InfoTwitter: @jencompgeekEmail: [email protected]
Saturday, October 20, 2012
Cloud Foundry Big Picture
3
Clou
d Pr
ovid
er In
terfa
ce
Application Service Interface
Private Clouds
PublicClouds
MicroCloud Foundry
Data Services
Other Services
Msg Services
.js
Apache2 license
Saturday, October 20, 2012
4
• Java–Spring–Grails–Lift–Play
• Ruby–Rails–Sinatra–Rack
• Node.js
Core Runtimes and Frameworks
Saturday, October 20, 2012
5
• Python–Django–WSGI
• Erlang OTP/Rebar• PHP• Perl• .Net
–On Iron Foundry
Community and partners contributions
Saturday, October 20, 2012
6
The Platinum Rule
Treat each framework the way it wants to be treated!
Saturday, October 20, 2012
7
• Command-line for application management–Create apps and services–Update bindings, memory etc.–Scale instances
• Access service and app info through environment variables–Service host, port, credentials–App ip and port
• A runtime library–Connect to services–Retrieve app info
Common Framework Support
Saturday, October 20, 2012
Common Framework Support• Auto-reconfiguration for typical apps• Access to services through Caldecott
–Creates tunnel for local clients–Mysql, Mongo, Redis CLIs, etc
• Manifest support
8Saturday, October 20, 2012
This Looks Great! But....
My App Doesn’t Use Any of These Frameworks!
9Saturday, October 20, 2012
Standalone: The “no framework” framework• Cloud Foundry now supports standalone applications!• Choose a runtime and provide a start command
–
10
$ vmc push myappDetected a Standalone Application, is this correct? [Yn]:1: java2: node3: ruby184: ruby19Select Runtime [java]:Start Command: java -jar myapp.jar
Saturday, October 20, 2012
Uses of Standalone Applications• Async Web Frameworks• BYOC: Embedding Jetty or Tomcat• Distributed polyglot applications• Workers
11Saturday, October 20, 2012
Call Me Maybe?• New frameworks are concurrent, asynchronous, event-
driven–C10K–Thread per request/response isn’t going to cut it
• Single thread to handle multiple connections–Callbacks
• Most use Netty for NIO• Some examples
–vert.x, Blue Eyes, Spray, Unfiltered, Finagle
12Saturday, October 20, 2012
vert.x - Asynchronous, Event-Driven Java
13Saturday, October 20, 2012
SockJS - WebSocket Emulation• Cloud Foundry does not (yet) support WebSocket• SockJS emulates WebSocket
–Provides low latency, full duplex, cross-domain communication channel between browser and web server
• Available for Node.js and vert.x–Also Erlang, Lua (Luvit), Python (Tornado)
14Saturday, October 20, 2012
Demo
Vert.x with SockJS on Cloud Foundry
Saturday, October 20, 2012
Uses of Standalone Applications• Async Web Frameworks• BYOC: Embedding Jetty or Tomcat• Distributed polyglot applications• Workers
16Saturday, October 20, 2012
Why BYOC?• Framework programming model
–Unfiltered with Jetty support• Outpace the CF engineers
–Tomcat 7/Servlet 3.0• http://blog.cloudfoundry.org/2012/06/18/deploying-tomcat-7-using-the-standalone-framework/
• Be cutting-edge–Clojure
• http://blog.cloudfoundry.org/2012/09/25/experimental-clojure-support-in-cloud-foundry/
17Saturday, October 20, 2012
More reasons to BYOC....• Deploy legacy EJB apps
–TomEE• Customize Tomcat
–Change logging, server config, etc
18Saturday, October 20, 2012
Demo
Unfiltered with Jetty on Cloud Foundry
Saturday, October 20, 2012
Uses of Standalone Applications• Async Web Frameworks• BYOC: Embedding Jetty or Tomcat• Distributed polyglot applications• Workers
20Saturday, October 20, 2012
WidgetInventoryService
AccountingService
ShippingService
@ControllerStoreFront
GadgetInventoryService
RDBMS
wgrus-monolithic.war
21Saturday, October 20, 2012
It’s simple to develop but ....• Lack of scalability
–Scale through replication–Non-replicable component => nothing can be replicated–Can’t scale different parts of the application differently
• Lack of deployability–Deploy it all in one go–Increased risk of something breaking
22Saturday, October 20, 2012
And....• Applications are brittle
–Store can’t accept orders unless all services are available–Failure (e.g. memory leak) in one component can take down
every other • Monolingual
–Can’t use non-JVM server-side technologies: NodeJS, Rails
23Saturday, October 20, 2012
Modern Applications• Multiple types of clients
–Mobile–HTML 5–Desktop
• Polyglot applications–NodeJS front-end–Java/Scala backend
• Asynchronous–RabbitMQ
24Saturday, October 20, 2012
And....• Polyglot persistence
–Relational–NoSQL–NewSQL
• Social network integration
25Saturday, October 20, 2012
Addressing the Scalability Problem
Saturday, October 20, 2012
27
The App
Saturday, October 20, 2012
Simple Distribution
28
Backend
Frontend
HTTP
Saturday, October 20, 2012
Widening Distribution
29
Frontend 1
HTTP
Backend 1
Saturday, October 20, 2012
Widening Distribution
29
Frontend 1
HTTP
Backend 1Backend 2
Saturday, October 20, 2012
Widening Distribution
29
Frontend 1
HTTP
Backend 1Backend 2 Backend 3
Saturday, October 20, 2012
Widening Distribution
29
Frontend 1
HTTP
Backend 1Backend 2 Backend 3
Frontend 2
Saturday, October 20, 2012
Widening Distribution
29
Frontend 1
HTTP
Backend 1Backend 2 Backend 3
Frontend 2 Frontend 3
Saturday, October 20, 2012
Scaling out in Cloud Foundry
vmc instances <app> 5
30Saturday, October 20, 2012
Cloud Foundry Manifests
31
---applications: ./frontend: ... depends-on: ./backend ./backend: ...
Saturday, October 20, 2012
ShippingService
StoreFront
wgrus-store.war
AccountingService
wgrus-billing.war
wgrus-shipping
WidgetInventoryService
wgrus-inventory
GadgetInventoryService
MySQL
32Saturday, October 20, 2012
Demo
Distributed polyglot WGRUS
Saturday, October 20, 2012
Scaling out through Akka• Remote actors
–Location transparent and distributable by design–Netty based in Akka 2.0–Needs cluster-like management
34Saturday, October 20, 2012
Remote Actors and Routing
35
Frontend 2Router
Frontend 1Router
Backend 1
Netty
Backend 2
Netty
173.14.13.3:57895173.136.3.4:59807
Saturday, October 20, 2012
Akka: Messaging based remoting
36
Frontend 1
Backend 1Backend 2 Backend 3
Frontend 2 Frontend 3
AMQP/Redis
Saturday, October 20, 2012
Demo
WGRUS with Akka
Saturday, October 20, 2012
Widening Distribution: Messaging Middleware
38
Frontend 1
Backend 1Backend 2 Backend 3
Frontend 2 Frontend 3
Saturday, October 20, 2012
ShippingService
StoreFront
wgrus-store.war
AccountingService
wgrus-billing
wgrus-shipping
WidgetInventoryService
wgrus-inventory
GadgetInventoryService
MySQL
39
Message Broker
Saturday, October 20, 2012
Spring Integration• High-level of abstraction for building message based
applications• Implements EAI patterns• Provides plumbing for exchanging messages between
application components• Promotes loosely coupled components• Integrates with external messaging infrastructure: JMS,
AMQP, HTTP, Email, File transfer
40Saturday, October 20, 2012
Spring Integration Concepts• Message channel
–Virtual pipe connecting producer and consumer• Message endpoints
–The filter of a pipes-and-filter architecture–Read from and/or write to channel
41Saturday, October 20, 2012
Spring Integration Endpoints• Endpoint types
–Transformer–Filter–Router–Splitter–Aggregator–ServiceActivator–Inbound channel adapter - read from external source, writes to
channel–Outbound channel adapter - read from channel write to external
destination42
Saturday, October 20, 2012
Demo
WGRUS with Spring Integration
Saturday, October 20, 2012
Uses of Standalone Applications• Async Web Frameworks• BYOC: Embedding Jetty or Tomcat• Distributed polyglot applications• Workers
44Saturday, October 20, 2012
Get to Work!• Update search indexes!• Email your users!• Backup your data!• Upload new data from external storage!
45Saturday, October 20, 2012
Polling for Tweets with Spring Integration
46
<int-twitter:search-inbound-channel-adapter id="twitter" query="cloud"> <int:poller fixed-rate="5000" max-messages-per-poll="10"/> </int-twitter:search-inbound-channel-adapter>
! <int:transformer input-channel="twitter" expression="payload.fromUser + ': ' + payload.text" output-channel="rabbit"/>
! <int-amqp:outbound-channel-adapter id="rabbit" exchange-name="tweets"/>
! <rabbit:fanout-exchange name="tweets" durable="false"/>! <rabbit:admin connection-factory="rabbitConnectionFactory"/>! <rabbit:template id="amqpTemplate" connection-factory="rabbitConnectionFactory"/>
! <beans profile="default">! ! <rabbit:connection-factory id="rabbitConnectionFactory"/>! </beans>
! <beans profile="cloud">! ! <cloud:rabbit-connection-factory id="rabbitConnectionFactory"/>! </beans>
Saturday, October 20, 2012
Batch Processing with Spring Batch
47Saturday, October 20, 2012
Spring Batch • Supports Batch API...
–Jobs have Steps–Steps have Readers, and optional Processors and Writers
• Readers read data• Processors process data coming into them, optionally transforming it. Optional.
• Writers write data out
48Saturday, October 20, 2012
Demo
Spring Batch Working it on Cloud Foundry
Saturday, October 20, 2012
Practical Tips
Packaging Your App
Saturday, October 20, 2012
Maven Appassembler• Creates start script and packages all deps in repo dir• vmc push --path=target/appassembler
–Start command “bin/<scriptname>”
51
<plugin><groupId>org.codehaus.mojo</groupId>! <artifactId>appassembler-maven-plugin</artifactId>
! ! <version>1.1.1</version>! ! <executions>
! ! <execution>! ! ! <phase>package</phase>
! ! ! ! <goals>! ! ! ! <goal>assemble</goal>
! ! ! ! </goals>! ! ! ! <configuration>
! ! ! ! <assembledirectory>target</assembledirectory>! ! ! ! ! <programs>
! ! ! ! ! <program>! ! ! ! ! ! <mainClass>org.springsource.samples.twitter.Demo</mainClass>
! ! ! ! ! ! </program>
Saturday, October 20, 2012
Gradle• Use the application plugin
–Run “gradle installApp”• Creates start script and packages all deps in lib dir• vmc push --path=build/install/<appname>
–Start command “bin/<scriptname>”
52
apply plugin: 'application'
mainClassName = "org.springsource.samples.twitter.Demo"
Saturday, October 20, 2012
SBT• Use sbt-package-dist• Creates a zip of all code and deps• vmc push --path=dist/appname/<zipname>.zip
–Start command “java $JAVA_OPTS -jar <main>.jar”
53
plugins.sbt:addSbtPlugin("com.twitter" %% "sbt-package-dist" % "1.0.0")
resolvers += "twitter-repo" at "http://maven.twttr.com"
build.sbt:import com.twitter.sbt._packageDistZipName := "bitshow.zip"
mainClass in Compile := Some("bitshow.Server")
Saturday, October 20, 2012
Eclipse Plugin• Does the packaging for you• Deploy and debug standalone Java apps
–Including Scala and Groovy• Caldecott support
–Tunnel to all services
54Saturday, October 20, 2012
Practical Tips
Accessing Services
Saturday, October 20, 2012
cloudfoundry-runtime• Programmatic creation of service connection factories
–Using ServiceCreator and ServiceInfo classes• CloudEnvironment class
–Access cloud properties–Access service info– No JSON parsing
• Get from the Spring milestone maven repo
56Saturday, October 20, 2012
Using ServiceCreator in Spring Applications
57
//Provides access to CF service and application env infoCloudEnvironment environment = new CloudEnvironment();! !//Retrieve env info for bound service named "mysqlService"RdbmsServiceInfo mysqlSvc =
environment.getServiceInfo("mysqlService", RdbmsServiceInfo.class);! !//create a DataSource bound to the serviceRdbmsServiceCreator dataSourceCreator = new RdbmsServiceCreator();DataSource dataSource = dataSourceCreator.createService(mysqlSvc);
Saturday, October 20, 2012
Using ServiceInfo for all Java Apps
58
//Provides access to CF service and application env infoCloudEnvironment environment = new CloudEnvironment();! !//Retrieve env info for bound service named "mongoService"MongoServiceInfo mongoSvc =
environment.getServiceInfo("mongoService", MongoServiceInfo.class);! !//create a Mongo DB bound to the serviceMongo mongoDB = new Mongo(mongoSvc.getHost(), mongoSvc.getPort());
Saturday, October 20, 2012
More Practical Tips...• Use VCAP_APP_HOST and VCAP_APP_PORT env vars
–If not using cloudfoundry-runtime lib• Don’t assign your app a URL unless you plan to bind to the
web port–CF will think your app did not start
• Keep It Alive!–CF will attempt to restart your app if it dies
• Use $JAVA_OPTS in your Java commands–Sets Heap appropriately–Allows debug on local clouds
59Saturday, October 20, 2012
Key TakeawayEndless possibilities with standalone apps on Cloud Foundry
60Saturday, October 20, 2012
Demos• Vert.x with SockJS
–https://github.com/cloudfoundry-samples/vertx-socks-sample• Unfiltered with Jetty
–https://github.com/cloudfoundry-samples/cf-unfiltered-sample• WGRUS
–https://github.com/cloudfoundry-samples/wgrus• Spring Batch Workers
–https://github.com/cloudfoundry-samples/spring-batch-tweet-workers
61Saturday, October 20, 2012
Questions?
Saturday, October 20, 2012