Designing a multi-layer system is not rocket science, the difficulty can lie in selecting the right technologies. The main concept behind the design is to have better control and fine tuning of the components. This blog post will discuss the benefits & limitations of implementing this type of design and our practical experience gained from using it for the Open Days reservation system, which helped to welcome 75.000 people on our site and was hosted on the Oracle cloud using their cloud services.
This post is part of the "Open Days reservation system - 2019" series. To learn more about the CERN Open Days project, read the following post.
The multi-layer system is not a new invention, it allows to combine technologies working together. The main idea behind it is to group functionalities and implement them using the best fitting programming framework / language, which can result in a fast and task optimized system.
- What are the interaction points of the system? (User interface(s))
- What is the status of the workflow and what changes are allowed during system usage? (Business logic)
- How can changes be applied in a trackable and reversible way (Data persistence)
Based on the answers to these questions we can have a simple or a complex implementation. The following diagram shows the difference between these two implementation possibilities. Note that the layout of the complex implementation strategy is only an example and the final design can be a subset or a more complicated solution made up of some of the visualized elements. (The cross-layer components of the complex strategy demonstrating the implementations of certain technologies like JAVA JSP, C# ASP.NET Web Forms, C# ASP.NET MVC, etc.)
A multi-layer design is very flexible, especially when it comes to selecting the technology of the architectural components. It allows the developer to use any combination of technologies as long as they support information exchange standards. Thanks to this feature architectural components are technology independent, which means that they can be replaced or reimplemented using another technology (i.e. given these meet the requirements of the replaced component) at anytime without adding additional risks to the system.
Design of the Open Days reservation system
Selecting the right software stack is a difficult task. The difficulty lies in forecasting future requirements of the system. It is possible to overcome this obstacle or at least be prepared for a technology shift, so the impact of any changes will be less severe. A multi-layer design aims to solve this by allowing different technologies to interact through standard interfaces(/messages), so at any point they can be replaced with the same functionality written in another language/framework. This allows for changes to the architectural components as the requirements of the system evolve over time.
- User interface layer: For this layer we chose the Angular framework. This framework is optimized to work fast for form applications. It requires following a strict coding standard, has a substantial active developer community and lots of feature libraries. It supports the re-use of written components, has an out of the box solution for internationalization and allows combination with Angular material design.
- Business logic layer: For this layer we chose the JAVA based Spring boot framework. This framework has a very well integrated third party collection set. It avoids the developer to deal with all the boiler-plate spring configuration. Its annotation support it makes the code simpler and more readable.
- Data persistence layer: For this layer we chose the Oracle Autonomous Transaction Processing (ATP) cloud database. It comes with auto update service for fixes and patches, plus it’s easy to scale resource allocation and thus helps to adjust the system based on its demand.
A well-built architectural design makes a big difference when a large stream of people are taking advantage of a system, but it is not the only significant feature. Introducing parallel task handling can also result in better resource performance and task management. It can help to distribute the usage of the system more uniformly between the components involved in execution of the system. This can be further improved by designing a stateless system. The concept behind this is to split a task into smaller subtasks so they can be carried out by any generic executor. So the components would be individually capable of making smaller changes and the sum of those small changes will result as the main task’s execution. Introducing a stateless design to your system allows you to scale the number of the system components more easier based on demand. The Open Days reservation system was designed stateless, which allowed us to use only the necessary amount of resources.
In order to make the components independently scalable we found it easy to follow the container-based approach. We used Docker containers for setting up individual building environments for the different layers. The containers were running on Kubernetes (K8s) clusters. The cluster deployments were completely automated using Terraform plans. These plans helped to interact with the Oracle Container Engine for Kubernetes (OKE) service, which is well integrated with the Oracle load balancer service. Thanks to the integration the configuration of traffic to the clusters was fast and easy.
The Open Days reservation system performed very well during its 2.5 months production time. Scaling of the layers individually took only a couple of minutes. This helped our organisation to better manage costs and resources. During the peak time our Kubernetes cluster was scaled to three times and the Autonomous Database to ten times its normal capacity. The system was stress tested, in just 6 minutes it was capable of handling the complete booking for 20,000 parallel users.
Pros and cons of a multi-layer system
A multi-layer design focuses on the fine tuning possibilities of a system by allowing various technologies to work well together. It works best using simple tasks and components dedicated to functionality as its layers. By using continuous integration & deployment (CI/CD) tasks, version management can become easier and simpler. With the right design, the root cause of a bug can be found faster. Adding stateless design on the top of the layer separation can improve the resource management.
Unfortunately, despite these benefits this approach also has some disadvantages. For example, the time spent on designing the system takes longer than usual, because it requires the developer to have a clear view of the system. Defining the communication standards between the layers / functional elements requires stricter rules than just designing a global solution.
Since this approach allows you to combine different technologies, it can increase the complexity of the system and also understanding how best to fine tune the layers requires higher professional knowledge.
Depending on the use case, deadlines, the clarity of the system’s purpose and the planned lifecycle, a multi-layer system approach can be a good choice. In the short term it can help the teams to reach their objectives faster and in the long run it can definitely pay off when a technology shift is required to withstand new emerging requirements.