SpringBoot 多端口随机启动

228 阅读1分钟

思路

  1. 继承 TomcatServletWebServerFactory 创建 MyTomcatFactory
  2. 将该类注册到 IOC
  3. 重写 getPort() 方法
  4. 使用配置文件定义端口号范围

注: 对于不同的服务相互之间会出现并发问题

对于 SocketUtils.findAvailableTcpPort(minPort, maxPort); 方法来说, 内部使用套接字建立的方式来检查端口是否占用, 但是测试完成后端口会被立即释放.
若 服务A 在检验到 4321 端口可用后释放了该端口, 那么在 服务A 创建成功之前 4321 端口都处于一种可用状态.
此时 服务B 也去检测 4321 端口, 由于 服务A 还未启动完成, 则服务B也会选用该端口进行服务的初始化.
在这种情况下 服务 A/B 只会有一个可以成功创建

画个图说明下

多端口启动并发问题.png

注: SocketUtils 将被移除

在 Spring Framework 5.3.16 中已经被添加了 Deprecated, 而且该方法会在 6.x 中被移除.
原说明地址: docs.spring.io/spring-fram…

代码


@Component
public class MyTomcatPort extends TomcatServletWebServerFactory {

    // 需要在配制文件中进行配制 server.max-port 参数
    @Value("${server.max-port}")
    private Integer maxPort;

    // 需要在配制文件中进行配制 server.min-port 参数
    @Value("${server.min-port}")
    private Integer minPort;

    @Override
    public int getPort() {
        return SocketUtils.findAvailableTcpPort(minPort, maxPort);
    }

}