Modern Web-Based Application Architecture 101This article is meant to provide a high-level overview of how a web-based application is commonly structured nowadays. Keep in mind the topic presented is very simplified. It is meant as an introduction only and hopefully encourages the reader to investigate some of the concepts in more depth.

Monolith vs Microservices

With the rise of containerization and microservices, applications nowadays tend to be composed of loosely coupled services that interact with each other. For example, an e-commerce site would have separate “microservices” for things like orders, questions, payments, and so on.

In addition to this, data is oftentimes geographically distributed in an effort to bring it closer to the end-user.

For example, instead of having a single database backend, we can have N smaller database backends distributed across different regions. Each of these would hold a portion of the data set related to the users located closer to it.

The Many Faces of Caching

As traffic grows, eventually the database + application servers combination is no longer the best cost-effective way to scale. Instead, we can do so by introducing some additional elements, each of these targeting a specific part of the user experience.

Here’s how things would look like from a single microservice’s perspective:

Modern Application Architecture

Starting from what’s closest to the end-user, let’s briefly describe all these components.

Content Delivery Networks

You can think of the content delivery network (CDN) as a geo-distributed network of proxies with the goal of improving the response times for the end-user.

CDN were traditionally used to cache “static” assets like web objects, downloadable files, streaming media, etc. Nowadays they can also be used to deliver some dynamic content as well.

Popular providers include Akamai, Cloudflare, and Fastly.

HTTP Caches

The HTTP cache or web accelerator layer is typically deployed between the web servers and the CDN.

Their purpose is to reduce the access times using a variety of techniques (like caching, prefetching, compression, etc) while also reducing resource utilization on the application servers.

For example, Varnish is a web application accelerator for content-heavy dynamic websites that caches HTTP requests and functions as a reverse proxy. Other examples include nginx and squid.

Database Caches

Next comes the database cache layer. This usually consists of an in-memory key/value store that stores results of read database queries, allowing to scale reads without introducing additional database servers.

Cache invalidation can be performed explicitly from the application or simply by defining a TTL for each object.

One important point to consider in regards to caching is that there might be application flows that require strict read-after-write semantics.

Some commonly used solutions for database caching are Redis and Memcached.

The Data Layer

Finally, the data layer can include online transaction processing (OLTP) and analytics/reporting (DW) components.

To scale the database, we have to consider reads and writes separately. We can scale reads by introducing replicas, while for writes we can do data partitioning or sharding.

For the data warehouse, there are many possibilities, even using a general-purpose database like MySQL. One might want to also consider a columnar storage, which is typically better for analytic queries (e.g. Clickhouse).

The data warehouse is refreshed periodically via an ETL process. Some of the available solutions for ETL include Fivetran and Debezium.

Queues

There are some special considerations for write-intensive services. For example, data sources sending a continuous stream of data, or things like incoming orders which might have “spikes” at certain times.

It is a common pattern to deploy a queueing system (like Activemq), or a more complex streams-processing system (like Apache Kafka) in front of the database layer.

The queue acts as a “buffer” for the incoming data sent by the application. Since we can control the amount of write activity the queue does, we avoid overloading the database when there is a spike of requests.

Final Words

These are just some of the patterns used to architect modern web applications in a cost-effective and scalable way, some of the challenges frequently encountered, and a few of the available solutions to help overcome them.

Subscribe
Notify of
guest

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Ankit Kapoor

nice. Crisp and informatory. Liked it.