Book Image

Cloud Native Applications with Ballerina

By : Dhanushka Madushan
Book Image

Cloud Native Applications with Ballerina

By: Dhanushka Madushan

Overview of this book

The Ballerina programming language was created by WSO2 for the modern needs of developers where cloud native development techniques have become ubiquitous. Ballerina simplifies how programmers develop and deploy cloud native distributed apps and microservices. Cloud Native Applications with Ballerina will guide you through Ballerina essentials, including variables, types, functions, flow control, security, and more. You'll explore networking as an in-built feature in Ballerina, which makes it a first-class language for distributed computing. With this app development book, you'll learn about different networking protocols as well as different architectural patterns that you can use to implement services on the cloud. As you advance, you'll explore multiple design patterns used in microservice architecture and use serverless in Amazon Web Services (AWS) and Microsoft Azure platforms. You will also get to grips with Docker, Kubernetes, and serverless platforms to simplify maintenance and the deployment process. Later, you'll focus on the Ballerina testing framework along with deployment tools and monitoring tools to build fully automated observable cloud applications. By the end of this book, you will have learned how to apply the Ballerina language for building scalable, resilient, secured, and easy-to-maintain cloud native Ballerina projects and applications.
Table of Contents (15 chapters)
1
Section 1: The Basics
4
Section 2: Building Microservices with Ballerina
8
Section 3: Moving on with Cloud Native

Evolution from the monolithic to the microservice architecture

The monolithic architecture dictated software development methodologies until cloud native conquered the realm of developers as a much more scalable design pattern. Monolithic applications are designed to be developed as a single unit. The construction of monolithic applications is simple and straightforward. There are problems related to monolithic applications though, such as scalability, availability, and maintenance.

To address these problems, engineers came up with the microservice architecture, which can be scalable, resilient, and maintainable. The microservice architecture allows organizations to develop increasingly flexible. The microservice architecture is the next step up from the Service-Oriented Architecture (SOA). Both these architectures use services for business use cases. In the next sections, we will follow the journey from the monolithic architecture to SOA to the microservice architecture. To start this journey, we will begin with the simplest form of software architecture, which is the N-tier architecture. In the next section, we will discuss what the N-tier architecture is and the different levels of the N-tier architecture.

The N-tier architecture in monolithic applications

The N-tier architecture allows developers to build applications on several levels. The simplest type of N-tier architecture is the one-tier architecture. In this type of architecture, all programming logic, interfaces, and databases reside in a single computer. As soon as developers understood the value of decoupling databases from an application, they invented the two-tier architecture, where databases were stored on a separate server. This allowed developers to build applications that allow multiple clients to use a single database and provide distributed services over a network.

Developers introduced the application layer to the two-tier architecture and formed the three-tier architecture. The three-tier architecture includes three layers, known as data, application, and presentation, as shown in the following diagram:

Figure 1.1 – Three-tier architecture

Figure 1.1 – Three-tier architecture

The topmost layer of the three-tier architecture is known as the presentation layer, which users directly interact with. This can be designed as a desktop application, a mobile application, or a web application. With the recent advancement of technology, desktop applications have been replaced with cloud applications. Computational power has moved from consumer devices onto the cloud platform with the recent growth of mobile and web technologies.

The three-tier architecture's middle layer is known as the application layer, in which all business logic falls. To implement this layer, general-purpose programming languages, along with supporting tools, are used. There are several programming languages with which you can implement business logic, such as Node.js, Java, and Python, along with several different libraries. These programming languages might be general-purpose programming languages such as Node.js and Java or domain-specific languages such as HTML, Apache Groovy, and Apache Synapse. Developers can use built-in tools such as API gateways, load balancers, and messaging brokers to develop an application, in addition to general-purpose programming languages.

The bottom layer is the data layer, which stores data that needs to be accessed by the application layer. This layer consists of databases, files, and third-party data storage services to read and write data. Databases usually consist of relational databases, which are used to store different entities in applications. There are multiple databases, such as MySQL, Oracle, MSSQL, and many more, used to build different applications. Other than using those databases, developers can select file-based and third-party storage services as well.

Developers need to be concerned about security, observability, delivery processes, deployability, and maintainability across all these layers over the entire life cycle of application development. With the three-tier architecture, it is easy and efficient to construct simple applications. Separating the application layer allows the three-tier architecture to be language-independent and scalable. Developers can distribute traffic between multiple application layer instances to allow horizontal scaling of the application. A load balancer sitting in front of the application layer spreads the load between the application instance replicas. Let's discuss monolithic application architecture in more detail and see how we can improve it in the next section.

Monolithic application architecture

The term "monolithic" comes from the Greek terms monos and lithos, together meaning a large stone block. The meaning in the context of IT for monolithic software architecture characterizes the uniformity, rigidity, and massiveness of the software architecture.

A monolithic code base framework is often written using a single programming language, and all business logic is contained in a single repository.

Typical monolithic applications consist of a single shared database, which can be accessed by different components. The various modules are used to solve each piece of business logic. But all business logic is wrapped up in a single API and is exposed to the frontend. The user interface (UI) of an application is used to access and preview backend data to the user. Here's a visual representation of the flow:

Figure 1.2 – A monolithic application

Figure 1.2 – A monolithic application

The scaling of monolithic applications is easy, as the developer can increase the processing and storage capacity of the host machine. Horizontal scalability can be accomplished by replicating data access layers and spreading the load of the client within each of these instances.

Since the monolithic architecture is simple and straightforward, an application with this paradigm can be easily implemented. Developers can start designing the application with a model entity view. This architecture can be easily mapped to the database design and applied to the application. It's also easy for developers to track, log, and monitor applications. Unlike the microservice architecture, which we will discuss later in this chapter, testing a monolithic application is also simple.

