springboot实现随机端口并指定随机范围

本文介绍了如何在SpringBoot项目中避免端口重复问题,通过启动时检查并获取可用端口,使用WebServerFactoryCustomizer自定义容器配置,创建了一个无侵入式的端口随机化starter。开发者只需引入jar包即可解决端口抢占问题。
摘要由CSDN通过智能技术生成

需求来源

项目采用随机端口启动但是会出现重复等问题,直接全随机会导致端口抢占问题。

主要思路

  1. 启动spring的时候获取到容器端口号
  2. .做一下当前容器端口号是否被暂用校验。
  3. 写一段随机代码获取可用端口,轮训获取到可用的返回
  4. 端口号写入容器中。
  5. 如何无侵入的修改所有项目。自定义starter

随机端口获取方法以及校验法

@Data
@Slf4j
public class ServerPortUtil {

    @Value("${whcloud-config.server.maxPort:59999}")
    private int MAX_PORT;
    @Value("${whcloud-config.server.minPort:50000}")
    private int MIN_PORT;


    public String getAvailablePort(String portStr) {
        if (!ObjectUtils.isEmpty(portStr)) {
            int port = Integer.parseInt(portStr);
            if (isLocalePortUsing(port)) {
                String availablePort = getAvailablePort();
                return availablePort;
            }else {
                return portStr;
            }
        }

        return getAvailablePort();
    }

    /**
     * 获取可用端口
     *
     * @return
     */
    public String getAvailablePort() {
        Random random = new Random();
        // 最大尝试次数为端口范围
        while (true) {
            // 指定范围内随机端口,随便写的算法,根据自己需要调整
            int port = random.nextInt(MAX_PORT - MIN_PORT) + MIN_PORT;
            boolean isUsed = isLocalePortUsing(port);
            if (!isUsed) {
                log.info("随机可用端口为:{}", port);
                return String.valueOf(port);
            }
        }
    }

    /**
     * 检查给定端口是否在用
     *
     * @param port 端口号
     * @return true:端口已经占用,false:端口没有占用
     */

    public boolean isLocalePortUsing(int port) {
        try {
            // 建立一个Socket连接, 如果该端口还在使用则返回true, 否则返回false, 127.0.0.1代表本机
            Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), port);
            socket.close();
            return true;
        } catch (Exception e) {
            // 异常说明端口连接不上,端口能使用
        }
        return false;
    }

}

我们使用WebServerFactoryCustomizer来自定义容器实现端口


@Slf4j
public class ServerPortRandomCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {

    private Environment environment;
    private ServerPortUtil serverPortUtil;

    public ServerPortRandomCustomizer(Environment environment, ServerPortUtil serverPortUtil) {
        this.environment = environment;
        this.serverPortUtil = serverPortUtil;
    }

    @Override
    public void customize(ConfigurableServletWebServerFactory factory) {

        String portStr = environment.getProperty("server.port");
        log.info("容器启动端口号:{}",portStr);
        // 自定义修改后添加进去覆盖
        String availablePort = serverPortUtil.getAvailablePort(portStr);
        if (!ObjectUtils.isEmpty(availablePort)){
            log.info("自定义修改端口号:{}",availablePort);
            factory.setPort(Integer.parseInt(availablePort));
        }
    }
}

我们以starter的方式提供jar

@Configuration
@Import({ServerPortConfig.class})
public class ServerPortRandomAutoConfigure {
    private static final Logger LOGGER = LoggerFactory.getLogger(ServerPortRandomAutoConfigure.class);

    public ServerPortRandomAutoConfigure() {
    }


    @Bean
    @ConditionalOnMissingBean
    public ServerPortRandomCustomizer serverPortRandomCustomizer(ServerPortConfig serverPortConfig, Environment environment) {
        LOGGER.info("Init ServerPortRandomCustomizer");
        return new ServerPortRandomCustomizer(environment, serverPortConfig);
    }
}

最后一步吧启动器放到spring.factories里面

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.wh.whcloudcommonstarter.configuration.ServerPortRandomAutoConfigure

需要使用得服务引入jar包即可

	<dependency>
			<groupId>com.wh</groupId>
			<artifactId>whcloud-common-starter</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值