Showing posts with label cloud native java. Show all posts
Showing posts with label cloud native java. Show all posts

From Microservices to Service Blocks using Spring Cloud Function and AWS Lambda

Thursday, July 6, 2017

This blog post will introduce you to building service block architectures using Spring Cloud Function and AWS Lambda.

What is Spring Cloud Function?

Spring Cloud Function is a project from Pivotal that brings the same popular fundamentals behind Spring Boot to serverless functions.

Service Block Architecture

One of the most important considerations in software design is modularity. If we think about modularity in the mechanical sense, components of a system are designed as modules that can be replaced in the event of a mechanical failure. In the engine of a car, for example, you do not need to replace the entire engine if a single spark plug fails.

In software, modularity allows you to design for change.

Modularity also gives developers a shared map that can be used to reason about the functionality of an application. By being able to visualize and map out the complex processes that are orchestrated by an application’s source code, developers and architects alike can more easily visualize where to make a change with surgical precision.

Changing software

In many ways, we should consider ourselves lucky to be building software instead of cars. Some of today’s most valuable companies are created using bits and bytes instead of plastic and metal. But despite these advances, the very best car company releases less often than the world’s very worst software company.

An application’s source code is a system of connected bits and bytes that is always evolving—one change after another. But, as the source code of a system expands or contracts, small changes require us to build and deploy entire applications.

To make one small code change to a production environment, we are required to deploy everything else we didn’t change.

When teams share a deployment pipeline for an application, teams become forced to plan around a schedule they have little or no control over. For this reason, innovation is stifled—as developers must wait for the next bus before they can get any feedback about their changes.

The result of building microservices is an ever increasing number of pathways to production. With more and more microservices, the amount of unchanged code per deployment decreases when measured across all applications. It’s the decomposition in microservices that ends up breeding lower unchanged code deployed over time—an important metric. Serverless functions can help to get this number even lower—as the unit of change becomes the function. But, how do microservices and serverless functions fit together?

Service Blocks

Service blocks are cloud-native applications that share many characteristics with microservices. The key difference with microservices is that a service block is a self-contained system that has multiple independently deployable units—mixing together serverless functions with containers.

Service Block Spring Cloud Function

While microservices can be created entirely as serverless functions, a service block focuses on a contextual model that combines together traditional "always-on" applications with portable on-demand functions.

The Patterns

The basic pattern of a service block combines a core application running in a container with a collection of serverless functions.

Service Block Patterns Spring Cloud Function

Building Event-driven Microservices Using CQRS and Serverless

Tuesday, January 31, 2017

This blog series will introduce you to building event-driven microservices as cloud-native applications.

In this first post, we’ll explore how to implement the CQRS pattern in microservices. We’ll also dive into why serverless is a natural fit for these kinds of systems. Later in the series we’ll explore a reference application that uses Spring Cloud Stream to implement CQRS.

What is an event-driven architecture?

Event-driven architectures treat domain events as first-class citizens. This approach is as old as software itself.

One example we use every day is in front-end applications. In every web browser in use today, events are handled as a way to capture inputs of a user form. Events connected to page elements are handled by an explicitly mapped function, sometimes referred to as an action or command, which will apply state changes to a user interface when triggered.

Now, more recently, with the widespread adoption of microservices, there is renewed interest in how to take advantage of event-driven techniques in distributed back-end systems.

CQRS

One of the most popular practices in event-driven architectures today is called CQRS, which is short for Command Query Responsibility Segregation. CQRS is a style of architecture that allows you to use different models to update and read domain data.

CQRS model

The basic idea of CQRS is that it’s perfectly natural to need to separate the models you’re using to update and read data. The diagram above shows this basic idea.

Building Spring Cloud Microservices That Strangle Legacy Systems

Tuesday, August 30, 2016

It’s safe to say that any company who was writing software ten years ago—and is building microservices today—will need to integrate with legacy systems. In this article, we will explore building cloud-native microservices that still need to integrate with legacy systems. We’ll use practices from Martin Fowler’s Strangler Application to slowly strangle domain data away from a legacy system using microservices.

When building microservices, the general approach is to take existing monoliths and to decompose their components into new microservices. The most critical concerns in this method have much less to do with the application code and more to do with handling data. This article will focus on various methods of strangling a monolith’s ownership of domain data by transitioning the system of record over time.

Throughout this article, we’ll use a reference application built with Spring Boot and Spring Cloud. The example demonstrates techniques for integrating a cloud-native microservice architecture with legacy applications in an existing SOA.

Going Cloud Native

Many companies want to start taking advantage of the public cloud without having to migrate every line of business application at the same time. The reasons for this are numerous. The existing line of business applications can be thought of as the vital organs of a living organism. During the migration, think about the complex relationships between the existing components deployed to your infrastructure. Think about the dependencies of your applications and the connections between them. Think about every application that relies on a database or network file system. These are among the many considerations that will cause a migration to become an expensive and time-consuming project.

