an iterative approach to service oriented architecture

123
Iterative Service Oriented Architecture Eric Saxby @sax @ecdysone @sax

Upload: s4xx4s

Post on 27-Aug-2014

773 views

Category:

Software


2 download

DESCRIPTION

While there are resources on why other companies have made the transition to SOA, and end-game service boundaries may be clear, there are few resources on how to make progress towards SOA without sinking an entire team or stopping concurrent product development. Faced with a growing codebase, slower tests and performance issues, we've extracted services from our large Rails app the way we do everything else: iteratively. I’ll walk through what we did right, and what we almost did wrong. Presented at RailsConf 2014.

TRANSCRIPT

Page 1: An Iterative Approach to Service Oriented Architecture

Iterative Service Oriented

Architecture

Eric Saxby@sax @ecdysone @sax

Page 2: An Iterative Approach to Service Oriented Architecture

From thisFrom this

Page 3: An Iterative Approach to Service Oriented Architecture

To thisTo this

Page 4: An Iterative Approach to Service Oriented Architecture

Why should you listen to me?

Proprietary and Confidential

Page 5: An Iterative Approach to Service Oriented Architecture

Why should you listen to me?

Proprietary and Confidential

■ I have many leather bound books

Page 6: An Iterative Approach to Service Oriented Architecture

Why should you listen to me?

Proprietary and Confidential

■ I have many leather bound books

■ My apartment smells of rich mahogany

Page 7: An Iterative Approach to Service Oriented Architecture

Why should you listen to me?

Proprietary and Confidential

■ Application developer Many various technologies. Rails for ~6 years."

■ Recent focus has been operational"

■ Such acronyms, so buzzwordTDD, Agile, DevOps, SOA, Cloud, IaaS

■ Broken a surprising amount of things in a short time"

■ Work at Wanelo

Page 8: An Iterative Approach to Service Oriented Architecture

Wanelo? Whaaa?

Page 9: An Iterative Approach to Service Oriented Architecture

Wanelo? Whaaa?

■ Social network for shoppingIf you buy things on the Internet, you are our demographic

Page 10: An Iterative Approach to Service Oriented Architecture

Wanelo? Whaaa?

■ Social network for shoppingIf you buy things on the Internet, you are our demographic

■ Many millions of users

Page 11: An Iterative Approach to Service Oriented Architecture

Wanelo? Whaaa?

■ Social network for shoppingIf you buy things on the Internet, you are our demographic

■ Many millions of users

■ Databases with billions of records

Page 12: An Iterative Approach to Service Oriented Architecture
Page 13: An Iterative Approach to Service Oriented Architecture

More importantly

Page 14: An Iterative Approach to Service Oriented Architecture

More importantly

■ Iterated from one large Rails codebase to services

Page 15: An Iterative Approach to Service Oriented Architecture

More importantly

■ Iterated from one large Rails codebase to services

■ Open source as much as we can

Page 16: An Iterative Approach to Service Oriented Architecture

More importantly

■ Iterated from one large Rails codebase to services

■ Open source as much as we can

■ Scaled Ruby where people say Ruby can’t be scaled

Page 17: An Iterative Approach to Service Oriented Architecture

More importantly

■ Iterated from one large Rails codebase to services

■ Open source as much as we can

■ Scaled Ruby where people say Ruby can’t be scaled

■ Very small team

Page 18: An Iterative Approach to Service Oriented Architecture

But are you really here for success?

“Good judgment comes from experience. Experience comes from bad judgment.” — Proverb"

— Theo Schlossnagle"

http://www.infoq.com/presentations/Scalable-Internet-Architectures

Page 19: An Iterative Approach to Service Oriented Architecture

“The Anti-Pattern Goldmine”

Page 20: An Iterative Approach to Service Oriented Architecture

■ That I may or may not have worked for"

■ One giant, tangled Rails 2 codebase our vendored code had vendored code!

■ 30 engineers racing to commit code as fast as possible"

■ Success == large project launched on specific date

A completely hypothetical company

Page 21: An Iterative Approach to Service Oriented Architecture

Releases a mess

■ Code branches for months at a time"

