0

I am working on a project in which we'll deploy a full Spring Boot microservices architecture, along with supporting services like load balancing, service registry, edge server, and centralized monitoring.

I have a single project that will be shared among all core microservices which contains DAOs and all the dependencies for the core microservices. I am hoping to be able to release one ~60Mb jar, and have the other Spring Boot core microservices be very lightweight (<1Mb). At runtime the core microservices will reference the shared jar on their classpath.

The way I've set the project up is to have separate project, with a structure like so:

|shared_project
|pom.xml

|ms-1
|pom.xml

|ms-2
|pom.xml

The shared project uses maven-assembly-plugin to create a big jar and copies it to my local .m2 repo. The ms-1 and ms-2 poms use maven-jar-plugin to create their jars and have one dependency, the shared project.

I'm sure this is not the best way to handle this. It's creating issues during unit tests and I have to imagine it'll create issues down the line. I've seen this done using parents in the pom file, nesting the project inside another directory, and other ways.

What I am wondering is what is the best practice regarding keeping your Spring Boot projects' dependencies and shared code centralized and externalized through use of Maven, such that the projects that you are frequently rolling are kept lightweight and decoupled?

Bonus questions:

  1. Does the fact that we'll be using Jenkins/TeamCity for CI and automated testing affect the answer?

  2. Does having one shared jar on the filesystem which each project references in its classpath during startup pose any challenges? Depending on demand, we may flexibly spin up 10 instances of microservice-1 and only 3 of microservice-2.

EDIT: I think this already has a good answer here: Parent pom and microservices

Community
  • 1
  • 1
Jonas Schreiber
  • 447
  • 4
  • 13
  • 1
    I think part of the reason you are facing a challenge with this arrangement, is that it is not really common practice to share anything between microservices. Good or bad it is common to have duplicate code within a service. That being said, look at your service and split in a way that you minimize have the overlap. Don't make them small for the sake of making them small. – code Jul 16 '16 at 05:26
  • yeah maybe I'm overoptimizing the deployment before they've been written I guess. I just don't want to set a bad precedent for others to follow. I'm definitely not writing the same code in 5 different places though. That would be insane. I'll just include it as a dependency and let it streamline naturally. – Jonas Schreiber Jul 16 '16 at 06:20
  • Does this answer your question? [Parent pom and microservices](https://stackoverflow.com/questions/27865238/parent-pom-and-microservices) – twobiers Aug 06 '20 at 12:36

2 Answers2

2

Sorry to reply 2 years later but it was my first hit on the search engine. You are mentioning sharing DAO, etc. but as much as I understand micro services, isn't it one of the main goals to don't share DAO at all. Does not this structure ruins actually your micro services architecture? Any feedback on this 2 years later? ;)

But I do agree, that there is a really small code base which can be shared. But it's only some basic utils, exceptions base, etc. so really basic stuff which could be shared among any project in a company.

I would never create a shared core code base or/and a deployment with dependencies to external jars. For my understanding the deployment of a micro services, based on java, must be as simple as "java -jar application.jar" ... makes local testing, CI, deployment and replacement of an application so easy

Wondering about other opinions

happy coding ;)

David M.
  • 77
  • 1
  • 13
0

This is what we do in our enterprise applications:

Create a new maven project which will serve as an uber jar for all projects. Add all the applications you need as an dependency in this project. Add maven shade plugin in this. Create a runner class with public static void main(String[] args) in this uber jar which initialises all beans and starts all applications.

Hope it helps.

Rishabh Agarwal
  • 1,988
  • 1
  • 16
  • 33