Even though it is simple to implement a monolithic application, there are lots of problems associated with maintaining it when it comes to building large, scalable systems:

  • Monolithic applications are designed, built, and implemented in a single unit. Therefore, all the components of the architecture of the system should be closely connected. In most cases, point-to-point communication makes it more difficult to introduce a new feature component to the application later.
  • As a monolithic application grows, it takes more time to start the entire application. Changing existing components or adding new features to the system may require stopping the whole system. This makes the deployment process slower and much more unstable.
  • On the other hand, having an unstable service in the system means the entire system is fragile. Since the components of a monolithic application are tightly coupled with each other, all components should function as planned. Having a problem in one subsystem causes all the dependent components to fail.
  • It is difficult to adopt modern technology because a monolithic application is built on homogeneous languages and frameworks. This makes it difficult to move forward with new technologies, and inevitably the whole system will become a legacy system.

Legacy systems have a business impact due to problems with the management of the system:

  • Maintaining legacy systems is costly and ineffective over time. Even though developers continue to add features, the complexity of the system increases exponentially. This means that organizations spend money on increasing the complexity of the application rather than refactoring and updating the system.
  • Security gets weaker over time as the dependent library components do not upgrade and become vulnerable to security threats. Migrating to new versions of libraries is difficult due to the tight coupling of components. The security features of these libraries are not up to date, making the system vulnerable to attacks.
  • When enforcement regulations become tidal, it gets difficult to adjust the structure according to these criteria. With the General Data Protection Act (GDPA) enforcement, the system should be able to store well-regulated information.
  • When technology evolves over time, due to compatibility problems, it is often difficult to integrate old systems with new systems. Developers need to add more adapters to the system to make it compliant with new systems. This makes the system a lot more complicated and bulkier.

Due to these obstacles, developers came up with a more modular design pattern, SOA, which lets developers build a system as a collection of different services. When it comes to SOA, a service is the smallest deployment unit used to implement application components. Each service is designed to solve problems in a specific business domain.

Services can be run on multiple servers and connected over a network. Service interfaces have loose coupling in that another service or client is able to access its features without understanding the internal architecture.

The core idea of SOA is to build loosely coupled, scalable, and reusable systems, where services work together to execute business logic. Services are the building block of SOA and are interconnected by protocols such as HTTP, JMS, TCP, and FTP. SOA commonly uses the XML format to communicate with other services. But interconnecting hundreds of services is a challenge if each service uses a point-to-point communication method. This makes it difficult to have thousands of links in interservice communication to maintain the system.

On the other hand, the system should be able to handle multiple different data formats, such as JSON, XML, Avro, and Thrift, which makes integration much more complicated. For engineers, observing, testing, migrating, and maintaining such a system is a nightmare. The Enterprise Service Bus (ESB) was introduced to SOA to simplify these complex messaging processes. In the next section, we will discuss what an ESB is and how it solves problems in SOA.

The ESB simplifies SOA

The ESB is located in the middle of the services, connecting all the services. The ESB provides a way of linking services by sitting in the center of services and offering various forms of transport protocols for communication. This addresses the issue of point-to-point connectivity issues where many services need to communicate with each other. If all of these services are directly linked to each other, communication is a mess and difficult to manage. The ESB decouples the service dependencies and offers a single bus where all of its services can be connected. Let's have a look at an SOA with point-to-point communication versus using an ESB for services to communicate:

Figure 1.3 – ESB architecture

Figure 1.3 – ESB architecture

On incoming service requests, the ESB may perform simple operations and forward them to another service. This makes it easier for developers to migrate to SOA and expose existing legacy systems as services so that they can be easily handled instead of creating everything from scratch.

An ESB is capable of managing multiple endpoints with multiple protocols. For example, an ESB can use the following features to facilitate the integration of services in SOA:

  • Security: An ESB handles security when connecting various services together. The ESB offers security features such as authentication, authorization, certificate management, and encryption to secure connected services.
  • Message routing: Instead of directly calling services, an ESB provides the modularity of SOA by providing routing on the ESB itself. Since all other services call the ESB to route services, developers can substitute service components without modifying the service.
  • Central communication platform: This prevents a point-to-point communication issue where each service does not need to know the address of the endpoint. The services blindly send requests to the ESB and the ESB routes requests as specified in the ESB routing logic. The ESB routes traffic between services and acts as smart pipes, and that makes service endpoints dumb.
  • Monitoring the whole message flow: Because the ESB is located in the center of the services, this is the perfect location to track the entire application. Logging, tracing, and collecting metrics can be placed in the ESB to collect the statistics of the overall system. This data can be used along with an analytical tool to analyze bugs, performance bottlenecks, and failures.
  • Integration over different protocols: The ESB ensures that services can be connected via different communication protocols, such as HTTP, TCP, FTP, JMS, and SMTP. It is also supported for various data interchange formats, such as JSON and XML.
  • Message conversion: If a service or client application is required to access another service, the message format may be modified from one to another. In this case, the ESB offers support for the conversion of messages across various formats, such as XML and JSON. It also supports the use of transformation (XSLT) and the modification of the message structure.
  • Enterprise Integration Patterns (EIP): These are used as building blocks for the SOA messaging system. These patterns include channeling, routing, transformation, messaging, system, and management. This helps developers build scalable and reliable SOA platforms with EIP.

SOA was used as mainstream cloud architecture for a long time until the microservice architecture came along as a new paradigm for building cloud applications. Let's discuss the emergence of the microservice architecture and how it solves problems with SOA in the next section.