Svcc services presentation (Silicon Valley code camp 2011)

670 views
628 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
670
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Svcc services presentation (Silicon Valley code camp 2011)

  1. 1. Proprietary and Confidential<br />Learning to Love Services<br />Experiences from the Transition to a <br />Service-oriented Architecture<br />Jeff Green<br />Staff Software Engineer<br />
  2. 2. Background<br />
  3. 3. Proprietary and Confidential<br />3<br />Ingenuity Systems<br />Collect large curated, computable knowledge base of biological information<br />Molecules (genes, chemicals)<br />Relationships between molecules<br />Pathways<br />Biological processes<br />Develop software applications to leverage knowledge base for researchers<br />Ingenuity Pathways Analysis (IPA)<br />iReports<br />Next Generation Sequencing application<br />
  4. 4. Proprietary and Confidential<br />4<br />IPA<br />Analyze dataset of molecules uploaded by user<br />
  5. 5. Proprietary and Confidential<br />5<br />IPA<br />Visualize and explore relationships between molecules<br />
  6. 6. Proprietary and Confidential<br />6<br />IPA<br />Search and browse through biological content<br />
  7. 7. Proprietary and Confidential<br />7<br />Technologies<br />Client: Swing-based primary client with some browser-based visualizations<br />Server: Multi-tier Java web application in Tomcat and Jetty servlet containers<br />Oracle database<br />
  8. 8. Proprietary and Confidential<br />8<br />Legacy Architecture<br />Servers separated for scalability<br />Communicate through multicasting<br />Early notion of services except:<br />Significant overlap of code and data access<br />Tightly coupled build, package, deployment<br />Entire system released quarterly<br />
  9. 9. Proprietary and Confidential<br />9<br />Why move toService-oriented Architecture?<br />Code/data reuse<br />Single definition of services and model objects<br />Common implementation<br />More precise scalability<br />Scale only parts of system under stress<br />More rapid releases<br />Push new features and fixes out to customers faster<br />Simplify testing<br />Separation of responsibilities<br />Untangle unnecessary dependencies<br />Reduce learning curve of code<br />
  10. 10. Proprietary and Confidential<br />10<br />Constraints<br />IPA enhancements must continue simultaneously<br />Changes cannot impact Production system prematurely<br />Majority of engineering resources still focused on new development<br />Homogeneous implementation<br />All services will be in Java, although external clients may be Swing or browser-based.<br />Majority of services will be private<br />Existing public apis will remain but are exception<br />
  11. 11. Proprietary and Confidential<br />11<br />Key Considerations<br />High-level architecture<br />What parts of the system should be services?<br />Implementation<br />How is a service defined?<br />Communication<br />How will consumers interact with providers?<br />Versioning<br />How can changes be managed?<br />Testing<br />How can quality be ensured?<br />
  12. 12. High-level Architecture<br />
  13. 13. Proprietary and Confidential<br />13<br />Architecture Questions<br />What existing capabilities should become separate services?<br />What is the responsibility of each service?<br />What data does each service own?<br />What are the dependencies?<br />No circularity<br />How granular should the system be?<br />If too granular, hard to maintain<br />If not granular enough, lose benefits of services (reuse, scalability, modularity, etc.)<br />
  14. 14. Proprietary and Confidential<br />14<br />Ingenuity Service Categories<br />Key Driver:<br />Reuse functionality to reduce development cost and enforce consistency<br />Biological content<br />Provide biological content from a single source in a consistent model<br />Algorithms<br />Optimized for executing algorithms on data<br />User management<br />User records<br />Authentication/authorization<br />Account creation<br />License management<br />
  15. 15. Proprietary and Confidential<br />15<br />Ingenuity Service Categories (cont.)<br />Views of biological entities<br />Common rendering for reports of all biological information about a molecule, chemical, etc.<br />Utilities<br />Event tracking<br />Document generation<br />
  16. 16. Proprietary and Confidential<br />16<br />Previous Design<br />
  17. 17. Proprietary and Confidential<br />17<br />IPA with Services<br />
  18. 18. Implementation<br />
  19. 19. Proprietary and Confidential<br />19<br />Strategy<br />Adopt a common nomenclature, ideally somewhat similar to existing system<br />Define simple, brief standards to guide development and ensure consistency<br />Code organization<br />Server directory structure<br />For each service, pick best implementation approach<br />Implement from scratch<br />Customize third-party application<br />Refactor existing code<br />
  20. 20. Proprietary and Confidential<br />20<br />What exactly is a service anyway?<br />A set of operations available to consumers<br />Defined by an Application Programming Interface (API): the set of operations and the data structures that serve as their input and output<br />Java implementation: an interface and the model objects (Plain Old Java Objects, POJOs) that serve as arguments and return values<br />
  21. 21. Proprietary and Confidential<br />21<br />Module<br />Encapsulates one or more related services and their implementations<br />Source code: API, business logic, data access<br />XML and property files<br />Web resources<br />Test code (both unit and integration)<br />Vertical slice of functionality<br />Improved modularity, reuse<br />Buildable unit resulting in <module>.jar and other artifacts<br />Existed in previous architecture, albeit different in nature<br />
  22. 22. Proprietary and Confidential<br />22<br />Module Source Packages<br />Defined new basic package structure to organize code within modules<br />Consistency helps with finding, understanding code<br />
  23. 23. Proprietary and Confidential<br />23<br />Module Directories<br />Defined new basic directory structure to organize resources within modules<br />Consistency helps with finding resources<br />Simplifies tools<br />
  24. 24. Proprietary and Confidential<br />24<br />Component<br />Encapsulates one or more modules for packaging/deployment (i.e. a releasable unit)<br />In practice, one per JVM<br />Unit of scale and redundancy<br />Owner of modules and schemas<br />Biological Content Component<br />Molecule Module<br />Finding Module<br />Graph Module<br />Graph Service<br />Molecule Service<br />Finding Service<br />Notation Service<br />
  25. 25. Proprietary and Confidential<br />25<br />Why have a module?<br />In smaller components, component = single module<br />In larger components, additional unit of encapsulation helps to further modularize the code<br />Clarifies code organization<br />Forces consideration of dependencies<br />Package boundaries not inherently enforced<br />An attempt to fight spaghetti<br />
  26. 26. Proprietary and Confidential<br />26<br />Tactics: Rebuild or Refactor?<br />Rebuild where existing approach was not sufficient<br />New licensing schemes<br />SSO authentication (CAS implementation)<br />Refactor where behavior should not change significantly<br />Content, algorithms, views<br />Changes must not impact ongoing enhancements<br />Rebuilt components have no immediate impact<br />Refactor on separate branch; schedule merge at appropriate time<br />
  27. 27. Proprietary and Confidential<br />27<br />Build, Package, Deploy<br />Before<br />Ant script built entire system at once<br />All components deployed together across multiple JVMs<br />After<br />Modified ant script builds a single component<br />Resulting component package is union of resources in modules it owns<br />Each component deployed separately<br />Current Tools<br />Hudson used to manage build/package tasks<br />Custom installer<br />
  28. 28. Communication<br />
  29. 29. Proprietary and Confidential<br />29<br />Considerations<br />How does a consumer locate a service provider?<br />Once found, what is protocol for communication?<br />Requirements<br />Consumers and providers must be loosely coupled<br />Flexibility to add providers without impacting consumers and vice-versa<br />Synchronous communication is acceptable<br />
  30. 30. Proprietary and Confidential<br />30<br />Spring Remoting<br />Already in use in existing application<br />Abstract data transfer from consumer and provider<br />Provides flexibility to switch from remote to local services through configuration<br />GraphService<br />GraphAlgorithm<br />GraphServiceImpl<br />getGraph(id)<br />GraphObj<br />Within single component<br />
  31. 31. Proprietary and Confidential<br />31<br />Spring Remoting<br />Already in use in existing application<br />Abstract data transfer from consumer and provider<br />Provides flexibility to switch from remote to local services through configuration<br />GraphService<br />GraphAlgorithm<br />GraphService<br />HttpService<br />HttpProxy<br />GraphServiceImpl<br />URL from<br />configuration<br />getGraph(id)<br />getGraph(id)<br />Http request w/ serialized objects<br />GraphObj<br />GraphObj<br />Http response w/ serialized objects<br />Across components<br />
  32. 32. Proprietary and Confidential<br />32<br />Service Discovery Manager (SDM)<br />Simple, custom utility provides a single (logical) point for service discovery<br />Provider registers service<br />Consumer requests service location<br />SDM<br />ServerA<br />Algorithm<br />Component<br />
  33. 33. Proprietary and Confidential<br />33<br />Service Discovery Manager (SDM)<br />Simple, custom utility provides a single (logical) point for service discovery<br />Provider registers service<br />Consumer requests service location<br />SDM<br />Provider registers at startup<br />GraphService<br />@ServerB<br />ServerB<br />ServerA<br />Content<br />Component<br />Algorithm<br />Component<br />GraphService<br />
  34. 34. Proprietary and Confidential<br />34<br />Service Discovery Manager (SDM)<br />Simple, custom utility provides a single (logical) point for service discovery<br />Provider registers service<br />Consumer requests service location<br />SDM<br />1a) Consumer requests service location<br />GraphService<br />@ServerB<br />ServerB<br />ServerA<br />GraphService<br />Content<br />Component<br />Algorithm<br />Component<br />GraphService<br />
  35. 35. Proprietary and Confidential<br />35<br />Service Discovery Manager (SDM)<br />Simple, custom utility provides a single (logical) point for service discovery<br />Provider registers service<br />Consumer requests service location<br />SDM<br />1b) SDM responds with location<br />GraphService<br />@ServerB<br />ServerB<br />ServerA<br />Content<br />Component<br />ServerB<br />Algorithm<br />Component<br />GraphService<br />
  36. 36. Proprietary and Confidential<br />36<br />Service Discovery Manager (SDM)<br />Simple, custom utility provides a single (logical) point for service discovery<br />Provider registers service<br />Consumer requests service location<br />SDM<br />GraphService<br />@ServerB<br />ServerB<br />ServerA<br />Content<br />Component<br />Algorithm<br />Component<br />GraphService<br />2a) Consumer requests service<br />directly from ServerB<br />
  37. 37. Proprietary and Confidential<br />37<br />Service Discovery Manager (SDM)<br />Simple, custom utility provides a single (logical) point for service discovery<br />Provider registers service<br />Consumer requests service location<br />SDM<br />GraphService<br />@ServerB<br />ServerB<br />ServerA<br />Content<br />Component<br />Algorithm<br />Component<br />GraphService<br />2b) Provider responds with data<br /><ul><li>Additional overhead with multiple requests, so stickiness is available
  38. 38. In practice, have not needed it</li></li></ul><li>Proprietary and Confidential<br />38<br />Service Discovery Manager (SDM)<br />Spring remoting bean replaced with SDM-implementation<br />Still abstracted from consumer and provider code<br />GraphService<br />GraphAlgorithm<br />GraphService<br />SDMProvider<br />SDMConsumer<br />GraphServiceImpl<br />URL from<br />SDM<br />getGraph(id)<br />Http request w/ serialized objects<br />getGraph(id)<br />GraphObj<br />GraphObj<br />Http response w/ serialized objects<br />
  39. 39. Proprietary and Confidential<br />39<br />api.jar<br />Consumers and providers must share api definition<br /><module>-api.jar encapsulates module service interfaces and model object classes<br />Built/published along with component providing the service<br />Consumer picks up published jar at build time<br />
  40. 40. Versioning<br />v1.0<br />v2.0<br />
  41. 41. Proprietary and Confidential<br />41<br />Change is Inevitable<br />A service is defined by API, which will change over time<br />Consumers and providers may change at different rates<br />Goal is to minimize impact of change on consumers<br />
  42. 42. Proprietary and Confidential<br />42<br />Types of Service Changes<br />Implementation only<br />No change to API; therefore no impact on consumer<br />API addition<br />New method or member in model object<br />API change or deletion<br />Service contract has changed<br />
  43. 43. Proprietary and Confidential<br />43<br />Version Label<br /><major>.<minor>.<build><br /><build> = implementation change<br />Updated every build (svn revision number)<br />No impact on consumer <br /><minor> = API addition<br />All releases with same major version are backward compatible<br />Consumer of older service can ignore<br /><major> = API change<br />Consumer must adapt<br />
  44. 44. Proprietary and Confidential<br />44<br />Usage during Service Discovery<br />Api.jar stamped with specific version<br />Consumer includes versioned api when built<br />Consumer requests service with specific version<br />SDM finds provider with = major version and >= minor version<br />Multiple versions can coexist<br />ServerC<br />ServerA<br />ServerB<br />SDM<br />Content<br />Component<br />Content<br />Component<br />Algorithm<br />Component<br />GraphService2.2<br />@ServerB<br />GraphService2.3<br />GraphService 2.2<br />GraphService2.2<br />GraphService2.3<br />@ServerC<br />ServerB<br />or<br />ServerC<br />
  45. 45. Proprietary and Confidential<br />45<br />Usage during Service Discovery<br />Api.jar stamped with specific version<br />Consumer includes versioned api when built<br />Consumer requests service with specific version<br />SDM finds provider with = major version and >= minor version<br />Multiple versions can coexist<br />ServerC<br />ServerA<br />ServerB<br />SDM<br />Content<br />Component<br />Content<br />Component<br />Algorithm<br />Component<br />GraphService2.2<br />@ServerB<br />GraphService2.3<br />GraphService 2.3<br />GraphService2.2<br />GraphService2.3<br />@ServerC<br />ServerC<br />
  46. 46. Proprietary and Confidential<br />46<br />Java Serialization Id<br />Every Java class has serialization id<br />Assigned by compiler or programmer<br />Intent is to identify change<br />If unspecified, API model object will get new id with every change<br />Potentially breaks backwards compatibility of minor version change<br />Solution is to specify id for all model objects<br />
  47. 47. Proprietary and Confidential<br />47<br />Stability Level<br />Need to separate components at different stages of lifecycle<br />Ongoing development should not impact testing and demos<br />Versioning not sufficient because only reflects API changes<br />
  48. 48. Proprietary and Confidential<br />48<br />Option: Duplicate Environments<br />Duplicate entire system for each stage of stability<br />
  49. 49. Proprietary and Confidential<br />49<br />Option: Duplicate Environments<br />Duplicate entire system for each stage of stability<br /><ul><li>Significant redundancy
  50. 50. Unmanageable when several environments</li></li></ul><li>Proprietary and Confidential<br />50<br />Better Option: Zones<br />Establish zones: logical categories of stability<br />Development vs. testing vs. stable<br />In practice, zone can be String<br />Providers broadcast service in appropriate zone<br />Consumers look for service in desired zone<br />
  51. 51. Proprietary and Confidential<br />51<br />Full Service Discovery Protocol<br />Discovery protocol involves three pieces of info<br />Service name (i.e. full interface name)<br />Version<br />Zone<br />Same SDM instance can be used across all zones<br />ServerB<br />ServerA<br />SDM<br />GraphService2.3<br />Stable<br />GraphService2.3<br />Stable@ServerB<br />Algorithm<br />Component<br />ServerC<br />GraphService2.3<br />Test@ServerC<br />GraphService 2.3<br />Stable<br />GraphService2.3<br />Test<br />GraphService2.3<br />Dev@ServerD<br />ServerB<br />ServerD<br />Dev<br />GraphService2.3<br />
  52. 52. Testing<br />
  53. 53. Proprietary and Confidential<br />53<br />Goals<br />Ensure component meets contract defined by API<br />Opportunity for more granular testing<br />No user interface available<br />Critical for individual release cycles<br />Ensure component is backwards compatible<br />Test component as a whole<br />“Unit test” where component is the testable unit<br />Not comfortable relying solely on class unit tests<br />Requires realistic data<br />Automate test execution<br />Enable more frequent updates with less cost<br />
  54. 54. Proprietary and Confidential<br />54<br />FitNesse<br />Framework for writing, organizing, and executing tests<br />Acts as a consumer of the component under test<br />Tests written in wiki-like syntax in browser client<br />Classes called Fixtures transform data to/from API model objects<br />Results are displayed and history is maintained<br />
  55. 55. Proprietary and Confidential<br />55<br />Test Resources<br />Modules that encapsulate code for services also contain the testing-related resources<br />FitNesse wiki pages<br />Fixtures<br />Fixtures built at same time as component<br /><ul><li>All test resources encapsulated in a separate package
  56. 56. Package includes api jars of the service it tests, just like other consumers of the service
  57. 57. For every component, there is a suite of FitNesse tests to validate it</li></li></ul><li>Proprietary and Confidential<br />56<br />Continuous Integration (CI)<br />Goal: rapidly iterate through the develop, build, test, and release cycle in as automated a way as possible<br />Basic workflow<br />Developer commits change to component<br />Altered component is built and deployed<br />Suite of tests are executed against the component<br />Assuming tests pass, build is released<br />Process is as automated as possible<br />Ideally frequency is limited only by hardware constraints<br />
  58. 58. Proprietary and Confidential<br />57<br />CI in Practice<br />Stable<br />Stable<br />Test<br />FitNesse<br />CI<br />Content<br />Component<br />Component is implemented in a Dev zone<br />Dev<br />
  59. 59. Proprietary and Confidential<br />58<br />CI in Practice<br />Stable<br />Stable<br />Component is built and deployed in the CI zone<br />Test<br />FitNesse<br />CI<br />Content<br />Component<br />Dev<br />
  60. 60. Proprietary and Confidential<br />59<br />CI in Practice<br />Stable<br />Stable<br />Component tests are deployed to the FitNesse server<br />Test<br />FitNesse<br />CI<br />Content<br />Component<br />Dev<br />
  61. 61. Proprietary and Confidential<br />60<br />CI in Practice<br />Stable<br />Stable<br />Tests are executed against the component<br />Test<br />FitNesse<br />CI<br />Content<br />Component<br />Dev<br />
  62. 62. Proprietary and Confidential<br />61<br />CI in Practice<br />If tests pass, component is promoted to Stable zone<br />Stable<br />Stable<br />Test<br />FitNesse<br />CI<br />Content<br />Component<br />Dev<br />
  63. 63. Proprietary and Confidential<br />62<br />CI in Practice<br />Stable<br />Stable<br />Test<br />FitNesse<br />CI<br />Content<br />Component<br />Algorithm<br />Component<br />Consumers use services in the Stable zone, even during development and testing<br />Dev<br />
  64. 64. Proprietary and Confidential<br />63<br />CI in Practice<br />Consumers go through the same CI workflow to be promoted to Stable<br />Stable<br />Stable<br />Test<br />FitNesse<br />CI<br />Content<br />Component<br />Algorithm<br />Component<br />Dev<br />
  65. 65. Proprietary and Confidential<br />64<br />CI in Practice<br />The process is initiated automatically once per day and the steps are automated from build to Stable promotion. Builds are still manually released to Production for now.<br />Stable<br />Stable<br />Test<br />FitNesse<br />CI<br />Content<br />Component<br />Algorithm<br />Component<br />Dev<br />
  66. 66. Proprietary and Confidential<br />65<br />Backwards Compatibility<br />Services must be backwards compatible<br />Support consumers of all previous minor versions<br />Ensures provider can be updated independently of consumer<br />To validate, execute test bundles built with previous minor versions<br />Confirms previous contract is still met<br />Confirms api jars are still compatible<br />
  67. 67. Results<br />
  68. 68. Proprietary and Confidential<br />67<br />Successes<br />New applications utilized services immediately<br />Enabled teams to focus on new innovation<br />Previously code/capability had to be duplicated<br />Apps used services even before IPA did<br />Faster, more frequent releases<br />Legacy system previously updated quarterly<br />User management service now updated within iteration (< 2 weeks)<br />Fixes released within a couple hours<br />More modular code base<br />Consistency in code structure, server layout<br />Several servers smaller than before<br />Improved startup time<br />Now feasible to run/debug within IDE<br />
  69. 69. Proprietary and Confidential<br />68<br />Challenges and Do-overs<br />Difficult to overhaul so many aspects of the system simultaneously<br />Major version in API package names<br />Potentially results in “false positive” change to significant numbers of files<br />20% case complicated the 80% case<br />Jar dependencies<br />Attempt at simplification ended up being more difficult<br />
  70. 70. Proprietary and Confidential<br />69<br />Next Steps<br />Recently achieved milestone of porting legacy application to use services it spawned<br />Improve service APIs, possibly rewrite<br />Feasible now that components have clearly defined boundaries<br />Improve test coverage<br />Performance testing of individual components<br />Understand load profiles to guide scalability decisions<br />Transition to standard tools<br />maven<br />puppet<br />
  71. 71. Proprietary and Confidential<br />70<br />Key Takeaways<br />Identify early what is necessary and what is not; focus on what is necessary<br />Take incremental steps where possible<br />Important for remaining agile<br />Establish simple patterns or standards to follow in implementation, packaging, and testing<br />Helps with tools creation, understanding of system<br />Be flexible<br />Try new approaches and process; adapt if first try does not work out<br />
  72. 72. Proprietary and Confidential<br />71<br />Questions?<br />Jeff Green<br />Staff Software Engineer<br />Ingenuity Systems<br />www.ingenuity.com<br />Slides available at:<br />http://www.slideshare.net/jenlwong/svcc-services-presentation-201110<br />Photo Credits: Petronas Towers: Franco Pecchio (Ai@ce, flickr.com); Coffee beans: Al Gebra (photl.com); Telegraph: Bill Bradford (mrbill, flickr.com); Chimp: Afrika Expeditionary Force (flickr.com); Mug shot: Jimmy Prescott (flickr.com); Crash test: NASA (everystockphoto.com); Trophies: Roberto Arias (Ariaski, flickr.com)<br />

×