# Architecture

Earlier we discusssed standalone architectures. Now we'll look at how to structure an application that is distributed across multiple systems. How can you leverage cloud resources? How would you fetch from a remote service, or save to a cloud database?

# Styles

# Client-Server

A client-server architecture breaks an application into a client (front-end) and remote server (back-end) which handles data processing and/or storage. This is a logical extension to a layered architecture, where we can move some of the processing (typically the persistance layer) to a different system.

Client-server pattern, where clients initiate sessions with a shared server; clients do not communicate with one another
Client-server pattern, where clients initiate sessions with a shared server; clients do not communicate with one another

One things that characterizes client-server from other distributed styles is that it relies on a request-response model: the client requests data from the server, which performs the required work, forms a response and returns it to the client. The server cannot initiate a conversation - it can only reply to requests that are initiated by the client.

This model is perfectly fine for specific scenarios. e.g., a web browser contacting a web server. However, it's not suitable for all types of networked applications.

Web server in action
Web server in action

Quality Score Comments
Usability High In combination with some other pattern
Extensibility Low It's a pretty rigid structure
Scalability Low Difficult to add more servers
Robustness Low Single point of failure
Reusability Medium Server can be repurposed

# Peer-to-Peer

https://en.wikipedia.org/wiki/Peer-to-peer

A peer-to-peer network attempts to overcome the restrictions of a simple client-server network, by allowing peers to communicate with one another. This approach makes sense in scenarios where you don't have centralized data to share. Examples are messaging clients, or peer-to-peer file-sharing where there is no single authority.

Of course, "sharing responsibility" means that you need specific mechanisms in place so that peers can communicate. e.g., how to peers "find" one another? how do they authenticate and handle security?

Peer-to-Peer network, where all peers are free to communicate with one another; a server is just another peer and is not strictly required
Peer-to-Peer network, where all peers are free to communicate with one another; a server is just another peer and is not strictly required

Quality Score Comments
Usability High In combination with some other pattern
Extensibility Low It's a pretty rigid structure
Scalability Low Difficult to add more servers
Robustness Low Single point of failure
Reusability Medium Server can be repurposed

# Broker

The Broker pattern (re)introduces a server to act as an intermediary in a distributed network. It can handle peer identification (i.e. contact the server to get a list of peers), resource allocation (what services are available?) and even authentication (as as central sign-in authority).

A broker acts as an intermediary between resources on a network
A broker acts as an intermediary between resources on a network

Quality Score Comments
Usability High In combination with some other pattern
Extensibility Low It's a pretty rigid structure
Scalability Low Difficult to add more servers
Robustness Low Single point of failure
Reusability Medium Server can be repurposed

# Microservices

A services-based architecture splits functionality into small "portions of an application" (also called domain services) that are independent and separately deployed. This is demonstrated below with a separately deployed user interface, a separately deployed series of coarse-grained services, and a monolithic database. Each service is a separate monolithic application that provides services to the application, and they share a single monolithic database.

Services Architecture
Services Architecture

Each service provides coarse-grained domain functionality (i.e. operating at a relatively high level of abstraction) and addresses a particular business-need. e.g. a service might handle a customer checkout request to process an order.

Working at a coarse-grained level of abstraction like this means that these types of services can rely on regular ACID (atomicity, consistency, isolation, durability) database transactions to ensure data integrity. In other words, since the service is handling the logic of the entire operation, it can consolidate all of the steps in a single database transaction. If there is a failure of any kind, it can report the status to the customer and rollback the transaction.

e.g. a customer purchasing an items from your online storefront: the same service can handle updating the order details, adjusting available inventory and processing the payment.

# Required Features

As soon as you start to think about a distributed system, you need to consider how you will handle a number of features that are not present in a standalone system.

  • How do you find the remote service to connect to?
  • How do you know who is making a request? How do you know that they are who they say they are? How do you know that they are allowed to make that request?
  • What do you do if you can't connect? What if it doesn't respond? What if it responds slowly?

# Discovery

# Authentication

# Error Handling

# Concurrency