springboot随机端口修改方法

本文介绍如何在SpringBoot应用中配置随机端口,包括主函数引用EurekaRandomPortConfig,SpringConfiguration类配置,application.yml及环境配置文件调整,以及自定义EurekaRandomPortConfig类实现端口随机分配。

 

1.主函数添加xx.xxxxx.xxxxx.xxx.xxx.xxxxxx.EurekaRandomPortConfig引用,继承EurekaRandomPortConfig类,

示例:

public class BasicApplication extends EurekaRandomPortConfig{

    public static void main(String[] args) {
        SpringApplication.run(BasicApplication.class, args);
    }
}

2.SpringConfiguration类

添加如下内容:

import xx.xxxxx.xxxxx.xxx.xxx.xxxxxx.EurekaConfig;
import xx.xxxxx.xxxxx.xxx.xxx.xxxxxx.ApplicationInfo;

@Bean
@ConfigurationProperties(prefix = "eureka.random")
public EurekaConfig getEurekaConfig() {
    return new EurekaConfig();
}


@Bean
@ConfigurationProperties(prefix = "spring.application")
public ApplicationInfo getApplicationInfo() {
    return new ApplicationInfo();
}

3.application.yml文件

删除固定端口设置:

server:

  # port: 7205             
  tomcat:
    uri-encoding: UTF-8

添加随机端口范围:

eureka:
  random:
    portBase: 9100
    portRange: 1000

4.appilication-dev.yml、application-prd.yml文件

注释如下节点:

eureka:
  instance:
    preferIpAddress: true
    #instance-id: ${spring.cloud.client.ipAddress}:${server.port}
    lease-renewal-interval-in-seconds: 10 #心跳时间,即服务续约间隔时间(缺省为30s)
    lease-expiration-duration-in-seconds: 30 #发呆时间,即服务续约到期时间(缺省为90s)

EurekaRandomPortConfig类

package xx.xxxxxxxxx.xxxx.xxx.xxxx.xxxxxx;

import java.io.File;
import java.net.InetAddress;
import java.net.Socket;

import org.apache.commons.lang.math.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
import org.springframework.context.annotation.Bean;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class EurekaRandomPortConfig implements EmbeddedServletContainerCustomizer {
	@Autowired
	private EurekaConfig config;
	@Autowired
	private ApplicationInfo info;
	private int port;//java -jar target/xxx.jar --eureka.random.portBase=9900启动命令修改端口号
	private static String path = "/xxx/xxxx/port";
	private static String fileName;
	private static final int RETRYTIMES = 100;

	@Override
	public void customize(ConfigurableEmbeddedServletContainer configurableEmbeddedServletContainer) {
		/*SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");//设置日期格式
	    System.out.print("begin:"+df.format(new Date())+"\n");*/
		boolean flag = true;
		int num = 0;
		while (flag == true && num < RETRYTIMES) {
			port = RandomUtils.nextInt(config.getPortRange()) + config.getPortBase();

			try {
				InetAddress address = InetAddress.getByName("127.0.0.1");
				Socket s = new Socket(
						address/* InetAddress.getLocalHost().getHostAddress() */, port); // 建立一个Socket连接
				s.close();
				flag = true;
				num++;
				log.info("port is using:" + port);
			} catch (Exception e) {
				try {
					Socket serverSocket = new Socket("0.0.0.0", port); // 建立一个Socket连接
					serverSocket.close();
					flag = true;
					num++;
					log.info("port is using:" + port);
				} catch (Exception ex) {
					/*
					 * File tmpFile = null; try { tmpFile =
					 * File.createTempFile("none", "tmp");
					 * tmpFile.deleteOnExit();
					 * log.info(tmpFile.getAbsolutePath()); } catch (IOException
					 * e1) { log.info("can not create temp file :" +
					 * e1.getMessage()); e1.printStackTrace(); }
					 */
					if (createFile(port, info.getName().toLowerCase()) == true) {
						flag = false;
						log.info("port is idle:" + port);
					} else {
						flag = true;
						num++;
						log.info("port is using:" + port);
					}
				}
			}
		}
		if (flag == true) {
			log.info("Run out of retries!");
		} else {
			configurableEmbeddedServletContainer.setPort(port);
			log.info("start port:" + port);

		}
//		System.out.print("end:"+df.format(new Date())+"\n");
	}

	/*
	 * @PreDestroy public void destory() {
	 * 
	 * log.info("我被销毁了、、、、、我是用的@PreDestory的方式、、、、、、");
	 * log.info("我被销毁了、、、、、我是用的@PreDestory的方式、、、、、、"); }
	 */
	public static boolean createFile(int port, String applicationName) {
		Boolean bool = false;
		File f = new File(path);

		if (!f.exists()) {
			f.mkdirs();// 创建目录
		}
		fileName = port + "_" + applicationName + ".ini";// 文件路径+名称+文件类型

		try {

			File filePath = new File(path);
			File[] tempList = filePath.listFiles();

			for (int i = 0; i < tempList.length; i++) {
				if (tempList[i].isFile()) {
					if (tempList[i].toString().contains(port + "")) {
						bool = false;
						return bool;
					}
				}

			}

			File file = new File(path, fileName);
			file.createNewFile();
			bool = true;

		} catch (Exception e) {
			bool = false;
			log.info("create file fail");
		}

		return bool;
	}

	@Bean
	public EurekaInstanceConfigBean eurekaInstanceConfigBean(InetUtils inetUtils) {

		EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(inetUtils);
		config.setInstanceId(config.getIpAddress() + ":" + port);
		config.setNonSecurePort(port);
		config.setPreferIpAddress(true);
		config.setIpAddress(config.getIpAddress());
		return config;
	}
}

EurekaConfig类

package xx.xxxxxxxx.xxxx.xxx.xxxx.xxxxxxx;

import lombok.Data;

@Data
public class EurekaConfig {

	private int portBase;
	private int portRange;
}

ApplicationInfo类

package xx.xxxxxxxx.xxxx.xxx.xxxx.xxxxxx;

import lombok.Data;

@Data

public class ApplicationInfo {
	private String name;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值