■ Monthly releases turn to weekly releases"

■ Change list distributed and explained to executives"

■ Multi-hour deploys"

■ Annual code freeze means 3 month code bonanza

Page 22: An Iterative Approach to Service Oriented Architecture

Over time, things get worse…

Page 23: An Iterative Approach to Service Oriented Architecture

Over time, things get worse…

■ Rough estimates == Firm deadlines

Page 24: An Iterative Approach to Service Oriented Architecture

Over time, things get worse…

■ Rough estimates == Firm deadlines

■ Shortcuts only way to meet deadlines

Page 25: An Iterative Approach to Service Oriented Architecture

Over time, things get worse…

■ Rough estimates == Firm deadlines

■ Shortcuts only way to meet deadlines

■ As soon as projects finished, teams split to meet new deadlines

Page 26: An Iterative Approach to Service Oriented Architecture

Over time, things get worse…

■ Rough estimates == Firm deadlines

■ Shortcuts only way to meet deadlines

■ As soon as projects finished, teams split to meet new deadlines

■ Estimates based on worst-case timelines… never worst-case enough

Page 27: An Iterative Approach to Service Oriented Architecture

Technical DebtTechnical Debt

Page 28: An Iterative Approach to Service Oriented Architecture

Technical DebtTechnical Debt

Page 29: An Iterative Approach to Service Oriented Architecture

What did I think I learned?

■ When programming is not fun, THERE IS A PROBLEM"

■ SOA IS SOLUTION TO ALL OUR PROBLEMS"

■ DEVOPS IS THE ANSWER

Page 30: An Iterative Approach to Service Oriented Architecture

Now for a role change

■ I move into the operations team renamed to “not the operations team”BECAUSE DEVOPS"

■ Working on systems automation"

■ Engineering: SOA is the only way forward"

■ Product: SOA is that thing getting in the way of cranking out features

Page 31: An Iterative Approach to Service Oriented Architecture

If at first you can’t succeed

Page 32: An Iterative Approach to Service Oriented Architecture

If at first you can’t succeed

■ Take a firm stance

Page 33: An Iterative Approach to Service Oriented Architecture

If at first you can’t succeed

■ Take a firm stance

■ Take some deep breaths

Page 34: An Iterative Approach to Service Oriented Architecture

If at first you can’t succeed

■ Take a firm stance

■ Take some deep breaths

■ Cry like a baby

Page 35: An Iterative Approach to Service Oriented Architecture
Page 36: An Iterative Approach to Service Oriented Architecture
Page 37: An Iterative Approach to Service Oriented Architecture

New features would be services, or not built

■ New login feature as separate application"

■ Data service to manage Enterprise software home-grown Rails app

Page 38: An Iterative Approach to Service Oriented Architecture

“This will be hard and we’ll screw up, but we have no other option”

Page 39: An Iterative Approach to Service Oriented Architecture
Page 40: An Iterative Approach to Service Oriented Architecture

Okay, so what is SOA again?

One site composed of multiple applications

Internal External

UIAPI only

HTTP

Synchronous

TCP

Asynchronous

Page 41: An Iterative Approach to Service Oriented Architecture

And why would I want this?

■ Scale organization"

■ Each team manages their own code"

■ Each team deploys their own code"

■ Outsource some code without giving keys to the kingdom

Page 42: An Iterative Approach to Service Oriented Architecture

And why would I want this?

■ Scale codebase"

■ Performance tightly coupled to workload"

■ Hide complexity behind clean interfaces"

■ Use tools best suited to task at hand

Page 43: An Iterative Approach to Service Oriented Architecture

And why would I want this?

■ Scale tests"

■ Small codebase == small test suite"

■ but… costly learning curve to test service boundaries

Page 44: An Iterative Approach to Service Oriented Architecture

At some point, the cost of not doing services outweighs the cost of doing

services

Page 45: An Iterative Approach to Service Oriented Architecture

Ok… back to our protagonists

■ Data service 9 months "

■ Complex state transitions between applications"

■ No major data problems"

■ Dependent applications ambiguously successful

Page 46: An Iterative Approach to Service Oriented Architecture

