So you’re implementing or maintaining an mid to large size enterprise system, and you’ve got a large piece of business logic that’s shared across many components within that system. Examples would be inventory checking, address validation, or email notifications.
In a system that grows organically, what often happens is that the chunk of biz logic is first created as its own module which is then compiled into the deployed artifact. As the system grows, that functionality is needed in more places for scaling or because the logic contained in it is needed by more and more of the business silos, so the module is compiled into other artifacts and deployed all over the place.
Consider a system that uses an Address Validator service. In this diagram, the Address Validator business logic is compiled into every application that needs it.
If you anticipate that happening, or already see it in the system you’re maintaining, try implementing a remote service that your code makes request to, instead of compiling all that business logic into every component.
Here are some advantages of putting the functionality into a remote service.
1. Reduce maintenance outages. The more nodes that use the functionality, the better outcome you get from deploying the functionality as a standalone service. New enhancements or bug fixes can be added to a standalone service without redeploying the client code, and if you make your standalone service HA, the client code won’t experience any downtime.
2. Decrease size of deployed artifacts. Replacing significant business logic in a client with the remote service client is very likely to reduce the total size of what you are deploying. Most components use a database (itself an example of a remote service), but if you need to deploy any significant data along with the artifact, that’s a good indicator it should be a remote service.
3. Reduced coupling. It’s likely any decent sized set of business functionality logic itself has connections out to databases or external web services. If the functionality is deployed in multiple places, every instance will need to communicate with those external services, and carry the baggage associated with it (like failover logic, client code like JDBC, etc.).
4. You can size the hardware more appropriately for the service. Maybe it needs tons of RAM but not much CPU. Maybe it needs lots of disk. By moving it to right-sized hardware, you can reduce your overall hardware expense.
5. The service can be language agnostic. If you’re working in a polyglot organization, a remote service that exposes its interfaces through HTTP, message queues, file drop boxes, or some other language-independent mechanism can now be used by most programming language.
Now let’s move the Address Validator into its own remote service. The resulting architecture is simplified for the better.
Deploying as an external service does comes with costs.
- You need to find a place for it to live – maybe several places if you want it to be scalable or HA.
- You need to implement a remote service interface.
- You may want to set up monitoring for the new system
- Marshalling and unmarshalling the request/response data uses more CPU and adds latency.
However, in many cases, the cost is worth the gain.
Pingback: Dialed In - The Bandwidth Blog | A Recipe for Adding Correlation IDs in Java Microservices
Pingback: A recipe for adding correlation IDs in Java Microservices - Bandwidth