Introduction to Distributed Architecture What is Architecture? SEI @ Carnegie Mellon A software architecture is an abstract view of a software system distinct from the details of implementation, algorithms, and data representation. Why Architecture Matters Accidental Architecture Grady Booch Every… system has an architecture. While some of these architectures are intentional, most appear to be accidental Waterfall Process Requirements Analysis Design Code and Test Integration System Test Waterfall Process Requirements Analysis Analysis Paralysis Design Design divorced from reality Code and Test Massive Integration Integration System Test Manifesto for Agile Software Development We are uncovering better ways of developing software by doing it and helping others do it. Through this work we have come to value: Individuals and interactions over processes and tools Working software over comprehensive documentation Customer collaboration over contract negotiation Responding to change over following a plan That is, while there is value in the items on the right, we value the items on the left more. Scrum: An agile Process Techies crave Extremes Architect Code Functional requirements What the system should do. • Use cases, User stories, acceptance criteria • Defines passing QA • Day to day you focus on this Nonfunctional requirements What the system should be. • Extremely expensive or impossible to “fix” later on • Defined passing Production • Assumed by your customers and users Nonfunctional Requirements • • • • • • Availability Stability Efficiency Reliability Maintainability Extensibility • • • • • • Fault Tolerance Security Capacity Latency Flexibility Scalability Functional: Passed QA Beautiful site (in my opinion) Easy to use Nonfunctional: Failed Production Availability Stability Latency Capacity Throughput Architecture There is no best architecture Pacemakers and Guided Missiles The Flying Buttress Patterns Example: Layered Architecture Three Tier Architecture The classic 3 tier architecture N-Tier Architecture Because three tiers wasn’t enough! N-Tier Architecture SMS SHAREPOINT IIS BIZTALK Windows Server 2008 SQL SERVER License management Questions about Architecture? Distributed Architecture Michael T. Nygard Designs appropriate for small brochureware websites fail outrageously when applied to thousanduser, transactional, distributed systems... Key Constraints on Distributed Systems • • • • • Stability Reliability and fault tolerance Consistency Capacity and Scalability Security Scenario: Stability You are the lead developer on a national health care site that will register millions of users a week. You are responsible for the signup process. Your team must verify the identity of users with a third party API. You call the service and the third party system will return a boolean true if the identity is valid or false otherwise. private string Register(RegistrationInfo registrationInfo) { try { bool validIdentity = identityService.verifyIdentity(registrationInfo); if (validIdentity) { database.save(registrationInfo); return “register_success.htm"; } return “register_failure.htm"; } catch (Exception) { return "errorpage.htm"; } } Stability 1. Register 6. Registered 2. Verify Site Server 3. Verified 4. Save User 5. User Saved Database Identity Verification Unbalanced Capacities 1. Register 6. Registered 2. Verify Site Server 3. Verified 4. Save User 5. User Saved Database Identity Verification Blocked Threads Verify joe Verify joe joe verified joe verified Verify sally Site Server Verify sally Verify bob Verify bob Verify bob Verify bob Verify bob Verify bob Identity Verification Cascading Failures Site Server Site Server Site Server Site Server Pattern 1: Timeouts private string Register(RegistrationInfo registrationInfo) { try { identityService.Timeout = 10000; bool validIdentity = identityService.verifyIdentity(registrationInfo); if (verified) { db.save(registrationInfo); return “register_success.htm"; } return “register_failure.htm"; } catch (Exception) { return "errorpage.htm"; } } Pattern 1: Timeouts Site Server Identity Verification Pattern 2: Non-blocking I/O private void BeginRegister(RegistrationInfo registrationInfo, Function<string> callback) { try { identityService.EndIdentity += identityService_EndIdentity(callback) identityService.BeginIdentity(registrationInfo); } catch (Exception) { callback("errorpage"); } } private void identityService_EndIdentity(bool success, Function<string> callback) { if (success) { callback("register_success.htm"); } callback("register_failure.htm"); } Pattern 2: Non-blocking I/O Site Server Identity Verification For Users… == The site is stable. We’re still failing. What’s the president recommending? What might be happening Thank you. We’ll email you when you are verified. What might be happening Identity Verification “The” Registration Process Udi Dahan When two principles are pushing in opposite directions, some underlying assumption is wrong. Often the word the is the culprit Read this again You are the lead developer on a national health care site that will register millions of users a week. You are responsible for the signup process. Your team must verify the identity of users with a third party API. You call the service and the third party system will return a boolean true if the identity is valid or false otherwise. Pattern 3: Decoupling Thank you. We’ll email you when you are verified Site Server Pending Registration Database Pattern 3: Decoupling Pending Registration Database Verification Application Identity Verification Scenario 2: Reliability You are the lead developer on a hospital’s prescription filling service. Your RX wholesaler has provided you with an HTTPS endpoint to integrate with. It is critical a prescription is not accidently prescribed twice and that prescriptions are not lost. Reliability 1. Prescribe 5. Success 2. Fill RX Site Server 3. RX ID 4. RX ID and Fill Info 5. Record Updated Database RX Service Invoking the Service private string Prescribe(PrescriptionInfo prescriptionInfo) { try { RxService rxService = new RxService(); int rxID = rxService.Prescribe(prescriptionInfo); database.Save(rxId, prescriptionInfo); return "success.htm"; } catch (Exception) { return "errorpage.htm"; } } What if the network goes down? 2. Prescribe 1. Prescribe Site Server 404 Timeout RX Service Invoking the Service private string Prescribe(PrescriptionInfo prescriptionInfo) { try { RxService rxService = new RxService(); int rxID = rxService.Prescribe(prescriptionInfo); database.Save(rxId, prescriptionInfo); return "success.htm"; } catch (Exception) { return "errorpage.htm"; } } Can I retry? Site Server Prescribe RX Service 404 Timeout Got it, but I couldn’t get Back to you. Site Server Prescribe RX Service Pattern 1: Idempotency Site Server Prescribe RX Service 404 Timeout Got it, but I couldn’t get Back to you. Site Server Prescribe RX Service Sheesh… I already got it! What if the database is down? 1. Prescribe 5. Success 2. Fill RX Site Server 3. RX ID 4. Update Patient Record Database RX Service Invoking the Service private string Prescribe(PrescriptionInfo prescriptionInfo) { try { RxService rxService = new RxService(); int rxID = rxService.Prescribe(prescriptionInfo); database.Save(rxId, prescriptionInfo); return "success.htm"; } catch (Exception) { return "errorpage.htm"; } } Can We Guarantee this code? private string Prescribe(PrescriptionInfo prescriptionInfo) { try { RxService rxService = new RxService(); int rxID = rxService.Prescribe(prescriptionInfo); database.Save(rxId, prescriptionInfo); return "success.htm"; } catch (Exception) { return "errorpage.htm"; } } Pattern 2: Transactional Queues Transactional Queue 1. Prescribe 3. Pending Site Server Fill RX Message Queue Inserting into a Queue private string Prescribe(PrescriptionInfo prescriptionInfo) { try { Queue.save(new RXPrescribeMessage(prescriptionInfo)); return "rxPending.htm"; } catch (Exception) { return "errorpage.htm"; } } Transactional Queue rxPrescribeMessage Queue rxDBUpdateMessage Fill rx Handler rx ID RX Service Transactional Queue Queue rxDBUpdateMessage Handler Save rx Database Message Handlers public void HandleRXPrescribeMessage(RXPrescribeMessage message) { var prescriptionInfo = message.prescriptionInfo; RxService rxService = new RxService(); int rxID = rxService.Prescribe(prescriptionInfo); Queue.save(new RXDBUpdateMessage(rxID, prescriptionInfo)); } public void HandleDBUpdateMessage(RXDBUpdateMessage message) { var rxId = message.rxID; var prescriptionInfo = message.prescriptionInfo database.Update(message.rxID, message.prescriptionInfo) } Nygard, Michael T. Cynical software expects bad things to happen and is never surprised when they do. Cynical software doesn’t even trust itself.. It refuses to get too intimate with other systems, because it could get hurt.