Your SlideShare is downloading. ×
Developing modular, polyglot applications with Spring (SpringOne India 2012)
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Developing modular, polyglot applications with Spring (SpringOne India 2012)

2,269
views

Published on

Published in: Technology

0 Comments
7 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,269
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
74
Comments
0
Likes
7
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Developing modular, polyglot applications with SpringChris RichardsonAuthor of POJOs in Action, Founder of the original CloudFoundry.com @crichardson chris.richardson@springsource.com http://plainoldobjects.com/
  • 2. Presentation goal Modular, polyglot applications: what, why and how?Why Spring is the ideal technology for building these applications
  • 3. About Chris
  • 4. (About Chris)
  • 5. About Chris - 1999CORBAEnterprise WebLogic ServerJavaBeans
  • 6. About Chris - 2004
  • 7. Spring programming model Dependency Injection POJO Portable Aspect- Service OrientedAbstractions Programming
  • 8. Transformed how I developed software!
  • 9. About Chris()
  • 10. About Chris - 2006Oakland JUG Cloud Computing
  • 11. Transformed how I deployed software!
  • 12. About Chris
  • 13. About Chrishttp://www.theregister.co.uk/2009/08/19/ springsource_cloud_foundry/
  • 14. vmc push About-Chris Developer Advocate for CloudFoundry.comSignup at http://cloudfoundry.com
  • 15. Agenda• The (sometimes evil) monolith• Refactoring to a modular, polyglot architecture• Presentation layer design• Using NoSQL databases• Inter-service communication options
  • 16. Let’s imagine you are building an e-commerce application
  • 17. Traditional web application architecture WAR StoreFrontUI Accounting Service MySQLBrowser Apache Database InventoryServiceSimple to Shipping Service develop test Tomcat deploy scale
  • 18. But there are problems
  • 19. Users expect a rich, dynamic and interactive experience h oug d en HTTP Request oo ’t g Browser e isn Java Web Application HTML/Javascript ec tur it ar ch e UI s tyl Old HTML5/JavaScript browser applications Real-time web ≅ NodeJS
  • 20. Limitations of relational databases• Scalability• Distribution• Schema updates• O/R impedance mismatch• Handling semi-structured data
  • 21. Intimidates developers
  • 22. Scalability issues• Different components have different scalability needs but you can only scale the entire system• Some components might not be scalable can’t scale system
  • 23. Obstacle to frequent deployments• 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
  • 24. Overloads your IDE and container Slows down development
  • 25. Obstacle to scaling development But the I want to update backend is not the UI working yet! Lots of coordination and communication required
  • 26. Requires long-term commitment to a technology stack
  • 27. Agenda• The (sometimes evil) monolith• Refactoring to a modular, polyglot architecture• Presentation layer design• Using NoSQL databases• Inter-service communication options
  • 28. The scale cubeY axis -functionaldecomposition ila g sim ninScale by r ing ing tiosplitting th litt r ti sp padifferent things by data s ale - Sc is ax Z X axis - horizontal duplication
  • 29. Y-axis scaling - application level WAR StoreFrontUI Accounting Service InventoryService Shipping Service
  • 30. Y-axis scaling - application level accounting application Accounting ServiceStore front web application inventory application StoreFrontUI InventoryService shipping application Shipping Service Apply X axis cloning and/or Z axis partitioning to each service
  • 31. 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
  • 32. Drawbacks of Y-axis splits• Complexity• Partitioned databases and transaction management• Deciding when to use this approach
  • 33. But there are many benefits• Scales development: develop, deploy and scale each service independently• Enables frequent deployments• Less for each developer to learn• Doesn’t overload IDE or container• Improves fault isolation• Easily adopt new technologies
  • 34. Two levels of architecture System-levelServicesInter-service glue: interfaces and communication mechanismsSlow changing Service-levelInternal architecture of each serviceEach service can use a different technology stackRapidly evolving - regularly rewritePick the best tool for the job
  • 35. Modular, polyglot, applications
  • 36. Lots of languages andframeworks to choose from And many more...
  • 37. But there are lots of awesome, and mature Spring projects• Spring Framework • Spring Integration• Spring Security • Spring AMQP• Spring Mobile • Spring Social• Spring Data • Spring Shell• Spring Web Services • ...• Spring Batch
  • 38. Spring works with Scala@Controllerclass TwilioController { @Autowired var surveyManagementService: SurveyManagementService = _ @RequestMapping(value = Array("/begincall.html")) @ResponseBody def beginCall(@RequestParam("From") callerId: String) = { surveyManagementService.findSurveyByCallerId(callerId) match { case None => <Response> <Say>Sorry dont recognize your number</Say> <Hangup/> </Response> case Some(survey) => <Response> <Say>{ survey.prompt }</Say> <Gather action="handleresponse.html" method="POST" numDigits="1"> { for ((choice, index) <- survey.choices zipWithIndex) yield <Say>Press { index } for { choice }</Say> } </Gather> <Say>We are sorry you could not decide</Say> <Hangup/> </Response> } }
  • 39. The Spring Scala project class  PersonConfiguration                            extends  FunctionalConfiguration  {        val  jack  =  bean()  {                new  Person("Jack",  "Doe")        }• Scala-style “setters/getters”        val  jane  =  bean()  {                new  Person("Jane",  "Doe")        }• Bean configuration DSL        val  john  =  bean()  {                val  john  =  new  Person("John",  "Doe")                john.father  =  jack()• Scala-style template classes                john.mother  =  jane()                john        } } https://github.com/SpringSource/spring-scala
  • 40. Coming in 2013 Java 8 closures = concise code!List<Album> albums = ... PredicateList<Album> sortedFavorites = albums.stream() .filter(a -> a.tracks.anyMatch(t -> (t.rating >= 4))) .sorted(comparing(a -> a.name)) .into(new ArrayList<>()); Parallelismint sum = shapes.parallel() .filter(s -> s.getColor() == BLUE) .map(s -> s.getWeight()) .sum(); http://cr.openjdk.java.net/~briangoetz/lambda/sotc3.html
  • 41. Key benefits of Spring are still Modularity Productivity Portability Testability
  • 42. Agenda• The (sometimes evil) monolith• Refactoring to a modular, polyglot architecture• Presentation layer design• Using NoSQL databases• Inter-service communication options
  • 43. Presentation layer evolution.... WAR StoreFrontUI HTML / HTTP View ControllerBrowser Model
  • 44. ...Presentation layer evolutionBrowser Web application Static content View Controller JSON-REST RESTful Endpoints Model Events EventHTML 5 - JavaScript publisherNo elaborate, server-side web framework required
  • 45. How to publish events to browser?
  • 46. NodeJS is the fashionable technology
  • 47. Why NodeJS?• Familiar JavaScript• High-performance, scalable event-driven, non-blocking I/O model• Compact runtime, e.g. 64M• Over 13,000 17,000 modules developed by the community• ManyJavaScript client frameworks have a NodeJS counterpart, e.g. socket.io and SockJS
  • 48. Why not NodeJS? a.k.a. callback hell
  • 49. Dealing with JavaScript “...Still the consequence of this is that we must take javascriptseriously as a first-class language and concentrate on how to limit the damage its flaws cause....”http://martinfowler.com/bliki/gotoAarhus2012.html
  • 50. NodeJS as a mediator... Node JS Service 1Browser Server app Static content REST Service 2 HTML 5Application EventsSocket.io Socket.io client server ...
  • 51. ...NodeJS as a mediatorREST REST Service Node JSEvents AMQP AMQP socket.io RabbitMQ Service
  • 52. Example NodeJS applicationvar express = require(express) , http = require(http) , amqp = require(‘amqp’) , server = http.createServer(app) , io = require(socket.io).listen(server) ....;server.listen(8081); Handle socket.io... connectionvar amqpCon = amqp.createConnection(...);io.sockets.on(connection, function (socket) { Republish as function amqpMessageHandler(message, headers, deliveryInfo) { var m = JSON.parse(message.data.toString()); socket.io event socket.emit(‘tick’, m); }; amqpCon.queue(“”, {}, Subscribe to AMQP function(queue) { queue.bind(“myExchange”, “myBindingKey”); queue queue.subscribe(amqpMessageHandler); });});
  • 53. Example browser application<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> 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());
  • 54. About Cujojs & s2js Dependency Injection www.cujojs.com github.com/s2js JavaScript Portable Aspect- Service OrientedAbstractions Programming
  • 55. Agenda• The (sometimes evil) monolith• Refactoring to a modular, polyglot architecture• Presentation layer design• Using NoSQL databases• Inter-service communication options
  • 56. Why NoSQL? Benefits Drawbacks• Higher performance • Limited transactions• Higher scalability • Limited querying• Richer data-model • Relaxed consistency• Schema-less • Unconstrained data
  • 57. Example NoSQL DatabasesDatabase Key featuresCassandra Extensible column store, very scalable, distributedNeo4j Graph database Document-oriented, fast, scalableMongoDBRedis Key-value store, very fast http://nosql-database.org/ lists 122+ NoSQL databases
  • 58. NoSQL and the scale cube nin a ing itio dr rd r t an ha pa ss s Ca DB g go on M MongoDB replica sets Cassandra replication
  • 59. The future is polyglot IEEE Software Sept/October 2010 - Debasish Ghosh / Twitter @debasishg
  • 60. Polyglot persistence architecture accounting application Accounting Service MySQLstorefront web application inventory application StoreFrontUI InventoryService Redis shipping application ShippingService Mongo
  • 61. Spring Data = simplifying data access• Redis• MongoDB• Neo4j• JPA• REST• Apache Hadoop• Gemfire http://www.springsource.org/spring-data
  • 62. Agenda• The (sometimes evil) monolith• Refactoring to a modular, polyglot architecture• Presentation layer design• Using NoSQL databases• Inter-service communication options
  • 63. Inter-service communication options• Synchronous HTTP asynchronous AMQP• Formats: JSON, XML, Protocol Buffers, Thrift, ... • JSON is fashionable and easier to debug • Binary format is more efficient
  • 64. Asynchronous message-based communication wgrus-billing.war Accounting Servicewgrus-store.war wgrus-inventory.war RabbitMQStoreFrontUI (Message InventoryService MySQL Broker) wgrus-shipping.war ShippingService
  • 65. Benefits• Decouples caller from server• Caller unaware of server’s coordinates (URL)• Message broker buffers message when server is down/slow• Supports a variety of communication patterns
  • 66. Drawbacks• Additional complexity of message broker• Request/reply using messaging is more complex• Firewall unfriendly
  • 67. Spring AMQP• Encapsulates low-level Producer Consumer details• Simplifiessending and Amqp Listener receiving of messages Template Container Spring AMQP AMQP
  • 68. 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
  • 69. Development time: same JVM@Servicepublic class OrderServiceImpl { @Service public class ShippingServiceImpl {@Autowiredprivate ShippingService shippingService; public void shipOrder(String orderId) { ....public void placeOrder() { } String orderId = generateOrderId(); … } shippingService.shipOrder(orderId);}} Order Shipping Service service shipOrder() Messaging Gateway Channel Service Activator
  • 70. Test and production: distributed Application code is unchanged Order Shipping Service serviceMessaging Gateway RabbitMQ Channel AMQP AMQP Channel Service Activator
  • 71. Synchronous REST wgrus-billing.war Accounting Servicewgrus-store.war REST wgrus-shipping.war StoreFrontUI Shipping MySQL Service wgrus-inventory.war ... InventoryService
  • 72. Pros and cons of REST• Pros • Cons • Simple and familiar • Only supports request/ reply • Request/reply is easy • Server must be available • Firewall friendly • Clientneeds to know • No intermediate broker URL(s) of server(s)
  • 73. Spring MVC makes REST easy URL matching @Controller & public class AccountController {object destructuring @AutowiredXML/JSON private MoneyTransferService moneyTransferService; @RequestMapping(value = "/accounts/{accountId}", method = RequestMethod.GET) @ResponseBody public AccountInfo getAccount(@PathVariable String accountId) { Account account = moneyTransferService.findAccountByid(accountId); return makeAccountInfo(account); } @RequestMapping(value = "/accounts", method = RequestMethod.POST) @ResponseStatus( HttpStatus.CREATED ) public void createAccount(@RequestBody AccountInfo accountInfo, UriComponentsBuilder builder, HttpServletResponse response) { ... } XML/JSON object
  • 74. Not all APIs are RESTfulFrom http://martinfowler.com/articles/richardsonMaturityModel.html
  • 75. About Hypertext As The Engine Of Application State• Single well known URL• Entity representation has typed relationship links• Client discovers what it can do to an entity via those linksSee http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
  • 76. About HATEOAS The well known URL$ curl http://cf-auto-scaler.cloudfoundry.com{"links": [ {"rel":"autoscaledapps", "href":"http://cf-auto-scaler.cloudfoundry.com/autoscaledapps"}]} Link link type$ curl http://cf-auto-scaler.cloudfoundry.com/autoscaledapps{"content":[ {"name":"vertx-clock", "links":[ {"rel":"self","href":"http://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock"}, {"rel":"rules","href":"http://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock/rules"} ] }],... Links to act on this app}
  • 77. Spring HATEOAS@Controller@RequestMapping(value = "/autoscaledapps")public class AutoscaledAppController { @RequestMapping(value = "/{appName}", method = RequestMethod.GET) public HttpEntity<AutoscaledAppResource> get(@PathVariable String appName) { AutoscaledAppResource ar = new AutoscaledAppResource(appName); ar.add(linkTo(AutoscaledAppController.class) .slash(appName).withSelfRel()); ar.add(linkTo(AutoscaledAppController.class) .slash(appName).slash("rules").withRel("rules")); return new HttpEntity<AutoscaledAppResource>(ar); } ... public class AutoscaledAppResource} extends ResourceSupport { private String name;https://github.com/SpringSource/spring-hateoas
  • 78. Consuming RESTful WSRestTemplate restTemplate = new RestTemplate();AccountInfo accountInfo = new AccountInfo(...);URI accountUrl = restTemplate.postForLocation("http://localhost/accounts", accountInfo);ResponseEntity<AccountInfo> accountInfoResponse = restTemplate.getForEntity(accountUrl, AccountInfo.class);Assert.assertEquals(HttpStatus.SC_OK, accountInfoResponse.getStatusCode());AccountInfo accountInfo2 = accountInfoResponse.getBody();...
  • 79. The Spring REST shell$ rest-shellhttp://localhost:8080:> baseUri http://cf-auto-scaler.cloudfoundry.comhttp://cf-auto-scaler.cloudfoundry.com:> discoverrel href=======================================================================autoscaledapps http://cf-auto-scaler.cloudfoundry.com/autoscaledappshttp://cf-auto-scaler.cloudfoundry.com:> follow --rel autoscaledappshttp://cf-auto-scaler.cloudfoundry.com/autoscaledapps:> post --from src/test/resources/examplejson/createapp1.json --follow true1 files uploaded to the server using POSThttp://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock:> discoverrel href================================================================================self http://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clockrules http://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock/ruleshttp://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock:> follow --rel ruleshttp://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock/rules:> post --from src/test/resources/examplejson/createrule1.json --follow true1 files uploaded to the server using POSThttp://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock/rules/idle:> uphttp://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock/rules:> up
  • 80. Original architecture WAR StoreFrontUI Accounting Service MySQLBrowser Apache Database InventoryServiceSimple to Shipping Service develop test Tomcat deploy scale
  • 81. Modular, polyglot architecture Desktop Browser Native Mobile application HTML5 mobile application oy StoreUI StoreUI StoreUI pl NodeJS !?! eAsynchronous, NodeJS Javascript scalable is d StoreUIcommunication th we RabbitMQ Spring/Scala doweb application Inventory Standalone Inventory Shipping Service Service Shipping “headless” Service Spring ow Integration/Java applications Billing Service Redis Inventory Mongo Order H Database Database MySQL Customer Database
  • 82. OSS community vFabricPostgres Ap Private   Clouds   p Data Services lica o n  S vFabric Public erv RabbitMQTM ice Msg Services Clouds  In ter fac Micro e Other Services Clouds Additional partners services …
  • 83. Cloud Foundry simplifies thedeployment of modular, polyglot applications
  • 84. Spring makes it easy to consume Cloud Foundry services
  • 85. Many Spring applications run on Cloud Foundry unchanged
  • 86. Summary• Modern applications have a modular, polyglot architecture• Springis the ideal technology for building these applications• Cloud Foundry is the ideal way to deploy these applications
  • 87. @crichardson chris.richardson@springsource.com http://plainoldobjects.com Thank you! www.cloudfoundry.com @cloudfoundry