Decomposing applications for deployability and scalability #springone2gx #s12gx
Upcoming SlideShare
Loading in...5
×
 

Decomposing applications for deployability and scalability #springone2gx #s12gx

on

  • 3,760 views

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 ...

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.

Statistics

Views

Total Views
3,760
Views on SlideShare
2,660
Embed Views
1,100

Actions

Likes
11
Downloads
85
Comments
1

4 Embeds 1,100

http://plainoldobjects.com 965
https://twitter.com 132
https://si0.twimg.com 2
https://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

11 of 1

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

    • Decomposing applications for deployability and scalabilityChris Richardson,Author of POJOs in Action, Founder of the original CloudFoundry.com @crichardsoncrichardson@vmware.comhttp://plainoldobjects.com/
    • Presentation goal How decomposing applications improves deployability and scalability and How Cloud Foundry helps 2
    • About Chris 3
    • (About Chris) 4
    • About Chris() 5
    • About Chris 6
    • About Chris http://www.theregister.co.uk/2009/08/19/springsource_cloud_foundry/ 7
    • vmc push About-Chris Developer Advocate Signup at http://cloudfoundry.com 8
    • AgendaThe (sometimes evil) monolithDecomposing applications into servicesHow do services communicate?Presentation layer designHow Cloud Foundry helps 9
    • Let’s imagine you are building an e-commerce application 10
    • Traditional web application architecture WAR StoreFrontUI Accounting Service MySQL Browser Apache InventoryService Database Shipping Service Simple to Tomcat develop test deploy scale 11
    • But there are problems with a monolithic architecture 12
    • Users expect a rich, dynamicand interactive experience h oug en HTTP Request od ’t go Browser isn Java Web Application re ctu HTML/Javascript e rc hit I a ty le U s Old Real-time web ≅ NodeJS 13
    • Intimidates developers 14
    • Obstacle to frequent deployments Need to redeploy everything to change one component Interrupts long running background (e.g. Quartz) jobs Increases risk of failure Fear of change Updates will happen less often e.g. Makes A/B testing UI really difficult 15
    • Overloads your IDE and container Slows down development 16
    • Obstacle to scaling development Accounting team E-commerce Engineering application Shipping team 17
    • Obstacle to scaling development WAR UI team StoreFrontUI Accounting team Accounting Inventory team InventoryService Shipping team Shipping 18
    • Obstacle to scaling development UI team Accounting team Lots of coordination and communication required 19
    • Requires long-term commitment to a technology stack 20
    • AgendaThe (sometimes evil) monolithDecomposing applications into servicesHow do services communicate?Presentation layer designHow Cloud Foundry helps 21
    • 22
    • The scale cube Y axis - functional decomposition ila ng Scale by i m ni g s itio r splitting tin rt lit pa different things sp a gs y dat th ale is - Sc ax in b X axis Z - horizontal duplication 23
    • Y-axis scaling - application level WAR StoreFrontUI Accounting Service InventoryService Shipping Service 24
    • Y-axis scaling - application level accounting web application Accounting Service Store front web application inventory web application StoreFrontUI InventoryService shipping web application Shipping Service Apply X axis cloning and/or Z axis partitioning to each service 25
    • Partitioning strategiesPartition by verb, e.g. shipping servicePartition by noun, e.g. inventory serviceSingle Responsibility PrincipleUnix utilities - do one focussed thing well Something of an art 26
    • Real world examples http://techblog.netflix.com/ Between 100-150 services are accessed to build a page. http://highscalability.com/amazon-architecture http://www.addsimplicity.com/downloads/ eBaySDForum2006-11-29.pdf http://queue.acm.org/detail.cfm?id=1394128 27
    • There are drawbacks 28
    • ComplexitySee Steve Yegge’s Google Platforms Rant re Amazon.com 29
    • Multiple databases =Transaction management challenges 30
    • When to use it? In the beginning: •You don’t need it •It will slow you down Later on: •You need it •Refactoring is painful 31
    • But there are many benefitsScales development: develop, deploy and scale each service independentlyUpdate UI independentlyImproves fault isolationEliminates long-term commitment to a single technology stack Modular, polyglot, multi-framework applications 32
    • Two levels of architecture System-levelServicesInter-service glue: interfaces and communication mechanismsSlow changing Service-levelInternal architecture of each serviceEach service could use a different technology stackPick the best tool for the jobRapidly evolving 33
    • If services are small...Regularly rewrite using a better technology stackAdapt system to changing requirements and better technology without a total rewritePick the best developers rather than best <pick a language> developers polyglot culture Fred George “Developer Anarchy” 34
    • The human body as a system 35
    • 50 to 70 billion of your cells die each day 36
    • Yet you (the system) remain you 37
    • Can we build software systems with these characteristics? http://dreamsongs.com/Files/ DesignBeyondHumanAbilitiesSimp.pdf http://dreamsongs.com/Files/WhitherSoftware.pdf 38
    • AgendaThe (sometimes evil) monolithDecomposing applications into servicesHow do services communicate?Presentation layer designHow Cloud Foundry helps 39
    • Inter-service communication optionsSynchronous HTTP asynchronous AMQPFormats: JSON, XML, Protocol Buffers, Thrift, ...Even via the database Asynchronous is preferred JSON is fashionable but binary format is more efficient 40
    • Asynchronous message-based communication wgrus-billing.war Accounting Servicewgrus-store.war wgrus-inventory.war RabbitMQ StoreFrontUI (Message InventoryService MySQL Broker) wgrus-shipping.war ShippingService 41
    • BenefitsDecouples caller from serverCaller unaware of server’s coordinates (URL)Message broker buffers message when server is down/slow 42
    • DrawbacksAdditional complexity of message brokerRPC using messaging is more complex 43
    • Writing code that calls services 44
    • The need for parallelism Service B b = serviceB() Call in parallel c = serviceC() Service A Service C d = serviceD(b, c) Service D 45
    • Java Futures are a great concurrency abstractionhttp://en.wikipedia.org/wiki/Futures_and_promises 46
    • Using Java Futurespublic class Client { private ExecutorService executorService; private RemoteServiceProxy remoteServiceProxy; public void doSomething() throws ... { Eventually contains result Future<Integer> result = executorService.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { return remoteServiceProxy.invokeRemoteService(); } }); /// Do other things When needed wait for result int r = result.get(500, TimeUnit.MILLISECONDS); System.out.println(r); 47 }}
    • Akka’s composable futures are even better 48
    • Composable Futuresval f1 = Future { ... ; 1 }val f2 = Future { ... ; 2 } Transforms Futureval f4 = f2.map(_ * 2)assertEquals(4, Await.result(f4, 1 second)) Combines two futuresval fzip = f1 zip f2assertEquals((1, 2), Await.result(fzip, 1 second)) http://doc.akka.io/docs/akka/2.0.1/scala/futures.html 49
    • Using Akka futures def callB() : Future[...] = ... def callC() : Future[...] = ... def callD() : Future[...] = ... Two calls execute in parallel val future = for { (b, c) <- callB() zip callC(); d <- callD(b, c) } yield d And then invokes D val result = Await.result(future, 1 second) http://doc.akka.io/docs/akka/2.0.1/scala/futures.html Get the result of D 50
    • Spring IntegrationProvides the building blocks for a pipes and filters architectureEnables development of application components that are •loosely coupled •insulated from messaging infrastructureMessaging defined declaratively 51
    • Handling failure Service A Service B Errors happen in distributed systems 52
    • About Netflix > 1B API calls/day 1 API call average 6 service calls Fault tolerance is essential http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html 53
    • How to run out of threadsHTTP Request X Thread 1 X Thread 2 ... X X Thread N Execute thread Service A XService B pool Eventually all threads If service B is down then thread will be Tomcat will be blocked blocked 54
    • Use timeouts and retries Never wait forever Errors can be transient retry http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html 55
    • Use per-dependency bounded thread poolService A Runnable 1 Task 1 Runnable 2 Task 2 Service B Runnable ... Task ... bounded queue bounded thread pool Fails fast if Limits number of service is slow or down outstanding requests http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html 56
    • Use a circuit breaker High error rate stop calling temporarily Down wait for it to come back up Slow gives it a chance to recover http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html 57
    • On failure Return cached data Avoid Failing Return default data Fail fast http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html 58
    • Aspects + Actors Dependency Caller Invoker Aspect Implements circuit breaker state machine CircuitBreakerEquivalent of thread Actor pool Worker Dependency Worker Actor Stub Actor 59
    • @DependencyProxy annotationtrait RestaurantService { def findNearbyRestaurants(location: Location) : Future[FindNearbyRestaurantResponse]} @Service @DependencyProxy(circuitBreaker = "factualCircuitBreaker", timeoutInMilliseconds=750) class FactualRestaurantService extends RestaurantService { ... } 60
    • 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
    • Seehttps://github.com/cer/votemeeteat for the Actor code 62
    • AgendaThe (sometimes evil) monolithDecomposing applications into servicesHow do services communicate?Presentation layer designHow Cloud Foundry helps 63
    • Modular applicationChoice of presentation layer technology 64
    • NodeJS is the fashionable technology 65
    • Why NodeJS?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 66
    • NodeJS example Handle HTTP Handle file readvar http = require(http); requestvar 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/); 67
    • Socket.io - server-sidevar express = require(express) , http = require(http) , app = express() Serve static content from public dir , server = http.createServer(app) , io = require(socket.io).listen(server) ;app.configure(function(){ Listen on port 8081 app.use(express.static(__dirname + /public));});server.listen(8081); Create a timer for socket.io clientio.sockets.on(connection, function (socket) { var counter = 0; function tick() { counter = counter + 1; Publish event socket.emit(tick, counter); }; setInterval(tick, 1000);}); 68
    • Socket.io - client-side<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> Bind to model Connect to</html> socket.io server clock.jsvar socket = io.connect(location.hostname);function ClockModel() { self.ticker = ko.observable(1); Subscribe to tick socket.on(tick, function (data) { event self.ticker(data); });}; Update modelko.applyBindings(new ClockModel()); 69
    • NodeJS isn’t the only game in town JVM-based http://vertx.io/ 70
    • A modern web application Service 1 RESTful WS Node JSBrowser HTML 5 Server Application Application Service 2 Events Socket.io Socket.io client server ... 71
    • NodeJS - using RESTful WS and AMQP REST ServiceRESTRequests Node JS Events socket.io AMQP AMQP RabbitMQ Service 72
    • AgendaThe (sometimes evil) monolithDecomposing applications into servicesHow do services communicate?Presentation layer designHow Cloud Foundry helps 73
    • Original architecture WAR StoreFrontUI Accounting Service MySQLBrowser Apache InventoryService Database Shipping Service Tomcat 74
    • Modern architecture Desktop Browser Native Mobile application HTML5 mobile application StoreUI StoreUI StoreUI NodeJSAsynchronous, scalable NodeJS Javascript communication StoreUI RabbitMQ Spring/Scala web application Inventory Service Shipping Service Standalone Inventory Service Shipping Service “headless” Spring/ Java applications MySQL Customer Redis Inventory Mongo Order Billing Service Database Database Database 75
    • Traditional tools: monolithic applications 76
    • Developing modular apps is more difficultMany 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? But Cloud Foundry helps... 77
    • Easy polyglot application deployment and serviceprovisioning OSS community vFabric Postgres Ap p lica Private   o Data Services Clouds   n  S erv i ce  In ter fac vFabric e RabbitMQTM Public Clouds Msg Services Micro Clouds Other Services Additional partners services …
    • Creating a platform service instance$ vmc create-service mysql --name mysql1Creating Service: OK$ vmc services......=========== Provisioned Services ============+-------------+---------+| Name | Service |+-------------+---------+| mysql1 | mysql |+-------------+---------+
    • Multi-application manifest - part 1---applications: inventory/target: Path to application 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: Required platform services si-rabbit: type: :rabbitmq si-mongo: type: :mongodb si-redis: type: :redis 80
    • Multi-application manifest - part 2store/target: Path to application 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: Required platform services si-mongo: type: :mongodb si-rabbit: type: :rabbitmq 81
    • One command to create platform services and deployapplication$ vmc pushWould 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 vmc push: Processing resources: OK •Reads the manifest file Packing application: OK Uploading (12K): OK •Creates the required platform servicesPush Status: OK •Deploys all the applicationsStaging Application inventory: OKStarting Application inventory: OKPushing 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
    • Micro Cloud Foundry: new developer sandbox App Instances Services Open source Platform as a Service project 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 83
    • Using Caldecott to tunnel into your services 84
    • Caldecott = TCP over HTTP native protocol native HTTP Service Caldecott protocol Caldecott gem Service client Port application NNNYour computer Cloud Foundry 85
    • 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): OKPush Status: OKBinding Service [mysql1]: OKStaging Application: OKStarting Application: OKGetting tunnel connection info: OKService connection info: username : uMe6Apgw00AhS password : pKcD76PcZR7GZ name : d7cb8afb52f084f3d9bdc269e7d99ab50Starting tunnel to mysql1 on port 10000.1: none2: mysqlWhich client would you like to start?: 2
    • …Using CaldecottLaunching mysql --protocol=TCP --host=localhost --port=10000 --user=uMe6Apgw00AhS -- password=pKcD76PcZR7GZ d7cb8afb52f084f3d9bdc269e7d99ab50Welcome 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 188Copyright (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>
    • Running JUnit test with Caldecott Configure your test code to use port + connection info 88
    • Summary 89
    • Monolithic applications are simple to develop and deployBUT have significant drawbacks 90
    • Apply the scale cube Modular, polyglot, and scalable applications Y axis - functional decomposition Services developed, deployed and scaled independently ngi on iti rt pa a at -d is ax Z X axis - horizontal duplication 91
    • Cloud Foundry helps Ap .js p lic a on Private    Se Data Services Clouds   rv ice  In te rfa ce Public Clouds ce rfa Msg Services te  In er vid ro d  P ou Micro Cl Clouds Other Services
    • @crichardson crichardson@vmware.com http://slideshare.net/chris.e.richardson/ Questions?www.cloudfoundry.com @cloudfoundry