EngineeringEngineering

We didn’t break anything!We didn’t break anything!

Page 47: An Iterative Approach to Service Oriented Architecture

ProductProduct

9 months??????9 months??????

Page 48: An Iterative Approach to Service Oriented Architecture

Ok, ok, ok, but what about?…

■ 3 months 2-4 engineers + the “DevOps” team"

■ Staging servers available in 2-3 weeks 2 months later… no one had deployed to them!

■ Released with feature flagExtra few weeks to break it in production

Page 49: An Iterative Approach to Service Oriented Architecture

But then…

■ Worked exactly as intended"

■ Very resilient to failures!

■ User metrics generally successful

Page 50: An Iterative Approach to Service Oriented Architecture

EngineeringEngineering

Success!!!1!!Success!!!1!!

Page 51: An Iterative Approach to Service Oriented Architecture

ProductProduct

3 months??????????3 months??????????

Page 52: An Iterative Approach to Service Oriented Architecture

How many engineers does it take to Service Oriented Architecture?

Page 53: An Iterative Approach to Service Oriented Architecture

What is success?

■ Engineering: Success"

■ Product: Failure!

■ Who wins?

Page 54: An Iterative Approach to Service Oriented Architecture

Nobody

Page 55: An Iterative Approach to Service Oriented Architecture

But let’s go deeper…

■ Why did we need SOA?"

■ Engineering did not trust product"

■ Engineering did not trust that we could fix the shortcuts required to do our job

Page 56: An Iterative Approach to Service Oriented Architecture

And even deeper…

■ Product did not trust Engineering to deliver on promises"

■ Product accountable for features, not for quality

Page 57: An Iterative Approach to Service Oriented Architecture

Trust

Page 58: An Iterative Approach to Service Oriented Architecture

So what did we learn?

Page 59: An Iterative Approach to Service Oriented Architecture

So what did we learn?

Fuck it, SOA FROM THE BEGINNING next time

Page 60: An Iterative Approach to Service Oriented Architecture

So what did we learn?

Fuck it, SOA FROM THE BEGINNING next timeX

Page 61: An Iterative Approach to Service Oriented Architecture

Agile is more than just sprinting

■ Iterate, using data to guide next iteration"

■ Deploy soon, to start collecting data"

■ Red — Green — Refactor"

■ SOA will not solve organizational problems

Page 62: An Iterative Approach to Service Oriented Architecture

SOA does not “fix” your code quality

Page 63: An Iterative Approach to Service Oriented Architecture

SOA is a tool to help with our technological pain points

Page 64: An Iterative Approach to Service Oriented Architecture

Iteration is how we create and deploy changes

Page 65: An Iterative Approach to Service Oriented Architecture

Iteration

■ Small changes deployed quickly"

■ Feature flags"

■ Each step prioritized and completed when necessary"

■ But when SOA?

Page 66: An Iterative Approach to Service Oriented Architecture

Performance

Page 67: An Iterative Approach to Service Oriented Architecture

Code complexity will be less than not doing SOA

Page 68: An Iterative Approach to Service Oriented Architecture

New code completely unrelated to old code

Page 69: An Iterative Approach to Service Oriented Architecture

With the caveat…

■ May go into old codebase short-term"

■ Deploy today is better than deploy next week"

■ Requires TRUST that this will be fixed later

Page 70: An Iterative Approach to Service Oriented Architecture
Page 71: An Iterative Approach to Service Oriented Architecture

So… Performance

Page 72: An Iterative Approach to Service Oriented Architecture

■ Site getting slower"

■ DBs becoming I/O bound on disk"

■ User growth/activity is crazy, and increasing

Page 73: An Iterative Approach to Service Oriented Architecture

■ One table completely outstripping others"

■ Reads from table killing caches for others"

■ We’re in the cloud, so max resource limits

Page 74: An Iterative Approach to Service Oriented Architecture

■ Site will stop working, soon"

■ Don’t want to stop feature development"

■ 10 engineers

Page 75: An Iterative Approach to Service Oriented Architecture

Step 1: Isolate the data

Page 76: An Iterative Approach to Service Oriented Architecture

