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

Services, services, services.

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!

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