I-Tier: Node.js at Groupon
Sean McCullough
@mcculloughsean
Enterprise Node.js Developer at Groupon
This Presentation is About...
• how Groupon's platform stopped working
• how we rewrote a part of it
• what went well and ...
Problems
Simple Start
• Monolithic Ruby on Rails app
• Sustained business through hyper-growth
• Small engineering team
• Simple pr...
Acquisitions
• CityDeal.de (Germany, most of EU)
• SoSata (India)
• Needish (South America)
Ran as separate platforms
One Monolithic Application
Actually, two separate monoliths
Move to Mobile
• ~50% of global transactions
• Streamlined user experience
• Mobile uses REST API
Two Facets of the Same Monolith
Two Facets X Two Monoliths
Business was Stuck
• Could not build features fast enough
• Wanted to build features worldwide
• Mobile and web lacked fea...
Platform was Broken
• Required cdn cached deal page
• Monolith was hard to scale
• Entire site would go down
• Couldn't su...
The Plan
Start with the Frontend
• Unify global look and feel
• REST API already built for mobile
• Backend services are more compl...
Design Goals
• Decouple teams
• Deploy apps on team schedule
• Allow for global design changes
• I18n/L13n
• Be small, do ...
Bakeoff
• Node
• MRI Ruby/Rails, MRI Ruby/Sinatra
• JRuby/Rails, Sinatra
• MRI Ruby + Sinatra + EM
• Java/Play, Java/Vertx...
Why Node.js?
• Vibrant community
• NPM!
• Frontend developers know javascript
• Performant enough
• Easy scaling (process ...
Why Node.js Javascript?
• Front-end devs know Javascript
• Leverage existing knowledge on server
Stack
• CoffeeScript (hi haters!)
• Express
• Mustache & custom view engine
• Custom asset pipeline
Boundaries
• Apps only talk to REST API and Memcached
• Layout is in a separate application
• Shared common asset bundle
Design Goals
• Simple controllers
• Render from the server
• Skip fancy performance optimizations
• Make the API a bottlen...
Simple Design
module.exports =
main: ( {attributes, renderCallback} ) ->
# Presenter that sets the layout
view = presenter...
Subscribe Page
• Simple application
• Partial implementation
• Proved out the concept
Growing Pains
• Max sockets
• Breaking our infrastructure
New problems
• User authentication
• More service calls
• Complicated routing
• More traffic
• Share look and feel
grout
Switchboard for incoming requests to I-Tier
applications
• domain
• locale
• country
• experiments
grout
• groupon.com/deals/my-awesome-deal
• itier-deal-page-vip.snc1/deals/my-awesome-
deal
• groupon.de/browse/berlin
• i...
grout
• Experiments between different applications on
the same URL
• Testing between alternative implementations
(includin...
gconfig
• Configuration as a service
• Some config can change on the fly
• Config can be promoted from uat -> staging ->
prod
Layout
• Distribute layout as library
• Use ESIs for top/bottom of page
• Apps are called through a “chrome service”
• Fet...
Layout Service
• Independent rollouts
• Changes can be shipped without re-deploying all
apps
• Easy to use in development
Layout Service
• Uses semantic versioning
• Roll forward with bug fixes
• Stay locked on a specific version
• Enable site-wi...
Rewrite All The Things!
Rewrite
• Get the whole company to move at once
• Supporting two platforms is hard
• Transition from June 2013 to Septembe...
Rewrite
• ~150 developers
• Global effort
• Feature freeze – A/B testing against mostly the
same features
What Went Well
It worked!
Webpages got faster
Sustained record traffic
What Didn't Go Well
Negatives of SOA
• Increased testing burden
• Tooling needs to catch up
• Increased operational overhead
Culture Problems
• Changed team workflow
• Teams are silos
• Code quality varies
Next Steps
• Better resiliency to outages
• Distributed tracing
• International (launching now)
• Open Source - Testium
tl;dr
• Kill web monolith
• Federated frontend
• Service oriented architecture
• grout
• gconfig
• Layout service
Thanks!
@mcculloughsean
empirejs 2014
Transitioning Groupon to Node.js - EmpireJS 2014
Transitioning Groupon to Node.js - EmpireJS 2014
Transitioning Groupon to Node.js - EmpireJS 2014
Transitioning Groupon to Node.js - EmpireJS 2014
Transitioning Groupon to Node.js - EmpireJS 2014
Transitioning Groupon to Node.js - EmpireJS 2014
Transitioning Groupon to Node.js - EmpireJS 2014
Transitioning Groupon to Node.js - EmpireJS 2014
Transitioning Groupon to Node.js - EmpireJS 2014
Transitioning Groupon to Node.js - EmpireJS 2014
Transitioning Groupon to Node.js - EmpireJS 2014
Transitioning Groupon to Node.js - EmpireJS 2014
Transitioning Groupon to Node.js - EmpireJS 2014
Upcoming SlideShare
Loading in...5
×

Transitioning Groupon to Node.js - EmpireJS 2014

1,444
-1

Published on

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

No Downloads
Views
Total Views
1,444
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
17
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Transitioning Groupon to Node.js - EmpireJS 2014

  1. 1. I-Tier: Node.js at Groupon Sean McCullough @mcculloughsean Enterprise Node.js Developer at Groupon
  2. 2. This Presentation is About... • how Groupon's platform stopped working • how we rewrote a part of it • what went well and what didn't
  3. 3. Problems
  4. 4. Simple Start • Monolithic Ruby on Rails app • Sustained business through hyper-growth • Small engineering team • Simple product
  5. 5. Acquisitions • CityDeal.de (Germany, most of EU) • SoSata (India) • Needish (South America) Ran as separate platforms
  6. 6. One Monolithic Application
  7. 7. Actually, two separate monoliths
  8. 8. Move to Mobile • ~50% of global transactions • Streamlined user experience • Mobile uses REST API
  9. 9. Two Facets of the Same Monolith
  10. 10. Two Facets X Two Monoliths
  11. 11. Business was Stuck • Could not build features fast enough • Wanted to build features worldwide • Mobile and web lacked feature parity • Could not change look and feel • Difficult to internationalize
  12. 12. Platform was Broken • Required cdn cached deal page • Monolith was hard to scale • Entire site would go down • Couldn't support growth
  13. 13. The Plan
  14. 14. Start with the Frontend • Unify global look and feel • REST API already built for mobile • Backend services are more complicated to unite
  15. 15. Design Goals • Decouple teams • Deploy apps on team schedule • Allow for global design changes • I18n/L13n • Be small, do the minimum
  16. 16. Bakeoff • Node • MRI Ruby/Rails, MRI Ruby/Sinatra • JRuby/Rails, Sinatra • MRI Ruby + Sinatra + EM • Java/Play, Java/Vertx • Python+Twisted • PHP
  17. 17. Why Node.js? • Vibrant community • NPM! • Frontend developers know javascript • Performant enough • Easy scaling (process model)
  18. 18. Why Node.js Javascript? • Front-end devs know Javascript • Leverage existing knowledge on server
  19. 19. Stack • CoffeeScript (hi haters!) • Express • Mustache & custom view engine • Custom asset pipeline
  20. 20. Boundaries • Apps only talk to REST API and Memcached • Layout is in a separate application • Shared common asset bundle
  21. 21. Design Goals • Simple controllers • Render from the server • Skip fancy performance optimizations • Make the API a bottleneck • Resilience when services fail
  22. 22. Simple Design module.exports = main: ( {attributes, renderCallback} ) -> # Presenter that sets the layout view = presenters.page 'subscribe', attributes # Grab the list of all the divisions grouponAPI.fetch { endpoint: 'divisions' }, (err, {divisions}, details) -> # If there’s an error, bail and pass the error along return renderCallback err if err? divisionsPresenter = presenters.divisions divisions, { currentDivision: attributes.query?.division_p } view.set { divisions: divisionsPresenter } render.pageHtml view, renderCallback
  23. 23. Subscribe Page • Simple application • Partial implementation • Proved out the concept
  24. 24. Growing Pains • Max sockets • Breaking our infrastructure
  25. 25. New problems • User authentication • More service calls • Complicated routing • More traffic • Share look and feel
  26. 26. grout Switchboard for incoming requests to I-Tier applications • domain • locale • country • experiments
  27. 27. grout • groupon.com/deals/my-awesome-deal • itier-deal-page-vip.snc1/deals/my-awesome- deal • groupon.de/browse/berlin • itier-browse-page-vip.lup1/browse/berlin
  28. 28. grout • Experiments between different applications on the same URL • Testing between alternative implementations (including the legacy monoliths!)
  29. 29. gconfig • Configuration as a service • Some config can change on the fly • Config can be promoted from uat -> staging -> prod
  30. 30. Layout • Distribute layout as library • Use ESIs for top/bottom of page • Apps are called through a “chrome service” • Fetch templates from service
  31. 31. Layout Service • Independent rollouts • Changes can be shipped without re-deploying all apps • Easy to use in development
  32. 32. Layout Service • Uses semantic versioning • Roll forward with bug fixes • Stay locked on a specific version • Enable site-wide experiments
  33. 33. Rewrite All The Things!
  34. 34. Rewrite • Get the whole company to move at once • Supporting two platforms is hard • Transition from June 2013 to September 1, 2013
  35. 35. Rewrite • ~150 developers • Global effort • Feature freeze – A/B testing against mostly the same features
  36. 36. What Went Well
  37. 37. It worked!
  38. 38. Webpages got faster
  39. 39. Sustained record traffic
  40. 40. What Didn't Go Well
  41. 41. Negatives of SOA • Increased testing burden • Tooling needs to catch up • Increased operational overhead
  42. 42. Culture Problems • Changed team workflow • Teams are silos • Code quality varies
  43. 43. Next Steps • Better resiliency to outages • Distributed tracing • International (launching now) • Open Source - Testium
  44. 44. tl;dr • Kill web monolith • Federated frontend • Service oriented architecture • grout • gconfig • Layout service
  45. 45. Thanks! @mcculloughsean empirejs 2014
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×