Remove ActiveRecord relations

class Product < ActiveRecord::Base has_many :saves end

Page 77: An Iterative Approach to Service Oriented Architecture

Remove ActiveRecord relations

class Product < ActiveRecord::Base def saves Save.where(product_id: self.id) end end

Page 78: An Iterative Approach to Service Oriented Architecture

Pretend it’s in a different database

class Save < ActiveRecord::Base establish_connection "saves_#{Rails.env}" end

production: database: production_db host: 10.0.0.100 saves_production: database: production_db host: 10.0.0.100

Page 79: An Iterative Approach to Service Oriented Architecture

■ Each change deployable"

■ Tests + staging servers will show where things break"

■ Watch out for DB connection count!

Page 80: An Iterative Approach to Service Oriented Architecture

Switch to using different database

■ Create read-only replica"

■ Site maintenance mode"

■ Push new database.yml pointing to replica"

■ Promote replica to be master"

■ Restart unicorns"

■ Disable maintenance

Page 81: An Iterative Approach to Service Oriented Architecture

■ Performance may now be fine"

■ Next step can come later, whenever necessary or convenient

Page 82: An Iterative Approach to Service Oriented Architecture

Step 2: Isolate the interface

Page 83: An Iterative Approach to Service Oriented Architecture

■ How many ways do you access table?"

■ What is long term growth?"

■ What are long term goals?

Page 84: An Iterative Approach to Service Oriented Architecture

How would you shard if you could shard?

■ Wanelo == Saves"

■ Saves are viewed by"

■ Product"

■ User

Page 85: An Iterative Approach to Service Oriented Architecture

Refactor to create an API

class Product < ActiveRecord::Base def saves Save.where(product_id: self.id) end end

Page 86: An Iterative Approach to Service Oriented Architecture

Refactor to create an API

class Product < ActiveRecord::Base def saves Save.by_product(self.id) end end

Page 87: An Iterative Approach to Service Oriented Architecture

Refactor to reduce the API

■ Remove redundancy"

■ Add tests"

■ You will break things very soon!

Page 88: An Iterative Approach to Service Oriented Architecture

Step 3: Extract DB adapter

Page 89: An Iterative Approach to Service Oriented Architecture

Move finders into a module or base class

class Save include SavesClient end

Page 90: An Iterative Approach to Service Oriented Architecture

module SavesClient def self.included(other) other.send(:attr_accessor, :id, :product_id) other.extend ClientClassMethods end !

module ClientClassMethods def by_product(*args) adapter.new(self).by_product(*args) end !

def adapter @adapter ||= SavesClient::DbAdapter end end end

Page 91: An Iterative Approach to Service Oriented Architecture

■ Finders call an adapter"

■ Adapter wraps database calls

Page 92: An Iterative Approach to Service Oriented Architecture

Why an adapter?

■ Adapter is your feature flag"

■ Deployable as in-place refactor"

■ Can be replaced later with different adapters

Page 93: An Iterative Approach to Service Oriented Architecture

module SavesClient class DbAdapter def self.close_connections # Check in the database connection, # since we're shutting down this thread SavesService::Save.clear_active_connections! end !

def by_product(*args) relation :by_product, *args end !

def relation(method, *args) SavesClient::AdapterRelation.new(self, SavesService::Save.send(method, *args)) end end end

Page 94: An Iterative Approach to Service Oriented Architecture

■ Because THREADS"

■ State changes should always return a new instance"

■ #all, #first, #etc are called on Relation instance"

■ Relation will delegate to adapter

def relation(method, *args) SavesClient::AdapterRelation.new(self, SavesService::Save.send(method, *args)) end

Adapter methods return a Relation

Page 95: An Iterative Approach to Service Oriented Architecture

■ ActiveRecord model, which moves into the client"

■ Insert your favorite DB adapter here"

■ Important part is that this is hidden from the including class

def relation(method, *args) SavesClient::AdapterRelation.new(self, SavesService::Save.send(method, *args)) end

Scope of query is called on…

Page 96: An Iterative Approach to Service Oriented Architecture

Save.by_product

DBAdapter

AdapterRelation.new

