Technical practice - SpringBoot random port startup

1. SpringBoot random port

1. Basic introduction

  1. The random port can automatically find the available ports within the specified range, and there is no need to specify a fixed startup port in the configuration file
  2. For example, if you need to run multiple instances in SpringBoot, it is troublesome to modify the configuration file separately.
  3. The principle of the random port is to establish a connection with the corresponding socket port. If it can be connected, it has been used, otherwise it is not used.
  4. The port check obtained at random can be used and then written to the memory through System.setProperty("Property name", port);, and then it can be obtained in the configuration file
  5. If the written name is server.port, you do not need to specify the port in the configuration file, otherwise you need to configure server.port=${property name}
  6. This practice is based on SpringBoot general engineering, and you can directly create project scaffolding
  7. [tip] For example, in the SpringCloud project, the service provider can use random ports to quickly start multiple services without modifying the configuration file and restarting separately.

2. Implementation steps

  1. Create ServerPortUtil .java port tool class, use socket to connect to the specified port, for example, there are the following conditions
    a. Specify the port range as 8000-65535
    b. Identify whether the port is used, if it has been used, it will continue to be randomly generated
    c. If all ports are unavailable, an error will be thrown directly and the operation will be interrupted
import java.net.InetAddress;
import java.net.Socket;
import java.util.Random;

public class ServerPortUtil {
    private static final int MAX_PORT = 65535;
    private static final int MIN_PORT = 8000;

    public static String getAvailablePort() {
        Random random = new Random();
		// Maximum number of attempts is port range
        int maxRetryCount = MAX_PORT - MIN_PORT;
        while (maxRetryCount > 0) {
        	// Random port within the specified range, write the algorithm casually, and adjust it according to your own needs
            int port = random.nextInt(MAX_PORT - MIN_PORT) + MIN_PORT;
            boolean isUsed = isLocalePortUsing(port);
            if (!isUsed) {
                return String.valueOf(port);
            }
            --maxRetryCount;
        }
        System.out.println("The system has no ports available, the operation is over");
        System.exit(1);
        return null;
    }

    /**
     * Check if a given port is available
     *
     * @author tianxincode@163.com
     * @since 2020/10/14
     */
    public static boolean isLocalePortUsing(int port) {
        try {
            // Establish a Socket connection, return true if the port is still in use, otherwise return false, 127.0.0.1 represents this machine
            new Socket(InetAddress.getByName("127.0.0.1"), port);
            return true;
        } catch (Exception e) {
            // The exception indicates that the port cannot be connected, but the port can be used
        }
        return false;
    }
}
  1. Create the StartCommand.java command class, call the random port function to obtain port information, and then write the port information into the running environment
    a. If the incoming parameter contains the port, use the specified port, otherwise use the automatically generated
import com.codecoord.randomport.util.ServerPortUtil;
import org.springframework.util.StringUtils;

public class StartCommand {
    /**
     * Port attribute name, if the name is server.port, it does not need to be specified in the configuration file, otherwise it needs to be specified as the name configured here, such as ${auto.port}
     */
    private static final String SERVER_PORT = "auto.port";

    public StartCommand(String[] args) {
        boolean isServerPort = false;
        String serverPort = "";
        if (args != null) {
            for (String arg : args) {
                if (StringUtils.hasText(arg) && arg.startsWith("--server.port" )) {
                    isServerPort = true;
                    serverPort = arg;
                    break;
                }
            }
        }

        String port;
        if (isServerPort) {
           port = serverPort.split("=")[1];
        } else {
            port = ServerPortUtil.getAvailablePort();
        }
        System.out.println("Current project port is " + port);
        System.setProperty(SERVER_PORT, port);
    }
}
  1. Write port information to the environment before the startup class starts
import com.codecoord.randomport.config.StartCommand;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplicatio
public class SpringbootRandomPortApplication {
    public static void main(String[] args) {
        // write port information 
        new StartCommand(args);
        SpringApplication.run(SpringbootRandomPortApplication.class, args);
    }
}
  1. Specify the port in the configuration file as randomly generated port information
server:
  # random port configuration
  port: ${auto.port}

3. Project testing

  1. Start the project normally, you can see the started port information in the console


Second, SpringBoot multi-instance operation

  1. The multi-instance operation of SpringBoot is configured as follows in IDEA



3. Then run/debug on startup to start

Posted by Ryan Sanders on Tue, 10 May 2022 10:50:48 +0300