This is the third in a series of technical blog posts contributed by VanHackers. Today’s post is by Olutunde M.
Olutunde started his career as a Business/Technical Analyst for school software projects in 2009. He has now worked on 50+ projects; some used by as many as twenty-two banks in Nigeria. He has trained hundreds of developers in various Java technologies such as Java Fundamentals, Web services with REST and SOAP, JMS, JPA, Android apps development, Web design, Java security, and Cryptography.
Do you want to write a blog for us? Click here
Traditional Java software development typically produces a piece of software in a single codebase, that had to be deployed as a single jar/war file. This is after following best practices and popular design patterns (e.g. separation of the application into presentation, service, persistence layers, etc.) This is referred to as monolithic, implying a single codebase containing all the software features.
But as software development evolved, new concepts like Microservices, Agile, Scrum, etc have surfaced and more and more companies from startups to giants are now embracing them.
Although the monolithic approach has many advantages, Microservices architecture has been proven to solve some of the major problems of monolithic architecture.
What is a microservices architecture
Microservices is an architectural style that structures an application as a collection of services for high maintainability, testability, loose coupling, independently deployability, organized around business capabilities, and owned by a small team.
The microservice architecture allows rapid, frequent, and reliable delivery of complex applications. It also allows companies to embrace new technology stack based on human resource availability and the concept of ‘the best tool for the job’.
Having spent the last couple of weeks implementing a Microservices architecture from the ground up with Spring Cloud, here are a few things I learned about microservices that I think anyone with the intent of implementing the architecture should know.
- Complexity: Microservices is not just Service Oriented Architecture (SOA) with a couple of APIs, it is a full-blown architecture, and implementing one is a lot harder and more complex than it seems on the surface.
- Security: How do you manage security for 10 or more independent services? Do you terminate the security check at the load balancer/router or will each microservice need to authenticate and authorize requests? The architecture requires a token-based Single Sign-On (SSO) of some sort to handle user signup/login, token generation, and authorization by roles and privileges, etc. Standing up an OAuth2 server (or using a 3rd party service like google or okta.com) is your best bet for SSO. Do not come up with a custom (token-based or not) security implementation, it’s better to use the proven ones out there.
- Endpoint management and routing: If we break a monolithic application into 10 or more services with each service on a different server and/or different ports, each communicating by RESTful web service, we are going to end up with that many APIs in the least and eventually it will become hard to manage because every client of our system will need to keep track of our 10 endpoints and what resource is available at each one. To solve this problem, we will need to implement a reverse proxy service to handle internal routing and give our entire system a single entry point. I am not aware of how you can use Apache or Nginx for this, you will need to build your own. See the next point for the reason.
- Service Registry: A service registry is where all your microservices will automatically register themselves (their IP and ports) at their boot time. This registry needs to be available to the reverse proxy server. The reverse proxy server will depend on it to pull the list of available services and be able to route incoming requests accordingly. I’m not aware Apache or Nginx can do this.
- Load balancing: You need a load balancer to handle internal load within the services’ multiple instances. Since one of the advantages of microservices is the ability to scale up or down each service based on load and other factors, your architecture needs to be able to load-balance internally. Your reverse proxy can be designed to serve this purpose alongside its other job.
- Logs and Logging: How do you manage logs coming from all your 10 to 15 micro-services and find errors and bugs? You need a centralized log collection system. Crazy, ain’t?
- Configuration management: What happens if you migrate one or more services from one server to another (an IP or port change). Do you need to update and redeploy other services that are already configured to use the old IP and/or ports? This problem is solved by implementing two utility microservices: a. A centralized configuration management system and b. A service registry (as described above) where all services can automatically register themselves upon startup. A centralized configuration management service allows all the services to use a ‘single configuration file’. And a service registry allows services to find each other by name instead of by IP address and port.
- Centralized session: This is optional, but it’s better to implement a centralized session (cache) management system as well. This will allow services access to objects in the cache saved by other services. A file-based session or cache cannot work for this, you will have to use Redis, Memcached, or a database.
By the time you’re done with this architecture, you would have built 5 to 6 microservices just to manage your system. That is beside the business-related microservices that still need to be built. Below are the likely infrastructure services:
A. Configuration service.
B. Service registry.
C. Proxy & load balancing service.
D. OAuth2 Authentication service.
E. Metrics and Log service.
F. Session management service.
[Some of these services can be combined, I only listed them separately for readability. And again, there is no harm if they’re implemented separately.]
Building all these (micro-) services is one part of the job, testing, tracing errors and bugs, deployment, and maintaining them is another. You will need some form of CI/CD and DevOps system to make these jobs easier.
I learned a lot during this process, and I hope that I’ve been able to help you think about Microservices in a new way!