Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Microservices with Go

You're reading from   Microservices with Go Building scalable and reliable microservices with Go

Arrow left icon
Product type Paperback
Published in Nov 2022
Publisher Packt
ISBN-13 9781804617007
Length 328 pages
Edition 1st Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Alexander Shuiskov Alexander Shuiskov
Author Profile Icon Alexander Shuiskov
Alexander Shuiskov
Arrow right icon
View More author details
Toc

Table of Contents (19) Chapters Close

Preface 1. Part 1: Introduction
2. Chapter 1: Introduction to Microservices FREE CHAPTER 3. Part 2: Foundation
4. Chapter 2: Scaffolding a Go Microservice 5. Chapter 3: Service Discovery 6. Chapter 4: Serialization 7. Chapter 5: Synchronous Communication 8. Chapter 6: Asynchronous Communication 9. Chapter 7: Storing Service Data 10. Chapter 8: Deployment with Kubernetes 11. Chapter 9: Unit and Integration Testing 12. Part 3: Maintenance
13. Chapter 10: Reliability Overview 14. Chapter 11: Collecting Service Telemetry Data 15. Chapter 12: Setting Up Service Alerting 16. Chapter 13: Advanced Topics 17. Index 18. Other Books You May Enjoy

Motivation to use microservices

In order to understand the motivation behind using the microservice architecture, it is very important to see the opposite approach – when the application is built and executed as a single program. Such applications are called monolithic applications or monoliths.

Monolithic architecture is, in most ways, the simplest model to implement since it does not involve splitting the application into multiple parts that need to coordinate with each other. This can provide you with major advantages in many cases, such as the following:

  • Small code base: Splitting an application into multiple independent parts may significantly increase the size of the code base by introducing extra logic required for communication between the components.
  • Application logic is still loosely defined: It is very common that parts of the application or the entire system go through major structural or logical changes, especially at the very early stages of development. This might be caused by a sudden change of requirements, priorities, changes in the business model, or a different approach to development. During the early stages of development, iterating fast can be critical not only to the development process, but also to the entire company.
  • Narrow scope of the application: Not every service requires a decomposition and division into separate parts. Consider a service for generating random passwords – it has a single logical feature and, in most cases, it would be unnecessary to split it into multiple parts.

In all of the preceding cases, monolithic architecture would be a better fit for the application. However, at some point, services get too big to remain monolithic. Developers start experiencing the following issues:

  • Large application size and slow deployments: At a certain point, an application can become so big that it can take minutes or even hours to build, start, or deploy.
  • Inability to deploy a particular part of the application independently: Not being able to replace a part of a large application can easily become a bottleneck, slowing down the development and release process.
  • Higher blast radius: If there is a bug in a certain function or library widely used across the application code, it is going to affect all parts of the system at once, potentially causing major issues.
  • Vertical scalability bottleneck: The more logic the application has, the more resources it needs in order to run. At a certain point, it can get hard or impossible to scale the application up even further, given the possible limits on CPU and RAM.
  • Interference: Certain parts of the application can heavily load CPU, I/O, or RAM, causing delays for the rest of the system.
  • Unwanted dependencies between components: Having the entire application represented as a single executable leaves room for unnecessary dependencies between the components. Imagine a developer refactoring a code base, and making a change suddenly affects some important parts of the system, such as payments. Having more isolation between the components gives more protection against such issues.
  • Security: A possible security issue in the application may result in unauthorized access to all components at once.

In addition to the possible issues we just described, different components may have different requirements, such as the following:

  • Resources and hardware requirements: Certain components are more CPU-intensive or memory-intensive and may perform I/O operations at a higher rate. Separating such components may reduce the load on the entire system, increasing system availability and reducing latency.
  • Deployment cadence: Some parts of the system mostly remain unchanged while others require multiple deployments per day.
  • Deployment monitoring and automated testing: Certain components may require stricter checks and monitoring and can be subject to slower deployments due to multi-step rollouts.
  • Technologies or programming languages: It is not uncommon that different parts of the system can be written in different programming languages or use fundamentally different technologies, libraries, and frameworks.
  • Independent APIs: Components may provide fully independent APIs.
  • Code review process: Some components may be subject to a stricter code review process and additional requirements.
  • Security: Components may have different security requirements and may require additional isolation from the rest of the application for security reasons.
  • Compliance: Some parts of the system may be subject to stricter compliance requirements. For example, handling personally identifiable information (PII) for users from a certain region can put stricter requirements on the entire system. Logical separation of such components helps to reduce the scope of work required to keep the system compliant.

With all the preceding issues described, we can see that at a certain point monolithic applications can become too big for a one-size-fits-all model. As the application grows, certain parts of it may start becoming independent and have different requirements, benefiting from a logical separation from the rest of the application.

In the next section, we are going to see how splitting the application into microservices can solve the aforementioned problems and which aspects of it you should be careful with.

You have been reading a chapter from
Microservices with Go
Published in: Nov 2022
Publisher: Packt
ISBN-13: 9781804617007
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime