skip to Main Content

I’m currently working on a project with some spring-boot based microservices. Currently every microservice has it’s own layered jar with the default spring boot layer configuration. This already reduces the number of different layers across minor version changes of the same microservice. But the many different microservices add up when needing to push container images to a customer.

However a lot of microservices share large parts of their dependencies. For example all use spring core and spring boot features. Most of them use spring-data-jpa. Some of them make use of a message broker, solr for search or spring-integration. And then there are features that are unique to only one microservice like there is one that needs to generate pdfs or another needs to send emails.

Am I somehow able to share common layers between different microservices? Like there is a layer containing spring-core and spring-boot and their transitive dependencies. And then there is a layer containing spring-data-jpa and it’s transitive dependencies excluding those from the spring-core and spring-boot layer. And so on ..

2

Answers


  1. In case there is a need to make deliverables smaller one can try the following:

    • do not package the SpringBoot application into a fat jar, but instead keep the libs with all the dependencies in some common folder.
    • when building the application for container image one most probably has to set the lib type as provided so that it’s not being packaged into the final assembly (that will make local development complicated IMHO).
    • every microservice will have the cp option passed to the JVM as an argument that will reference that folder.
    • if building with docker the copying of the libs folder should be defined as a separate step, or even make a base image that will include all of the libs in a specific folder (to be further referenced by the JVM)

    Things to consider:

    • All of those steps will complicate the container image-building phase.
    • Typically, the space saved will not compensate for the effort and complexity of the support needed.
    Login or Signup to reply.
  2. There can be multiple options

    • OPTION 1 Use multi stage Dockerfile?

      • this way the team can have a common layer which can run at first

      • though it may force you to have a single build pipeline for all microservices

      • we can leverage --target argument for during the image build phase to reduce steps to stop at a particular stage

      • for separate base image for spring-data-jpa, broker, etc. This sounds less fruitful

      • this option will be slow, the second option below is better I believe.

    • OPTION 2 Create a common(single or multiple) spring (java) based parent pom.xml(s)

      • The common layer can correspond to set of common jars/dependencies and can be built in advance as a base image, can be introduced with some kind of versioning
      • The versioning would require a thorough lookup, documentation & communication across team(s).
      • this way you can have different base images for data-jpa, message-broker, etc.

    NOTE – will update the answer for more ideas for sure

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search