Page 97: An Iterative Approach to Service Oriented Architecture

relation.all

adapter.all

ActiveRecord::Save Postgres

Instantiate client instance(s)

Page 98: An Iterative Approach to Service Oriented Architecture

Critical to deploy at this step

■ 100% guaranteed to make mistakes"

■ 100% guaranteed to have missed something"

■ Cost of fixing this is low at this step

Page 99: An Iterative Approach to Service Oriented Architecture

Step 4: Launch service app

Page 100: An Iterative Approach to Service Oriented Architecture

Insert your framework of choice

■ HTTP? JSON? MessagePack?"

■ What is easiest to develop?"

■ Transport mechanism maps to an adapter in the client"

■ Can be replaced later

Page 101: An Iterative Approach to Service Oriented Architecture

brief interlude

Page 102: An Iterative Approach to Service Oriented Architecture

Q: Why should you have deployed by now?

Page 103: An Iterative Approach to Service Oriented Architecture

A: Because the client is much more complex than the server

Page 104: An Iterative Approach to Service Oriented Architecture

So………..

Page 105: An Iterative Approach to Service Oriented Architecture

Your bugs are in the client

Page 106: An Iterative Approach to Service Oriented Architecture

Server code will be dictated by the client

■ By service launch time, whiteboard diagram will have changed"

■ Understanding will have changed"

■ Don’t write your server before you understand the needs of the client

Page 107: An Iterative Approach to Service Oriented Architecture

So, back to the server

■ We used Sinatra + Oj"

■ Sinatra is awesome!

Page 108: An Iterative Approach to Service Oriented Architecture

Step 5: Use the service

Page 109: An Iterative Approach to Service Oriented Architecture

Adapter is your feature flag

switch between DB and service"

=="

switch between DB and HTTP adapters

Page 110: An Iterative Approach to Service Oriented Architecture

Save.by_product

HTTPAdapter

AdapterRelation.new

Page 111: An Iterative Approach to Service Oriented Architecture

relation.all

adapter.all

HTTPClient JSON to Hash

Instantiate client instance(s)

Page 112: An Iterative Approach to Service Oriented Architecture

Retrospective

Page 113: An Iterative Approach to Service Oriented Architecture

■ Isolate data"

■ Isolate interface"

■ Extract DB adapter into gem"

■ Launch service"

■ Switch to service adapter

Page 114: An Iterative Approach to Service Oriented Architecture

Tests?

Page 115: An Iterative Approach to Service Oriented Architecture

Integration vs Unit

■ Spin up server, a la Sunspot?"

■ “Fake” adapter"

■ In-memory store (Array)"

■ Need unit + integration"

■ Can delete redundant tests later

Page 116: An Iterative Approach to Service Oriented Architecture

Development

■ Need to actually run service"

■ Failures are in interactions"

■ Foreman + Subcontractor"

■ Each app needs isolated Bundler env"

■ Don’t mix dependencies

Page 117: An Iterative Approach to Service Oriented Architecture

But what about a new app?

Page 118: An Iterative Approach to Service Oriented Architecture

How can we iterate on something that doesn’t exist?

Page 119: An Iterative Approach to Service Oriented Architecture

■ Deploy as early as possible"

■ Chef/Puppet/Salt/Capistrano/CFEngine"

■ Focus on being able to change quickly"

■ Isolate and understand differences

Page 120: An Iterative Approach to Service Oriented Architecture

Feature flags are more than on/off

■ Off"

■ Asynchronously write"

■ On

Page 121: An Iterative Approach to Service Oriented Architecture

Integrate deep before wide

■ Code path from beginning to end"

■ Edge cases/Errors will bubble up"

■ Avoid complexity or cleverness in design"

■ It will come on its own

Page 122: An Iterative Approach to Service Oriented Architecture

Takeaways

■ Barriers to SOA are barriers to all development"

■ Figure out how to iterate"

■ Hexagonal architecture can bubble up from organization’s needs"

■ Priorities/needs change. Facilitate this.

Page 123: An Iterative Approach to Service Oriented Architecture

Thanks!

sax ecdysone sax

especially to everyone involved in this work, of which I was one small part