Hybrid cloud data center integration

The unfathomable complexity of migrating applications to the cloud can delay a decision from being made until the business deems necessary, which is usually triggered by a major event that results in a loss of revenue. This ticking time bomb will result in a lift-and-shift migration of applications. The problem with the lift and shift approach is that any technical debt that you had on-premises finds new life in the cloud environment. The problem being, the architectural and infrastructure issues that triggered the cloud migration still may not be fixed.

The approach I discuss in this article focuses on addressing the underlying symptoms of legacy systems that decrease system resiliency and lead to costly failures.

Event Sourcing in Microservices Using Spring Cloud and Reactor

Tuesday, April 19, 2016

When building applications in a microservice architecture, managing state becomes a distributed systems problem. Instead of being able to manage state as transactions inside the boundaries of a single monolithic application, a microservice must be able to manage consistency using transactions that are distributed across a network of many different applications and databases.

In this article we will explore the problems of data consistency and high availability in microservices. We will start by taking a look at some of the important concepts and themes behind handling data consistency in distributed systems.

Throughout this article we will use a reference application of an online store that is built with microservices using Spring Boot and Spring Cloud. We’ll then look at how to use reactive streams with Project Reactor to implement event sourcing in a microservice architecture. Finally, we’ll use Docker and Maven to build, run, and orchestrate the multi-container reference application.

Eventual Consistency

When building microservices, we are forced to start reasoning about state in an architecture where data is eventually consistent. This is because each microservice exclusively exposes resources from a database that it owns. Further, each of these databases would be configured for high availability, with different consistency guarantees for each type of database.

Eventual consistency is a model that is used to describe some operations on data in a distributed system—where state is replicated and stored across multiple nodes of a network. Typically, eventual consistency is talked about when running a database in high availability mode, where replicas are maintained by coordinating writes between multiple nodes of a database cluster. The challenge of the database cluster is that writes must be coordinated to all replicas in the exact order that they were received. When this happens, each replica is considered to be eventually consistent—that the state of all replicas are guaranteed to converge towards a consistent state at some point in the future.

When first building microservices, eventual consistency is a frequent point of contention between developers, DBAs, and architects. The head scratching starts to occur more frequently when the architecture design discussions begin to turn to the topic of data and handling state in a distributed system. The head scratching usually boils down to one question.

How can we guarantee high availability while also guaranteeing data consistency?

To answer this question we need to understand how to best handle transactions in a distributed system. It just so happens that most distributed databases have this problem nailed down with a healthy helping of science.

Transaction Logs

Mostly all databases today support some form of high availability clustering. Most database products will provide a list of easy to understand guarantees about a system’s consistency model. A first step to achieving safety guarantees for stronger consistency models is to maintain an ordered log of database transactions. This approach is pretty simple in theory. A transaction log is an ordered record of all updates that were transacted by the database. When transactions are replayed in the exact order they were recorded, an exact replica of a database can be generated.

Eventual consistency diagram

The diagram above represents three databases in a cluster that are replicating data using a shared transaction log. The zipper labeled Primary is the authority in this case and has the most current view of the database. The difference between the zippers represent the consistency of each replica, and as the transactions are replayed, each replica converges to a consistent state with the Primary. The basic idea here is that with eventual consistency, all zippers will eventually be zipped all the way up.

Building Microservices with Polyglot Persistence Using Spring Cloud and Docker

Tuesday, August 25, 2015

This series continues from the last blog post about building microservices using Spring Cloud. This post has two parts. The first part describes how to create cloud-native data services using Spring Boot. The second part is a companion example project that uses Docker Compose to run multiple microservices locally to simulate a polyglot persistence setup.

What is polyglot persistence?

Polyglot persistence is a term that describes an architecture that uses a collection of different database solutions as a part of a platform’s core design. More plainly, each backing service is managed from an exclusive connection to a Spring Boot service that exposes domain data as HTTP resources.

The central idea behind polyglot persistence is that service architectures should be able to utilize the best languages for the job at hand. There is no clear definition of how to do this well, and it tends to evolve organically as central databases become cumbersome when required to add new features.

Spring Boot Roles

When designing microservices that manage exclusive access to multiple data providers, it can be useful to think about the roles in which your microservices will play.

We can think of a Spring Boot application as the basic building block for our microservice architecture.

Microservice Roles
Figure 1. Each Spring Boot application plays a role when integrating with other services

The diagram above describes six Spring Boot applications that are color coded to describe the role they play when integrated using Spring Cloud.

Data Services

Each Spring Boot application in a microservices architecture will play a role to varying degrees of importance. The data service role is one of the most important roles in any setup. This role handles exposing the application’s domain data to other microservices in the platform.

Polyglot Data Services

The diagram below describes an example microservice architecture with multiple Spring Boot applications that expose data from multiple database providers.

Polyglot Persistence Microservices
Figure 2. Example Polyglot Persistence Architecture