Skip to main content

Running Spring Boot Web App on the Random Port from Port Range

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.


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).

Comments

Popular posts from this blog

Checking file's "magic numbers"

Few days ago I had very interesting task. Our customer required that we perform checking of so called file's "magic numbers" to determinate does uploaded file correspond to it's extension.  We are already allowed only to upload files with some predefined extensions (PDF, DOC ...). But this can not prevent some evil user to update an exe file after renaming it to PDF or DOC. So first of all I will explain what are "magic numbers", and then I will show how we handle them.

Simple Workflow Engine With Spring

Few months ago, during working on one of the company project, we had need to developed  REST services which is used for sending an email depending on data sent by client application. During developing this service we decide to create simple workflow engine which will be charged for sending an email, but also this engine can be used for any kind of simple flows. In this article i will explain step by step how you can implement your simple workflow engine which can handle sequence flow.