Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Services, services, services.

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for Evan Phoenix Evan Phoenix
September 13, 2014

Services, services, services.

Services. You think you should write them, but how? What are the pitfalls? Are microservices a thing? What are they even? Let's find out!

Avatar for Evan Phoenix

Evan Phoenix

September 13, 2014
Tweet

Other Decks in Programming

Transcript

  1. Evan Phoenix ❄️ –Martin Fowler “Microservices” - yet another new

    term on the crowded streets of software architecture.
  2. Evan Phoenix ❄️ Small things? • Structure an application as

    a composition of services • Isolate functionality within separate code bases • Profit?
  3. Evan Phoenix ❄️ What size is “micro” • “single data

    type” • User service • “a single operation” • Login service • “logical group” • Email
  4. Evan Phoenix ❄️ Benefits • Responsibility isolation • The “Don’t

    Break My Shit” rule • Forced discipline • “You can’t instance_eval what you can’t see” • Separate Velocity Vectors • Deploy Tuesdays!
  5. Evan Phoenix ❄️ Responsibility • Also known as “Surface Area”

    • It’s the behavior of a certain app within the domain • As small as possible, no smaller • Don’t break things up just to break them • Keeps teams in control of their own destiny
  6. Evan Phoenix ❄️ Discipline • We’re lazy. It’s ok. •

    We look for shortcuts and hacks, that’s why we’re programmers. • Service boundaries keep us honest • “This DB is slow, I’ll just read it’s data file directly.” • Constraints allow for innovation, embrace them.
  7. Evan Phoenix ❄️ Velocity • Unique services have their own

    schedules • Team A doesn’t need to wait on Team B to finish a feature • High, safe velocity == happy programmers
  8. Evan Phoenix ❄️ Boundaries • “Breaking the Monolith” • Controllers

    • Starting from scratch • “Org units” • Whiteboard boxes
  9. Evan Phoenix ❄️ “The Breakup” • Divide up work at

    the controller level • Cut where makes sense for our work • Maybe 1 controller per service!
  10. Evan Phoenix ❄️ ActiveRecord chop • Don’t share ActiveRecord models

    between Services • No really. • No. Really.
  11. Evan Phoenix ❄️ SMP - Shared Model Pain • “We’ll

    just put them in a gem and share them!” • Step away from the computer. • Different services will want different “helpers” • Accelerates bitrot on models by 10x
  12. Evan Phoenix ❄️ “The Breakup Redux” • Ignore controllers •

    Put each model in it’s own service • Move controllers that “own” a model too
  13. Evan Phoenix ❄️ Fix “touchers” • Some controllers will use

    a model is a small way • This exposes a place where services will communicate • Beware of “deep” RPC calls!
  14. Evan Phoenix ❄️ 1 def user_list 2 User.all.each do |u|

    3 render '_user', :name => u.name 4 end 5 end 6 7 8 class User 9 def self.all 10 rpc("user_list").map { |n| User.new(n) } 11 end 12 13 def initialize(id); @id = id; end 14 15 def name; rpc("user_name", @id); end 16 end +50ms +50 ms times User.count
  15. Evan Phoenix ❄️ Whiteboard Arch • Whatever you draw on

    a whiteboard when asked is how you should split up the app • The represent the logical divisions within the problem domain • Intuition is to be rewarded, it reduces cognitive burdon • But feel free to iterate
  16. Evan Phoenix ❄️ Deployment • Your new best friend /

    worst enemy • N apps can’t mean N deployment mechanisms • Each service will have differences • Any pain in deployment process is amplified
  17. Evan Phoenix ❄️ If a app is never deployed, was

    it written? • Comfortable, reliable, and boring • Better to use fit apps to deployment than deployment to apps • Unify deployment across all apps • Don’t add burden with strange deployments
  18. Evan Phoenix ❄️ Solutions • Capistrano • PaaS • Heroku

    • Cloudfoundry • Vektra (soon) • Custom
  19. Evan Phoenix ❄️ Requirements • One configuration system • Don’t

    store config statically in config/ • Use ENV vars • 12factor rules • Easy to retrieve logs
  20. Evan Phoenix ❄️ The Network is the Computer Services depend

    on a fragile layer to talk to each other
  21. Evan Phoenix ❄️ Expect Failure • Gracefully degrade • Use

    back pressure • Returning errors better than crashing • Beware of priority inversion • A => B => C => A (deadlock)
  22. Evan Phoenix ❄️ Tracing • Add request ids to everything

    • Log them • Corollate them • Attach them to state / actions
  23. Evan Phoenix ❄️ How & What • Don’t argue over

    how X talks to Y • Have one convention that spans all services • Build tooling that exercises these conventions • This should eventually be second nature to everyone • You don’t debate how method calls work, do you?
  24. Evan Phoenix ❄️ How • RPC • beware rigid, lang

    specific datatypes • REST / Documents • Message passing
  25. Evan Phoenix ❄️ How - RPC • Remember the Deep

    RPC problem? Be careful! • Make it obvious when a method call is remote • Be sensitive to the kinds of values you send
  26. Evan Phoenix ❄️ RPC - Obvious name = user.name #

    BAD!! ! name = UserService.name(user) # GOOD! • Devs will cut and paste code • Be sure they know they cut and paste a remote call
  27. Evan Phoenix ❄️ RPC - Value kinds • Don’t use

    any lang specific serializers (Marshal) • Try hard not to invent your own protocol • You’re not in the protocol business, are you? • Using an existing protocol means more tooling, easier debugging and more accessibility.
  28. Evan Phoenix ❄️ Example: Finagle • Async RPC library for

    the JVM • All RPC calls return Futures • Futures are composed and blocked only at boundaries
  29. Evan Phoenix ❄️ REST / Documents • Services talk via

    APIs you’d build for the external world • JSON over HTTP from REST endpoints • Data is renormalized
  30. Evan Phoenix ❄️ HTTP/JSON Agony • Very flexible • Flexible

    is the productivity killer. • Constant debate on • REST • JSON • HTTP • URLs • Query Parameters
  31. Evan Phoenix ❄️ Standardize • Write a doc that sets

    down definitions • Don’t leave room for flexibility • Apps shouldn’t innovate in the area of URL usage
  32. Evan Phoenix ❄️ Clients • Desire to write a client

    gem for an internal API • Causes the dev to write the API twice • Everyone then uses a nice HTTP API via a ruby gem that hides it! • Clients do things subtly different for the same kind of operation
  33. Evan Phoenix ❄️ More Standardizing • Mandate what client APIs

    look like • Auto generate the client API if you can • Use something like ActiveResource • Try to not hand write every client gem
  34. Evan Phoenix ❄️ Testing • VCR • Anything that can

    pretend to be a remote service • IE could still be just mocks on a HTTP fetcher
  35. Evan Phoenix ❄️ Message Passing • Make communication async •

    Forces messages to be well documented and clear • Allows for unique communication patterns • Broadcast • Pub/Sub
  36. Evan Phoenix ❄️ Brokers • A service that flows messages

    between services • Use a broker, don’t use ZeroMQ • You’ll know when you should go broker less • SQS/SNS, RabbitMQ, etc
  37. Evan Phoenix ❄️ “What was I doing?” • Getting a

    users details • Send a “GetUserDetails” message • Block, RPC style, waiting for a reply, OR • Write state about operation and let handler for “UserDetails” message figure it out.
  38. Evan Phoenix ❄️ Awkward, But Powerful • Use different message

    passing patterns for different operations • Message passing can be awkward, but it’s very powerful • You’ll never master it, that’s ok.
  39. Evan Phoenix ❄️ Testing • Abstract away our broker •

    Replace it with a mocked one • Make a message, pass it in, see what was emitted • Repeat
  40. Evan Phoenix ❄️ Comm Delay • Communication delay between services

    a new problem vector • Remember the Deep RPC problem? • When and how to talk to other services
  41. Evan Phoenix ❄️ Denormalized Docs • Push searches down, get

    full documents back • Avoid returning references • Return “all” data
  42. Evan Phoenix ❄️ DND { "name": “Evan", "parent_id": 8 }

    ! { "name": “Evan", "parents": ["Kipp", "Lise"] }
  43. Evan Phoenix ❄️ Futures • Also called Promises • An

    asynchronous method call • Start an operation • Only block when the value is actually needed
  44. Evan Phoenix ❄️ fut = Future.new { fetch("a/doc.json") } user

    = User.find_by_name “evan" ! user.doc = fut.value user.save
  45. Evan Phoenix ❄️ “Where did I put that?” • Services

    will need to be able to find each other • Try to automate how this happens, don’t hardcode anything • Generate a config file on deployment • Put everything in internal DNS • Use consul, etcd, etc.
  46. Evan Phoenix ❄️ “Has anyone seen my database?” • Make

    the decision early • Use it everywhere • Experience pain about your decision as early as possible • Switch or refine, don’t stop. • Comfortable, stable, boring
  47. Evan Phoenix ❄️ Multiple langs • Explicit, rigid boundaries enables

    multilang archs • Benefit • Right lang for the job • Drawback • Code usability between services
  48. Evan Phoenix ❄️ Code reusability • Different than the shared

    model problem • Common tooling code around logging, api access, etc • For each new lang, write the tooling first • Otherwise when you need it, you won’t have it • If you can’t be burdened to write the tooling, you can’t be burden the team to use a new lang.
  49. Evan Phoenix ❄️ Should I do services? 1. You already

    do, you use a networked database 2. Are you willing to put the right pieces in place at the beginning? 3. Don’t sacrifice the tooling, it will be your lifeblood 4. It’s not a question of if, but when.
  50. Evan Phoenix ❄️ When? • No single app can be

    larger than the Human Cognitive Mass (HCM) threshold. • Every app that crosses it will have to be broken up or made smaller. • Corollary: Every sufficiently complex problem domain will require an app larger than HCM. • Corollary: Team HCM is smaller than individual HCM
  51. Evan Phoenix ❄️ Microservices? • Ignore the hype and the

    name • Services should be a comfortable size for your team • Don’t decouple for the sake of decoupling
  52. Evan Phoenix ❄️ Do Your Homework • Be ready for

    the network to fail • Spend time on deployment environment • Don’t decouple just to decouple
  53. Evan Phoenix ❄️ Summary • Tooling matters • Figure out

    the details and stick with them • Interservice communication • Testing strategy • You will build services, you already do.
  54. Evan Phoenix ❄️ –Voltaire, La Bégueule “Le mieux est l'ennemi

    du bien.” “The perfect is the enemy of the good.” “Sacred cows make the best hamburgers.” –Evan Phoenix