By default the spring boot web application is listening on the port 8080 for the incoming connection.
This behavior can be changed by providing server.port property value during starting of the application or as part of the application.properties or through the code by implementing EmbeddedServletContainerCustomizer.
But it would be even better if we could specified a range of the ports which can be used for the starting the application.
It would be great if I could specify a property like server.portRange=8100..8200 to define a list of the port on which I want to start my service.
In this blog post I will describe how this can be done.
Full code example you find on Bitbucket.
This behavior can be changed by providing server.port property value during starting of the application or as part of the application.properties or through the code by implementing EmbeddedServletContainerCustomizer.
But it would be even better if we could specified a range of the ports which can be used for the starting the application.
It would be great if I could specify a property like server.portRange=8100..8200 to define a list of the port on which I want to start my service.
In this blog post I will describe how this can be done.
Starting application on the random port from range
To allow usage of the property like server.portRange, I will create WebContainerPortCustomizer which implements EmbeddedServletContainerCustomizer.
1: package com.example.demo;
2:
3: import org.springframework.beans.factory.annotation.Value;
4: import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
5: import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
6: import org.springframework.stereotype.Component;
7: import org.springframework.util.SocketUtils;
8: import java.util.List;
9:
10: @Component
11: public class WebContainerPortCustomizer implements EmbeddedServletContainerCustomizer {
12:
13: @Value("#{'${server.portRange:${server.port:0}}'.split('\\.\\.')}")
14: private List<Integer> portRange;
15:
16: @Override
17: public void customize(ConfigurableEmbeddedServletContainer configurableEmbeddedServletContainer) {
18: configurableEmbeddedServletContainer.setPort(getAvailablePort());
19: }
20:
21: public int getAvailablePort() {
22: if(portRange.size() == 1){
23: return portRange.get(0);
24: }
25: return SocketUtils.findAvailableTcpPort(portRange.get(0), portRange.get(1));
26: }
27: }
28:
Full code example you find on Bitbucket.
As you can see from the code, if the port range is not specified, then server.port value will be used if specified otherwise it will fallback to random port.
For finding which port from range is available we used spring SocketUtils library, method findAvaibleTcpPort will return back available port or throw IllegalStateException.
Conclusion
If you are still wondering why you need something like this, why do you simple not start your service on any random port?
In some environment it is necessary to specif a list of the ports which are allowed to be used for accessing some service.
With option of providing an port range for starting web service we do not need to modify service starting script, we can just call it and new service will be ready and listening on one of the ports from range
This is small and simple solution which can be easily pack in spring boot starter application for reuse in multiple services (application).
With option of providing an port range for starting web service we do not need to modify service starting script, we can just call it and new service will be ready and listening on one of the ports from range
This is small and simple solution which can be easily pack in spring boot starter application for reuse in multiple services (application).
Comments
Post a Comment